From 86a783b3ad0f11674c0786daf5484d64f624a0af Mon Sep 17 00:00:00 2001 From: CommanderRoot Date: Fri, 1 Apr 2022 17:35:17 +0200 Subject: [PATCH] DEV: Replace deprecated String.prototype.substr() (#16233) String.prototype.substr() is deprecated so we replace it with String.prototype.slice() which works similarily but isn't deprecated. Signed-off-by: Tobias Speicher Co-authored-by: Jarek Radosz --- .../addon/components/site-settings/color.js | 2 +- .../addon/controllers/admin-site-settings.js | 2 +- .../admin/addon/models/color-scheme-color.js | 18 +++++++++--------- .../admin/addon/models/version-check.js | 2 +- .../addon/lib/attribute-hook.js | 2 +- .../app/components/composer-messages.js | 2 +- .../strip-mobile-app-url-params.js | 2 +- .../javascripts/discourse/app/lib/formatter.js | 2 +- .../discourse/app/lib/link-hashtags.js | 4 ++-- .../discourse/app/lib/link-mentions.js | 2 +- .../discourse/app/lib/static-route-builder.js | 2 +- .../javascripts/discourse/app/lib/text.js | 2 +- .../javascripts/discourse/app/lib/uploads.js | 2 +- .../javascripts/discourse/app/lib/utilities.js | 2 +- .../app/mixins/textarea-text-manipulation.js | 2 +- .../javascripts/discourse/app/models/invite.js | 2 +- .../app/models/topic-tracking-state.js | 2 +- .../javascripts/discourse/app/models/topic.js | 2 +- .../discourse/app/routes/topic-from-params.js | 2 +- .../discourse/app/widgets/topic-map.js | 2 +- .../discourse/lib/bootstrap-json/index.js | 2 +- .../public/assets/scripts/discourse-boot.js | 2 +- .../discourse/tests/helpers/d-editor-helper.js | 6 +++--- app/assets/javascripts/locales/i18n.js | 5 +++-- .../addon/engines/discourse-markdown-it.js | 4 ++-- .../engines/discourse-markdown/emoji.js | 4 ++-- .../engines/discourse-markdown/helpers.js | 4 ++-- .../engines/discourse-markdown/quotes.js | 4 ++-- .../addon/components/category-row.js | 2 +- app/assets/javascripts/wizard/lib/preview.js | 12 ++++++------ 30 files changed, 52 insertions(+), 51 deletions(-) diff --git a/app/assets/javascripts/admin/addon/components/site-settings/color.js b/app/assets/javascripts/admin/addon/components/site-settings/color.js index 8d098cb7d80..0b1db9a5c1a 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/color.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/color.js @@ -5,7 +5,7 @@ function RGBToHex(rgb) { // Choose correct separator let sep = rgb.indexOf(",") > -1 ? "," : " "; // Turn "rgb(r,g,b)" into [r,g,b] - rgb = rgb.substr(4).split(")")[0].split(sep); + rgb = rgb.slice(4).split(")")[0].split(sep); let r = (+rgb[0]).toString(16), g = (+rgb[1]).toString(16), diff --git a/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js b/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js index dc5ba1193d7..3dbcc3742cf 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js @@ -30,7 +30,7 @@ export default Controller.extend({ } if (word.startsWith("plugin:")) { - pluginFilter = word.substr("plugin:".length).trim(); + pluginFilter = word.slice("plugin:".length).trim(); return false; } diff --git a/app/assets/javascripts/admin/addon/models/color-scheme-color.js b/app/assets/javascripts/admin/addon/models/color-scheme-color.js index 49cb552a92f..24beb9130ca 100644 --- a/app/assets/javascripts/admin/addon/models/color-scheme-color.js +++ b/app/assets/javascripts/admin/addon/models/color-scheme-color.js @@ -76,17 +76,17 @@ const ColorSchemeColor = EmberObject.extend({ if (hex.length === 6 || hex.length === 3) { if (hex.length === 3) { hex = - hex.substr(0, 1) + - hex.substr(0, 1) + - hex.substr(1, 1) + - hex.substr(1, 1) + - hex.substr(2, 1) + - hex.substr(2, 1); + hex.slice(0, 1) + + hex.slice(0, 1) + + hex.slice(1, 2) + + hex.slice(1, 2) + + hex.slice(2, 3) + + hex.slice(2, 3); } return Math.round( - (parseInt(hex.substr(0, 2), 16) * 299 + - parseInt(hex.substr(2, 2), 16) * 587 + - parseInt(hex.substr(4, 2), 16) * 114) / + (parseInt(hex.slice(0, 2), 16) * 299 + + parseInt(hex.slice(2, 4), 16) * 587 + + parseInt(hex.slice(4, 6), 16) * 114) / 1000 ); } diff --git a/app/assets/javascripts/admin/addon/models/version-check.js b/app/assets/javascripts/admin/addon/models/version-check.js index 4f939064af3..edf6ad5e0e6 100644 --- a/app/assets/javascripts/admin/addon/models/version-check.js +++ b/app/assets/javascripts/admin/addon/models/version-check.js @@ -28,7 +28,7 @@ const VersionCheck = EmberObject.extend({ @discourseComputed("installed_sha") shortSha(installedSHA) { if (installedSHA) { - return installedSHA.substr(0, 10); + return installedSHA.slice(0, 10); } }, }); diff --git a/app/assets/javascripts/discourse-common/addon/lib/attribute-hook.js b/app/assets/javascripts/discourse-common/addon/lib/attribute-hook.js index d60b94eaf71..b66172c73b5 100644 --- a/app/assets/javascripts/discourse-common/addon/lib/attribute-hook.js +++ b/app/assets/javascripts/discourse-common/addon/lib/attribute-hook.js @@ -33,7 +33,7 @@ AttributeHook.prototype.unhook = function (node, prop, next) { } let colonPosition = prop.indexOf(":"); - let localName = colonPosition > -1 ? prop.substr(colonPosition + 1) : prop; + let localName = colonPosition > -1 ? prop.slice(colonPosition + 1) : prop; node.removeAttributeNS(this.namespace, localName); }; diff --git a/app/assets/javascripts/discourse/app/components/composer-messages.js b/app/assets/javascripts/discourse/app/components/composer-messages.js index ad323bcb55b..2f00c76a49d 100644 --- a/app/assets/javascripts/discourse/app/components/composer-messages.js +++ b/app/assets/javascripts/discourse/app/components/composer-messages.js @@ -158,7 +158,7 @@ export default Component.extend({ } // TODO pass the 200 in from somewhere - const raw = (composer.get("reply") || "").substr(0, 200); + const raw = (composer.get("reply") || "").slice(0, 200); const title = composer.get("title") || ""; // Ensure we have at least a title diff --git a/app/assets/javascripts/discourse/app/initializers/strip-mobile-app-url-params.js b/app/assets/javascripts/discourse/app/initializers/strip-mobile-app-url-params.js index 07d3f02db80..0ad6bc5c339 100644 --- a/app/assets/javascripts/discourse/app/initializers/strip-mobile-app-url-params.js +++ b/app/assets/javascripts/discourse/app/initializers/strip-mobile-app-url-params.js @@ -6,7 +6,7 @@ export default { if (queryStrings.indexOf("user_api_public_key") !== -1) { let params = queryStrings.startsWith("?") - ? queryStrings.substr(1).split("&") + ? queryStrings.slice(1).split("&") : []; params = params.filter((param) => { diff --git a/app/assets/javascripts/discourse/app/lib/formatter.js b/app/assets/javascripts/discourse/app/lib/formatter.js index 3a57516b186..b8d8e7509fb 100644 --- a/app/assets/javascripts/discourse/app/lib/formatter.js +++ b/app/assets/javascripts/discourse/app/lib/formatter.js @@ -25,7 +25,7 @@ export function tinyDateYear(date) { // TODO: locale support ? export function toTitleCase(str) { return str.replace(/\w\S*/g, function (txt) { - return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); + return txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase(); }); } diff --git a/app/assets/javascripts/discourse/app/lib/link-hashtags.js b/app/assets/javascripts/discourse/app/lib/link-hashtags.js index da3391d5d4a..9d4201b3c14 100644 --- a/app/assets/javascripts/discourse/app/lib/link-hashtags.js +++ b/app/assets/javascripts/discourse/app/lib/link-hashtags.js @@ -22,13 +22,13 @@ export function linkSeenHashtags(elem) { if (hashtags.length === 0) { return []; } - const slugs = [...hashtags.map((hashtag) => hashtag.innerText.substr(1))]; + const slugs = [...hashtags.map((hashtag) => hashtag.innerText.slice(1))]; hashtags.forEach((hashtag, index) => { let slug = slugs[index]; const hasTagSuffix = slug.endsWith(TAG_HASHTAG_POSTFIX); if (hasTagSuffix) { - slug = slug.substr(0, slug.length - TAG_HASHTAG_POSTFIX.length); + slug = slug.slice(0, slug.length - TAG_HASHTAG_POSTFIX.length); } const lowerSlug = slug.toLowerCase(); diff --git a/app/assets/javascripts/discourse/app/lib/link-mentions.js b/app/assets/javascripts/discourse/app/lib/link-mentions.js index e72575fadd9..5d1cf918897 100644 --- a/app/assets/javascripts/discourse/app/lib/link-mentions.js +++ b/app/assets/javascripts/discourse/app/lib/link-mentions.js @@ -81,7 +81,7 @@ export function linkSeenMentions(elem, siteSettings) { ...elem.querySelectorAll("span.mention:not(.mention-tested)"), ]; if (mentions.length) { - const usernames = mentions.map((m) => m.innerText.substr(1)); + const usernames = mentions.map((m) => m.innerText.slice(1)); updateFound(mentions, usernames); return usernames .uniq() diff --git a/app/assets/javascripts/discourse/app/lib/static-route-builder.js b/app/assets/javascripts/discourse/app/lib/static-route-builder.js index 200714b4f3a..bf5862a5db9 100644 --- a/app/assets/javascripts/discourse/app/lib/static-route-builder.js +++ b/app/assets/javascripts/discourse/app/lib/static-route-builder.js @@ -25,7 +25,7 @@ export default function (page) { activate() { this._super(...arguments); - jumpToElement(document.location.hash.substr(1)); + jumpToElement(document.location.hash.slice(1)); }, model() { diff --git a/app/assets/javascripts/discourse/app/lib/text.js b/app/assets/javascripts/discourse/app/lib/text.js index 635a5c44b2a..24d97d6a942 100644 --- a/app/assets/javascripts/discourse/app/lib/text.js +++ b/app/assets/javascripts/discourse/app/lib/text.js @@ -142,7 +142,7 @@ export function excerpt(cooked, length) { if (element.nodeType === Node.TEXT_NODE) { if (resultLength + element.textContent.length > length) { - const text = element.textContent.substr(0, length - resultLength); + const text = element.textContent.slice(0, length - resultLength); result += encode(text); result += "…"; resultLength += text.length; diff --git a/app/assets/javascripts/discourse/app/lib/uploads.js b/app/assets/javascripts/discourse/app/lib/uploads.js index 6b75f07e908..51a640a5d42 100644 --- a/app/assets/javascripts/discourse/app/lib/uploads.js +++ b/app/assets/javascripts/discourse/app/lib/uploads.js @@ -10,7 +10,7 @@ function isGUID(value) { } export function markdownNameFromFileName(fileName) { - let name = fileName.substr(0, fileName.lastIndexOf(".")); + let name = fileName.slice(0, fileName.lastIndexOf(".")); if (isAppleDevice() && isGUID(name)) { name = I18n.t("upload_selector.default_image_alt_text"); diff --git a/app/assets/javascripts/discourse/app/lib/utilities.js b/app/assets/javascripts/discourse/app/lib/utilities.js index 8a78eb0a4bb..b3e12d20b67 100644 --- a/app/assets/javascripts/discourse/app/lib/utilities.js +++ b/app/assets/javascripts/discourse/app/lib/utilities.js @@ -482,7 +482,7 @@ export function inCodeBlock(text, pos) { // Character at position `pos` can be in a code block that is unfinished. // To check this case, we look for any open code blocks after the last closed // code block. - const lastOpenBlock = text.substr(end).search(OPEN_CODE_BLOCKS_REGEX); + const lastOpenBlock = text.slice(end).search(OPEN_CODE_BLOCKS_REGEX); return lastOpenBlock !== -1 && pos >= end + lastOpenBlock; } diff --git a/app/assets/javascripts/discourse/app/mixins/textarea-text-manipulation.js b/app/assets/javascripts/discourse/app/mixins/textarea-text-manipulation.js index 443250751b8..b5a3e49512e 100644 --- a/app/assets/javascripts/discourse/app/mixins/textarea-text-manipulation.js +++ b/app/assets/javascripts/discourse/app/mixins/textarea-text-manipulation.js @@ -96,7 +96,7 @@ export default Mixin.create({ if (opts && opts.lineVal) { const lineVal = value.split("\n")[ - value.substr(0, this._textarea.selectionStart).split("\n").length - 1 + value.slice(0, this._textarea.selectionStart).split("\n").length - 1 ]; return { start, end, value: selVal, pre, post, lineVal }; } else { diff --git a/app/assets/javascripts/discourse/app/models/invite.js b/app/assets/javascripts/discourse/app/models/invite.js index 122208bc1b2..6608ecb079d 100644 --- a/app/assets/javascripts/discourse/app/models/invite.js +++ b/app/assets/javascripts/discourse/app/models/invite.js @@ -36,7 +36,7 @@ const Invite = EmberObject.extend({ @discourseComputed("invite_key") shortKey(key) { - return key.substr(0, 4) + "..."; + return key.slice(0, 4) + "..."; }, @discourseComputed("groups") diff --git a/app/assets/javascripts/discourse/app/models/topic-tracking-state.js b/app/assets/javascripts/discourse/app/models/topic-tracking-state.js index 685750b52ef..050d0247ebf 100644 --- a/app/assets/javascripts/discourse/app/models/topic-tracking-state.js +++ b/app/assets/javascripts/discourse/app/models/topic-tracking-state.js @@ -441,7 +441,7 @@ const TopicTrackingState = EmberObject.extend({ }, _generateCallbackId() { - return Math.random().toString(12).substr(2, 9); + return Math.random().toString(12).slice(2, 11); }, onStateChange(cb) { diff --git a/app/assets/javascripts/discourse/app/models/topic.js b/app/assets/javascripts/discourse/app/models/topic.js index 013467578f3..e6b960f4eac 100644 --- a/app/assets/javascripts/discourse/app/models/topic.js +++ b/app/assets/javascripts/discourse/app/models/topic.js @@ -574,7 +574,7 @@ const Topic = RestModel.extend({ @discourseComputed("excerpt") excerptTruncated(excerpt) { - return excerpt && excerpt.substr(excerpt.length - 8, 8) === "…"; + return excerpt && excerpt.slice(-8) === "…"; }, readLastPost: propertyEqual("last_read_post_number", "highest_post_number"), diff --git a/app/assets/javascripts/discourse/app/routes/topic-from-params.js b/app/assets/javascripts/discourse/app/routes/topic-from-params.js index b1f30baa5ce..5875089d6d7 100644 --- a/app/assets/javascripts/discourse/app/routes/topic-from-params.js +++ b/app/assets/javascripts/discourse/app/routes/topic-from-params.js @@ -92,7 +92,7 @@ export default DiscourseRoute.extend({ const opts = {}; if (document.location.hash) { - opts.anchor = document.location.hash.substr(1); + opts.anchor = document.location.hash.slice(1); } else if (_discourse_anchor) { opts.anchor = _discourse_anchor; } diff --git a/app/assets/javascripts/discourse/app/widgets/topic-map.js b/app/assets/javascripts/discourse/app/widgets/topic-map.js index 7f21df2aac4..69439af54d0 100644 --- a/app/assets/javascripts/discourse/app/widgets/topic-map.js +++ b/app/assets/javascripts/discourse/app/widgets/topic-map.js @@ -284,7 +284,7 @@ createWidget("topic-map-link", { const truncateLength = 85; if (content.length > truncateLength) { - content = `${content.substr(0, truncateLength).trim()}...`; + content = `${content.slice(0, truncateLength).trim()}...`; } return attrs.title ? replaceEmoji(content) : content; diff --git a/app/assets/javascripts/discourse/lib/bootstrap-json/index.js b/app/assets/javascripts/discourse/lib/bootstrap-json/index.js index c7a5e649fea..c93b32b5d15 100644 --- a/app/assets/javascripts/discourse/lib/bootstrap-json/index.js +++ b/app/assets/javascripts/discourse/lib/bootstrap-json/index.js @@ -230,7 +230,7 @@ async function handleRequest(proxy, baseURL, req, res) { let url = `${proxy}${req.path}`; const queryLoc = req.url.indexOf("?"); if (queryLoc !== -1) { - url += req.url.substr(queryLoc); + url += req.url.slice(queryLoc); } if (req.method === "GET") { diff --git a/app/assets/javascripts/discourse/public/assets/scripts/discourse-boot.js b/app/assets/javascripts/discourse/public/assets/scripts/discourse-boot.js index 1bc1786c8db..a456dff9817 100644 --- a/app/assets/javascripts/discourse/public/assets/scripts/discourse-boot.js +++ b/app/assets/javascripts/discourse/public/assets/scripts/discourse-boot.js @@ -9,7 +9,7 @@ let len = prefix.length; Object.keys(requirejs.entries).forEach(function (key) { if (key.indexOf(prefix) === 0) { - Ember.TEMPLATES[key.substr(len)] = require(key).default; + Ember.TEMPLATES[key.slice(len)] = require(key).default; } else if (key.indexOf(adminPrefix) === 0) { Ember.TEMPLATES[key] = require(key).default; } diff --git a/app/assets/javascripts/discourse/tests/helpers/d-editor-helper.js b/app/assets/javascripts/discourse/tests/helpers/d-editor-helper.js index 88d6cb2df9b..09d2f0aef33 100644 --- a/app/assets/javascripts/discourse/tests/helpers/d-editor-helper.js +++ b/app/assets/javascripts/discourse/tests/helpers/d-editor-helper.js @@ -1,11 +1,11 @@ export default function formatTextWithSelection(text, [start, len]) { return [ '"', - text.substr(0, start), + text.slice(0, start), "<", - text.substr(start, len), + text.slice(start, start + len), ">", - text.substr(start + len), + text.slice(start + len), '"', ].join(""); } diff --git a/app/assets/javascripts/locales/i18n.js b/app/assets/javascripts/locales/i18n.js index bde0d1a7bb8..c930469c2e0 100644 --- a/app/assets/javascripts/locales/i18n.js +++ b/app/assets/javascripts/locales/i18n.js @@ -201,8 +201,9 @@ I18n.toNumber = function(number, options) { number = parts[0]; while (number.length > 0) { - buffer.unshift(number.substr(Math.max(0, number.length - 3), 3)); - number = number.substr(0, number.length - 3); + var pos = Math.max(0, number.length - 3); + buffer.unshift(number.slice(pos, pos + 3)); + number = number.slice(0, -3); } formattedNumber = buffer.join(options.delimiter); diff --git a/app/assets/javascripts/pretty-text/addon/engines/discourse-markdown-it.js b/app/assets/javascripts/pretty-text/addon/engines/discourse-markdown-it.js index b9c9f4759a9..80381858cd2 100644 --- a/app/assets/javascripts/pretty-text/addon/engines/discourse-markdown-it.js +++ b/app/assets/javascripts/pretty-text/addon/engines/discourse-markdown-it.js @@ -426,12 +426,12 @@ export function extractDataAttribute(str) { return null; } - const key = `data-${str.substr(0, sep)}`.toLowerCase(); + const key = `data-${str.slice(0, sep)}`.toLowerCase(); if (!/^[A-Za-z]+[\w\-\:\.]*$/.test(key)) { return null; } - const value = str.substr(sep + 1); + const value = str.slice(sep + 1); return [key, value]; } diff --git a/app/assets/javascripts/pretty-text/engines/discourse-markdown/emoji.js b/app/assets/javascripts/pretty-text/engines/discourse-markdown/emoji.js index 6a68b19d9f2..df735a5fd1c 100644 --- a/app/assets/javascripts/pretty-text/engines/discourse-markdown/emoji.js +++ b/app/assets/javascripts/pretty-text/engines/discourse-markdown/emoji.js @@ -90,7 +90,7 @@ function getEmojiName(content, pos, state, inlineEmoji) { if (content.charCodeAt(pos + length) === 58) { // check for t2-t6 - if (content.substr(pos + length + 1, 3).match(/t[2-6]:/)) { + if (content.slice(pos + length + 1, pos + length + 4).match(/t[2-6]:/)) { length += 3; } break; @@ -105,7 +105,7 @@ function getEmojiName(content, pos, state, inlineEmoji) { return; } - return content.substr(pos, length); + return content.slice(pos, pos + length); } // straight forward :smile: to emoji image diff --git a/app/assets/javascripts/pretty-text/engines/discourse-markdown/helpers.js b/app/assets/javascripts/pretty-text/engines/discourse-markdown/helpers.js index 069a88c2f32..17fa1e1c2c4 100644 --- a/app/assets/javascripts/pretty-text/engines/discourse-markdown/helpers.js +++ b/app/assets/javascripts/pretty-text/engines/discourse-markdown/helpers.js @@ -38,13 +38,13 @@ export function textReplace(state, callback, skipAllLinks) { if (token.type === "link_open" || token.type === "link_close") { linkLevel -= token.nesting; } else if (token.type === "html_inline") { - const openLink = token.content.substr(0, 2).toLowerCase(); + const openLink = token.content.slice(0, 2).toLowerCase(); if (openLink === "/i)) { linkLevel++; } - } else if (token.content.substr(0, 4).toLowerCase() === "") { + } else if (token.content.slice(0, 4).toLowerCase() === "") { linkLevel--; } } diff --git a/app/assets/javascripts/pretty-text/engines/discourse-markdown/quotes.js b/app/assets/javascripts/pretty-text/engines/discourse-markdown/quotes.js index 28bd3ed7e94..037685f8236 100644 --- a/app/assets/javascripts/pretty-text/engines/discourse-markdown/quotes.js +++ b/app/assets/javascripts/pretty-text/engines/discourse-markdown/quotes.js @@ -23,12 +23,12 @@ const rule = { let i; for (i = 1; i < split.length; i++) { if (split[i].indexOf("post:") === 0) { - postNumber = parseInt(split[i].substr(5), 10); + postNumber = parseInt(split[i].slice(5), 10); continue; } if (split[i].indexOf("topic:") === 0) { - topicId = parseInt(split[i].substr(6), 10); + topicId = parseInt(split[i].slice(6), 10); continue; } diff --git a/app/assets/javascripts/select-kit/addon/components/category-row.js b/app/assets/javascripts/select-kit/addon/components/category-row.js index f6ca802b43c..9ab473d382c 100644 --- a/app/assets/javascripts/select-kit/addon/components/category-row.js +++ b/app/assets/javascripts/select-kit/addon/components/category-row.js @@ -110,7 +110,7 @@ export default SelectKitRowComponent.extend({ _formatDescription(description) { const limit = 200; - return `${description.substr(0, limit)}${ + return `${description.slice(0, limit)}${ description.length > limit ? "…" : "" }`; }, diff --git a/app/assets/javascripts/wizard/lib/preview.js b/app/assets/javascripts/wizard/lib/preview.js index 3ed162ccad3..243f34e9190 100644 --- a/app/assets/javascripts/wizard/lib/preview.js +++ b/app/assets/javascripts/wizard/lib/preview.js @@ -314,9 +314,9 @@ export function parseColor(color) { if (m) { const c = m[1]; return [ - parseInt(c.substr(0, 2), 16), - parseInt(c.substr(2, 2), 16), - parseInt(c.substr(4, 2), 16), + parseInt(c.slice(0, 2), 16), + parseInt(c.slice(2, 4), 16), + parseInt(c.slice(4, 6), 16), ]; } @@ -404,9 +404,9 @@ export function lighten(color, percent) { return ( "#" + - (0 | ((1 << 8) + color[0])).toString(16).substr(1) + - (0 | ((1 << 8) + color[1])).toString(16).substr(1) + - (0 | ((1 << 8) + color[2])).toString(16).substr(1) + (0 | ((1 << 8) + color[0])).toString(16).slice(1) + + (0 | ((1 << 8) + color[1])).toString(16).slice(1) + + (0 | ((1 << 8) + color[2])).toString(16).slice(1) ); }