From e2fed24995033e3c70279a5c623573668feb18be Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 23 Nov 2020 12:47:47 +0100 Subject: [PATCH] Clean up node-vibrant (#7777) --- package.json | 5 +- src/common/color/rgb.ts | 5 + src/common/image/extract_color.ts | 132 +++++++++++++++++ src/data/media-player.ts | 1 - .../lovelace/cards/hui-media-control-card.ts | 140 ++---------------- src/panels/lovelace/common/color/contrast.ts | 12 -- .../lovelace/common/color/luminanace.ts | 7 - yarn.lock | 123 ++++++++++++--- 8 files changed, 256 insertions(+), 169 deletions(-) create mode 100644 src/common/image/extract_color.ts delete mode 100644 src/panels/lovelace/common/color/contrast.ts delete mode 100644 src/panels/lovelace/common/color/luminanace.ts diff --git a/package.json b/package.json index 28367bf4f0..4431314d52 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,9 @@ "@types/sortablejs": "^1.10.6", "@vaadin/vaadin-combo-box": "^5.0.10", "@vaadin/vaadin-date-picker": "^4.0.7", + "@vibrant/color": "^3.2.1-alpha.1", + "@vibrant/core": "^3.2.1-alpha.1", + "@vibrant/quantizer-mmcq": "^3.2.1-alpha.1", "@vue/web-component-wrapper": "^1.2.0", "@webcomponents/webcomponentsjs": "^2.2.7", "chart.js": "~2.8.0", @@ -109,7 +112,7 @@ "marked": "^1.1.1", "mdn-polyfills": "^5.16.0", "memoize-one": "^5.0.2", - "node-vibrant": "^3.1.6", + "node-vibrant": "3.2.1-alpha.1", "proxy-polyfill": "^0.3.1", "punycode": "^2.1.1", "qrcode": "^1.4.4", diff --git a/src/common/color/rgb.ts b/src/common/color/rgb.ts index 3d54ee0597..54b69408dc 100644 --- a/src/common/color/rgb.ts +++ b/src/common/color/rgb.ts @@ -22,3 +22,8 @@ export const rgbContrast = ( return (lum2 + 0.05) / (lum1 + 0.05); }; + +export const getRGBContrastRatio = ( + rgb1: [number, number, number], + rgb2: [number, number, number] +) => Math.round((rgbContrast(rgb1, rgb2) + Number.EPSILON) * 100) / 100; diff --git a/src/common/image/extract_color.ts b/src/common/image/extract_color.ts new file mode 100644 index 0000000000..e9561bcc8c --- /dev/null +++ b/src/common/image/extract_color.ts @@ -0,0 +1,132 @@ +import Vibrant from "node-vibrant/lib/browser"; +import MMCQ from "@vibrant/quantizer-mmcq"; +import { BasicPipeline } from "@vibrant/core/lib/pipeline"; +import { Swatch, Vec3 } from "@vibrant/color"; +import { getRGBContrastRatio } from "../color/rgb"; + +const CONTRAST_RATIO = 4.5; + +// How much the total diff between 2 RGB colors can be +// to be considered similar. +const COLOR_SIMILARITY_THRESHOLD = 150; + +// For debug purposes, is being tree shaken. +const DEBUG_COLOR = __DEV__ && false; + +const logColor = ( + color: Swatch, + label = `${color.hex} - ${color.population}` +) => + // eslint-disable-next-line no-console + console.log( + `%c${label}`, + `color: ${color.bodyTextColor}; background-color: ${color.hex}` + ); + +const customGenerator = (colors: Swatch[]) => { + colors.sort((colorA, colorB) => colorB.population - colorA.population); + + const backgroundColor = colors[0]; + let foregroundColor: Vec3 | undefined; + + const contrastRatios = new Map(); + const approvedContrastRatio = (hex: string, rgb: Swatch["rgb"]) => { + if (!contrastRatios.has(hex)) { + contrastRatios.set(hex, getRGBContrastRatio(backgroundColor.rgb, rgb)); + } + + return contrastRatios.get(hex)! > CONTRAST_RATIO; + }; + + // We take each next color and find one that has better contrast. + for (let i = 1; i < colors.length && foregroundColor === undefined; i++) { + // If this color matches, score, take it. + if (approvedContrastRatio(colors[i].hex, colors[i].rgb)) { + if (DEBUG_COLOR) { + logColor(colors[i], "PICKED"); + } + foregroundColor = colors[i].rgb; + break; + } + + // This color has the wrong contrast ratio, but it is the right color. + // Let's find similar colors that might have the right contrast ratio + + const currentColor = colors[i]; + if (DEBUG_COLOR) { + logColor(colors[i], "Finding similar color with better contrast"); + } + + for (let j = i + 1; j < colors.length; j++) { + const compareColor = colors[j]; + + // difference. 0 is same, 765 max difference + const diffScore = + Math.abs(currentColor.rgb[0] - compareColor.rgb[0]) + + Math.abs(currentColor.rgb[1] - compareColor.rgb[1]) + + Math.abs(currentColor.rgb[2] - compareColor.rgb[2]); + + if (DEBUG_COLOR) { + logColor(colors[j], `${colors[j].hex} - ${diffScore}`); + } + + if (diffScore > COLOR_SIMILARITY_THRESHOLD) { + continue; + } + + if (approvedContrastRatio(compareColor.hex, compareColor.rgb)) { + if (DEBUG_COLOR) { + logColor(compareColor, "PICKED"); + } + foregroundColor = compareColor.rgb; + break; + } + } + } + + if (foregroundColor === undefined) { + foregroundColor = + // @ts-expect-error + backgroundColor.getYiq() < 200 ? [255, 255, 255] : [0, 0, 0]; + } + + if (DEBUG_COLOR) { + // eslint-disable-next-line no-console + console.log(); + // eslint-disable-next-line no-console + console.log( + "%cPicked colors", + `color: ${foregroundColor}; background-color: ${backgroundColor.hex}; font-weight: bold; padding: 16px;` + ); + colors.forEach((color) => logColor(color)); + // eslint-disable-next-line no-console + console.log(); + } + + return { + foreground: new Swatch(foregroundColor, 0), + background: backgroundColor, + }; +}; + +Vibrant.use( + new BasicPipeline().filter + .register( + "default", + (r: number, g: number, b: number, a: number) => + a >= 125 && !(r > 250 && g > 250 && b > 250) + ) + .quantizer.register("mmcq", MMCQ) + // Our generator has different output + // @ts-expect-error + .generator.register("default", customGenerator) +); + +export const extractColors = (url: string, downsampleColors = 16) => + new Vibrant(url, { + colorCount: downsampleColors, + }) + .getPalette() + .then(({ foreground, background }) => { + return { background: background!, foreground: foreground! }; + }); diff --git a/src/data/media-player.ts b/src/data/media-player.ts index 45bf6010ee..e8bed9d7a9 100644 --- a/src/data/media-player.ts +++ b/src/data/media-player.ts @@ -36,7 +36,6 @@ export const SUPPORT_STOP = 4096; export const SUPPORT_PLAY = 16384; export const SUPPORT_SELECT_SOUND_MODE = 65536; export const SUPPORT_BROWSE_MEDIA = 131072; -export const CONTRAST_RATIO = 4.5; export type MediaPlayerBrowseAction = "pick" | "play"; diff --git a/src/panels/lovelace/cards/hui-media-control-card.ts b/src/panels/lovelace/cards/hui-media-control-card.ts index ed9ed8b972..3525dd2089 100644 --- a/src/panels/lovelace/cards/hui-media-control-card.ts +++ b/src/panels/lovelace/cards/hui-media-control-card.ts @@ -16,14 +16,13 @@ import { } from "lit-element"; import { classMap } from "lit-html/directives/class-map"; import { styleMap } from "lit-html/directives/style-map"; -import Vibrant from "node-vibrant"; -import { Swatch } from "node-vibrant/lib/color"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; import { computeStateName } from "../../../common/entity/compute_state_name"; import { stateIcon } from "../../../common/entity/state_icon"; import { supportsFeature } from "../../../common/entity/supports-feature"; import { debounce } from "../../../common/util/debounce"; +import { extractColors } from "../../../common/image/extract_color"; import "../../../components/ha-card"; import "../../../components/ha-icon"; import "../../../components/ha-icon-button"; @@ -33,7 +32,6 @@ import { UNAVAILABLE_STATES } from "../../../data/entity"; import { computeMediaDescription, computeMediaControls, - CONTRAST_RATIO, getCurrentProgress, MediaPickedEvent, SUPPORT_BROWSE_MEDIA, @@ -41,7 +39,6 @@ import { SUPPORT_TURN_ON, } from "../../../data/media-player"; import type { HomeAssistant, MediaEntity } from "../../../types"; -import { contrast } from "../common/color/contrast"; import { findEntities } from "../common/find-entites"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import { installResizeObserver } from "../common/install-resize-observer"; @@ -50,114 +47,6 @@ import { createEntityNotFoundWarning } from "../components/hui-warning"; import type { LovelaceCard, LovelaceCardEditor } from "../types"; import { MediaControlCardConfig } from "./types"; -function getContrastRatio( - rgb1: [number, number, number], - rgb2: [number, number, number] -): number { - return Math.round((contrast(rgb1, rgb2) + Number.EPSILON) * 100) / 100; -} - -// How much the total diff between 2 RGB colors can be -// to be considered similar. -const COLOR_SIMILARITY_THRESHOLD = 150; - -// For debug purposes, is being tree shaken. -const DEBUG_COLOR = __DEV__ && false; - -const logColor = ( - color: Swatch, - label = `${color.getHex()} - ${color.getPopulation()}` -) => - // eslint-disable-next-line no-console - console.log( - `%c${label}`, - `color: ${color.getBodyTextColor()}; background-color: ${color.getHex()}` - ); - -const customGenerator = (colors: Swatch[]) => { - colors.sort((colorA, colorB) => colorB.population - colorA.population); - - const backgroundColor = colors[0]; - let foregroundColor: string | undefined; - - const contrastRatios = new Map(); - const approvedContrastRatio = (color: Swatch) => { - if (!contrastRatios.has(color)) { - contrastRatios.set( - color, - getContrastRatio(backgroundColor.rgb, color.rgb) - ); - } - - return contrastRatios.get(color)! > CONTRAST_RATIO; - }; - - // We take each next color and find one that has better contrast. - for (let i = 1; i < colors.length && foregroundColor === undefined; i++) { - // If this color matches, score, take it. - if (approvedContrastRatio(colors[i])) { - if (DEBUG_COLOR) { - logColor(colors[i], "PICKED"); - } - foregroundColor = colors[i].hex; - break; - } - - // This color has the wrong contrast ratio, but it is the right color. - // Let's find similar colors that might have the right contrast ratio - - const currentColor = colors[i]; - if (DEBUG_COLOR) { - logColor(colors[i], "Finding similar color with better contrast"); - } - - for (let j = i + 1; j < colors.length; j++) { - const compareColor = colors[j]; - - // difference. 0 is same, 765 max difference - const diffScore = - Math.abs(currentColor.rgb[0] - compareColor.rgb[0]) + - Math.abs(currentColor.rgb[1] - compareColor.rgb[1]) + - Math.abs(currentColor.rgb[2] - compareColor.rgb[2]); - - if (DEBUG_COLOR) { - logColor(colors[j], `${colors[j].hex} - ${diffScore}`); - } - - if (diffScore > COLOR_SIMILARITY_THRESHOLD) { - continue; - } - - if (approvedContrastRatio(compareColor)) { - if (DEBUG_COLOR) { - logColor(compareColor, "PICKED"); - } - foregroundColor = compareColor.hex; - break; - } - } - } - - if (foregroundColor === undefined) { - foregroundColor = backgroundColor.bodyTextColor; - } - - if (DEBUG_COLOR) { - // eslint-disable-next-line no-console - console.log(); - // eslint-disable-next-line no-console - console.log( - "%cPicked colors", - `color: ${foregroundColor}; background-color: ${backgroundColor.hex}; font-weight: bold; padding: 16px;` - ); - colors.forEach((color) => logColor(color)); - // eslint-disable-next-line no-console - console.log(); - } - - return [foregroundColor, backgroundColor.hex]; -}; - @customElement("hui-media-control-card") export class HuiMediaControlCard extends LitElement implements LovelaceCard { public static async getConfigElement(): Promise { @@ -634,26 +523,21 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { }); } - private _setColors(): void { + private async _setColors(): Promise { if (!this._image) { return; } - new Vibrant(this._image, { - colorCount: 16, - generator: customGenerator, - }) - .getPalette() - .then(([foreground, background]: [string, string]) => { - this._backgroundColor = background; - this._foregroundColor = foreground; - }) - .catch((err: any) => { - // eslint-disable-next-line no-console - console.error("Error getting Image Colors", err); - this._foregroundColor = undefined; - this._backgroundColor = undefined; - }); + try { + const { foreground, background } = await extractColors(this._image); + this._backgroundColor = background.hex; + this._foregroundColor = foreground.hex; + } catch (err) { + // eslint-disable-next-line no-console + console.error("Error getting Image Colors", err); + this._foregroundColor = undefined; + this._backgroundColor = undefined; + } } private _marqueeMouseOver(): void { diff --git a/src/panels/lovelace/common/color/contrast.ts b/src/panels/lovelace/common/color/contrast.ts deleted file mode 100644 index 56640fbf3e..0000000000 --- a/src/panels/lovelace/common/color/contrast.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { luminanace } from "./luminanace"; - -export const contrast = ( - rgb1: [number, number, number], - rgb2: [number, number, number] -): number => { - const lum1 = luminanace(...rgb1); - const lum2 = luminanace(...rgb2); - const brightest = Math.max(lum1, lum2); - const darkest = Math.min(lum1, lum2); - return (brightest + 0.05) / (darkest + 0.05); -}; diff --git a/src/panels/lovelace/common/color/luminanace.ts b/src/panels/lovelace/common/color/luminanace.ts deleted file mode 100644 index d2fdb0bd3a..0000000000 --- a/src/panels/lovelace/common/color/luminanace.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const luminanace = (r: number, g: number, b: number): number => { - const a = [r, g, b].map((v) => { - v /= 255; - return v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4; - }); - return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722; -}; diff --git a/yarn.lock b/yarn.lock index 9b9363e598..0f92702f09 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3299,11 +3299,6 @@ dependencies: "@types/geojson" "*" -"@types/lodash@^4.14.53": - version "4.14.149" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440" - integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ== - "@types/marked@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@types/marked/-/marked-1.1.0.tgz#53509b5f127e0c05c19176fcf1d743a41e00ff19" @@ -3329,10 +3324,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-11.12.1.tgz#d90123f6c61fdf2f7cddd286ddae891586dd3488" integrity sha512-sKDlqv6COJrR7ar0+GqqhrXQDzQlMcqMnF2iEU6m9hLo8kxozoAGUazwPyELHlRVmjsbvlnGXjnzyptSXVmceA== -"@types/node@^10.11.7": - version "10.17.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8" - integrity sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q== +"@types/node@^10.12.18": + version "10.17.46" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.46.tgz#1cd867ebfe9957ab45951f2f715f8de5f3dab7a3" + integrity sha512-Tice8a+sJtlP9C1EUo0DYyjq52T37b3LexVu3p871+kfIBIN+OQ7PKPei1oF3MgF39olEpUfxaLtD+QFc1k69Q== "@types/resize-observer-browser@^0.1.3": version "0.1.3" @@ -3611,6 +3606,94 @@ dependencies: "@vaadin/vaadin-development-mode-detector" "^2.0.0" +"@vibrant/color@^3.2.1-alpha.1": + version "3.2.1-alpha.1" + resolved "https://registry.yarnpkg.com/@vibrant/color/-/color-3.2.1-alpha.1.tgz#1bcee4545d2276d36f9a1acb42ab3485a9b489ec" + integrity sha512-cvm+jAPwao2NerTr3d1JttYyLhp3eD/AQBeevxF7KT6HctToWZCwr2AeTr003/wKgbjzdOV1qySnbyOeu+R+Jw== + +"@vibrant/core@^3.2.1-alpha.1": + version "3.2.1-alpha.1" + resolved "https://registry.yarnpkg.com/@vibrant/core/-/core-3.2.1-alpha.1.tgz#9adff0835b5c750be3386ec01669d2a8d6389fdb" + integrity sha512-X9Oa9WfPEQnZ6L+5dLRlh+IlsxJkYTw9b/g3stFKoNXbVRKCeXHmH48l7jIBBOg3VcXOGUdsYBqsTwPNkIveaA== + dependencies: + "@vibrant/color" "^3.2.1-alpha.1" + "@vibrant/generator" "^3.2.1-alpha.1" + "@vibrant/image" "^3.2.1-alpha.1" + "@vibrant/quantizer" "^3.2.1-alpha.1" + "@vibrant/types" "^3.2.1-alpha.1" + "@vibrant/worker" "^3.2.1-alpha.1" + +"@vibrant/generator-default@^3.2.1-alpha.1": + version "3.2.1-alpha.1" + resolved "https://registry.yarnpkg.com/@vibrant/generator-default/-/generator-default-3.2.1-alpha.1.tgz#70ae71ea1f72d3e71aa6b244830d01ecae1d755a" + integrity sha512-BWnQhDaz92UhyHnpdAzKXHQecY+jvyMXtzjKYbveFxThm6+HVoLjwONlbck7oyOpFzV2OM7V11XuR85BxaHvjw== + dependencies: + "@vibrant/color" "^3.2.1-alpha.1" + "@vibrant/generator" "^3.2.1-alpha.1" + +"@vibrant/generator@^3.2.1-alpha.1": + version "3.2.1-alpha.1" + resolved "https://registry.yarnpkg.com/@vibrant/generator/-/generator-3.2.1-alpha.1.tgz#887b36f7ed978ff94c93cc8a3ac742ce769b6112" + integrity sha512-luS5YvMhwMqG01YTj1dJ+cmkuIw1VCByOR6zIaCOwQqI/mcOs88JBWcA1r2TywJTOPlVpjfnDvAlyaKBKh4dMA== + dependencies: + "@vibrant/color" "^3.2.1-alpha.1" + "@vibrant/types" "^3.2.1-alpha.1" + +"@vibrant/image-browser@^3.2.1-alpha.1": + version "3.2.1-alpha.1" + resolved "https://registry.yarnpkg.com/@vibrant/image-browser/-/image-browser-3.2.1-alpha.1.tgz#fe595bfe0c0ddc412300b5419e1e42d8b88d4380" + integrity sha512-6xWvQfB20sE6YtCWylgEAHuee3iD8h3aFIDbCS2yj7jIelKcYTrrp5jg2d2BhOOB6pC5JzF+QfpCrm0DmAIlgQ== + dependencies: + "@vibrant/image" "^3.2.1-alpha.1" + +"@vibrant/image-node@^3.2.1-alpha.1": + version "3.2.1-alpha.1" + resolved "https://registry.yarnpkg.com/@vibrant/image-node/-/image-node-3.2.1-alpha.1.tgz#2901e09aee05d64ac9e792a951ee0727299ab80f" + integrity sha512-/Io/Rpo4EkO6AhaXdcxUXkbOFhSFtjm0LSAM4c0AyGA5EbC8PyZqjk8b11bQAEMCaYaweFQfTdGD7oVbXe21CQ== + dependencies: + "@jimp/custom" "^0.16.1" + "@jimp/plugin-resize" "^0.16.1" + "@jimp/types" "^0.16.1" + "@vibrant/image" "^3.2.1-alpha.1" + +"@vibrant/image@^3.2.1-alpha.1": + version "3.2.1-alpha.1" + resolved "https://registry.yarnpkg.com/@vibrant/image/-/image-3.2.1-alpha.1.tgz#8bcde820f5ad873e2e96b00479def80f86e925a5" + integrity sha512-4aF5k79QfyhZOqRovJpbnIjWfe3uuWhY8voqVdd4/qgu4o70/AwVlM+pYmCaJVzI45VWNWWHYA5QlYuKsXnBqQ== + dependencies: + "@vibrant/color" "^3.2.1-alpha.1" + "@vibrant/types" "^3.2.1-alpha.1" + +"@vibrant/quantizer-mmcq@^3.2.1-alpha.1": + version "3.2.1-alpha.1" + resolved "https://registry.yarnpkg.com/@vibrant/quantizer-mmcq/-/quantizer-mmcq-3.2.1-alpha.1.tgz#b36ecb48f4bff9ea35ed23389d8af79c079c079a" + integrity sha512-Wuk9PTZtxr8qsWTcgP6lcrrmrq36syVwxf+BUxdgQYntBcQ053SaN34lVGOJ0WPdK5vABoxbYljhceCgiILtZw== + dependencies: + "@vibrant/color" "^3.2.1-alpha.1" + "@vibrant/image" "^3.2.1-alpha.1" + "@vibrant/quantizer" "^3.2.1-alpha.1" + +"@vibrant/quantizer@^3.2.1-alpha.1": + version "3.2.1-alpha.1" + resolved "https://registry.yarnpkg.com/@vibrant/quantizer/-/quantizer-3.2.1-alpha.1.tgz#8d29e288ea7acbcd0c9ab8c6b86f80adce606210" + integrity sha512-iHnPx/+n4iLtYLm1GClSfyg2fFbMatFG0ipCyp9M6tXNIPAg+pSvUJSGBnVnH7Nl/bR8Gkkj1h0pJ4RsKcdIrQ== + dependencies: + "@vibrant/color" "^3.2.1-alpha.1" + "@vibrant/image" "^3.2.1-alpha.1" + "@vibrant/types" "^3.2.1-alpha.1" + +"@vibrant/types@^3.2.1-alpha.1": + version "3.2.1-alpha.1" + resolved "https://registry.yarnpkg.com/@vibrant/types/-/types-3.2.1-alpha.1.tgz#54ecf8b4d1045af699bfaf592e455079801bc951" + integrity sha512-ts9u7nsrENoYI5s0MmPOeY5kCLFKvQndKVDOPFCbTA0z493uhDp8mpiQhjFYTf3kPbS04z9zbHLE2luFC7x4KQ== + +"@vibrant/worker@^3.2.1-alpha.1": + version "3.2.1-alpha.1" + resolved "https://registry.yarnpkg.com/@vibrant/worker/-/worker-3.2.1-alpha.1.tgz#d09e4ec72902d36b9632c2c0aab855747acf1015" + integrity sha512-mtSlBdHkFNr4FOnMtqtHJxy9z5AsUcZzGlpiHzvWOoaoN9lNTDPwxOBd0q4VTYWuGPrIm6Fuq5m7aRbLv7KqiQ== + dependencies: + "@vibrant/types" "^3.2.1-alpha.1" + "@vue/web-component-wrapper@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@vue/web-component-wrapper/-/web-component-wrapper-1.2.0.tgz#bb0e46f1585a7e289b4ee6067dcc5a6ae62f1dd1" @@ -8870,7 +8953,7 @@ lodash@^4.17.10, lodash@^4.17.11: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== -lodash@^4.17.19, lodash@^4.17.20: +lodash@^4.17.19: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -9546,17 +9629,17 @@ node-releases@^1.1.61: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.61.tgz#707b0fca9ce4e11783612ba4a2fcba09047af16e" integrity sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g== -node-vibrant@^3.1.6: - version "3.1.6" - resolved "https://registry.yarnpkg.com/node-vibrant/-/node-vibrant-3.1.6.tgz#8554c3108903232cbe1e722f928469ee4379aa18" - integrity sha512-Wlc/hQmBMOu6xon12ZJHS2N3M+I6J8DhrD3Yo6m5175v8sFkVIN+UjhKVRcO+fqvre89ASTpmiFEP3nPO13SwA== +node-vibrant@3.2.1-alpha.1: + version "3.2.1-alpha.1" + resolved "https://registry.yarnpkg.com/node-vibrant/-/node-vibrant-3.2.1-alpha.1.tgz#d80a3dd22741150b804ae0d3eb99ceaf9f79980a" + integrity sha512-EQergCp7fvbvUCE0VMCBnvaAV0lGWSP8SXLmuWQIBzQK5M5pIwcd9fIOXuzFkJx/8hUiiiLvAzzGDS/bIy2ikA== dependencies: - "@jimp/custom" "^0.16.1" - "@jimp/plugin-resize" "^0.16.1" - "@jimp/types" "^0.16.1" - "@types/lodash" "^4.14.53" - "@types/node" "^10.11.7" - lodash "^4.17.20" + "@types/node" "^10.12.18" + "@vibrant/core" "^3.2.1-alpha.1" + "@vibrant/generator-default" "^3.2.1-alpha.1" + "@vibrant/image-browser" "^3.2.1-alpha.1" + "@vibrant/image-node" "^3.2.1-alpha.1" + "@vibrant/quantizer-mmcq" "^3.2.1-alpha.1" url "^0.11.0" nopt@^4.0.1: