From f7975c041adadfbdcbadd8760314f2c113b0f2ba Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Sat, 24 Apr 2021 18:21:49 +1000 Subject: [PATCH] Added token outlines --- package.json | 1 + src/components/map/MapInteraction.js | 9 +- src/components/map/MapToken.js | 73 +++++++++------ src/components/token/Tokens.js | 3 + src/database.js | 60 +++++++++++-- src/modals/SelectTokensModal.js | 11 +++ src/tokens/index.js | 10 +++ yarn.lock | 129 ++++++++++++++++++++++++++- 8 files changed, 249 insertions(+), 47 deletions(-) diff --git a/package.json b/package.json index 628ff9a..546abb7 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "fake-indexeddb": "^3.1.2", "file-saver": "^2.0.5", "fuse.js": "^6.4.6", + "image-outline": "^0.1.0", "interactjs": "^1.10.8", "konva": "^7.2.5", "lodash.clonedeep": "^4.5.0", diff --git a/src/components/map/MapInteraction.js b/src/components/map/MapInteraction.js index 3d63a34..fc08eff 100644 --- a/src/components/map/MapInteraction.js +++ b/src/components/map/MapInteraction.js @@ -30,16 +30,9 @@ function MapInteraction({ }) { const [mapImage, mapImageStatus] = useMapImage(map); - // Map loaded taking in to account different resolutions const [mapLoaded, setMapLoaded] = useState(false); useEffect(() => { - if ( - !map || - !mapState || - // FIXME - (map.type === "file" && !map.file && !map.resolutions) || - mapState.mapId !== map.id - ) { + if (!map || !mapState || mapState.mapId !== map.id) { setMapLoaded(false); } else if (mapImageStatus === "loaded") { setMapLoaded(true); diff --git a/src/components/map/MapToken.js b/src/components/map/MapToken.js index ccb2770..c2f0ebb 100644 --- a/src/components/map/MapToken.js +++ b/src/components/map/MapToken.js @@ -1,5 +1,5 @@ import React, { useState, useEffect, useRef } from "react"; -import { Image as KonvaImage, Group } from "react-konva"; +import { Image as KonvaImage, Group, Line } from "react-konva"; import { useSpring, animated } from "react-spring/konva"; import useImage from "use-image"; import Konva from "konva"; @@ -21,7 +21,9 @@ import { useDataURL } from "../../contexts/AssetsContext"; import TokenStatus from "../token/TokenStatus"; import TokenLabel from "../token/TokenLabel"; -import { tokenSources, unknownSource } from "../../tokens"; +import colors from "../../helpers/colors"; + +import { tokenSources } from "../../tokens"; function MapToken({ tokenState, @@ -42,15 +44,10 @@ function MapToken({ const gridCellPixelSize = useGridCellPixelSize(); - const tokenSource = useDataURL(tokenState, tokenSources, unknownSource); - const [tokenSourceImage, tokenSourceStatus] = useImage(tokenSource); - const [tokenAspectRatio, setTokenAspectRatio] = useState(1); + const tokenURL = useDataURL(tokenState, tokenSources); + const [tokenImage, tokenImageStatus] = useImage(tokenURL); - useEffect(() => { - if (tokenSourceImage) { - setTokenAspectRatio(tokenSourceImage.width / tokenSourceImage.height); - } - }, [tokenSourceImage]); + const tokenAspectRatio = tokenState.width / tokenState.height; const snapPositionToGrid = useGridSnapping(); @@ -196,15 +193,12 @@ function MapToken({ const pixelRatio = canvas.pixelRatio || 1; if ( - tokenSourceStatus === "loaded" && + tokenImageStatus === "loaded" && tokenWidth > 0 && tokenHeight > 0 && - tokenSourceImage + tokenImage ) { - const maxImageSize = Math.max( - tokenSourceImage.width, - tokenSourceImage.height - ); + const maxImageSize = Math.max(tokenImage.width, tokenImage.height); const maxTokenSize = Math.max(tokenWidth, tokenHeight); // Constrain image buffer to original image size const maxRatio = maxImageSize / maxTokenSize; @@ -221,8 +215,8 @@ function MapToken({ debouncedStageScale, tokenWidth, tokenHeight, - tokenSourceStatus, - tokenSourceImage, + tokenImageStatus, + tokenImage, ]); // Animate to new token positions if edited by others @@ -273,17 +267,38 @@ function MapToken({ name={tokenName} id={tokenState.id} > - + {!tokenImage ? ( + + [x * tokenWidth, y * tokenHeight]) + .flat(1)} + fill={colors.black} + width={tokenWidth} + height={tokenHeight} + x={0} + y={0} + rotation={tokenState.rotation} + offsetX={tokenWidth / 2} + offsetY={tokenHeight / 2} + closed + // Round edges for more complex shapes + tension={tokenState.outline.length > 6 ? 0.333 : 0} + /> + + ) : ( + + )} { + v.stores({}).upgrade((tx) => { tx.table("tokens").each((token) => { let assets = []; assets.push({ @@ -505,7 +507,7 @@ const versions = { }, // v1.9.0 - Create foreign keys for assets 25(v) { - v.stores().upgrade((tx) => { + v.stores({}).upgrade((tx) => { tx.table("assets").each((asset) => { if (asset.prevType === "map") { tx.table("maps").update(asset.prevId, { @@ -530,7 +532,7 @@ const versions = { }, // v1.9.0 - Remove asset migration helpers 26(v) { - v.stores().upgrade((tx) => { + v.stores({}).upgrade((tx) => { tx.table("assets") .toCollection() .modify((asset) => { @@ -544,7 +546,7 @@ const versions = { }, // v1.9.0 - Remap map resolution assets 27(v) { - v.stores().upgrade((tx) => { + v.stores({}).upgrade((tx) => { tx.table("maps") .toCollection() .modify((map) => { @@ -559,19 +561,40 @@ const versions = { }); }); }, + // v1.9.0 - Move tokens to use more defaults and add token outline 28(v) { - v.stores().upgrade((tx) => { + v.stores({}).upgrade((tx) => { tx.table("tokens") .toCollection() - .modify((token) => { + .modify(async (token) => { token.defaultCategory = token.category; delete token.category; token.defaultLabel = ""; + if (token.width === token.height) { + token.outline = [ + { x: 0.5, y: 0.0 }, + { x: 0.85, y: 0.15 }, + { x: 1.0, y: 0.5 }, + { x: 0.85, y: 0.85 }, + { x: 0.5, y: 1.0 }, + { x: 0.15, y: 0.85 }, + { x: 0.0, y: 0.5 }, + { x: 0.15, y: 0.15 }, + ]; + } else { + token.outline = [ + { x: 0.0, y: 0.0 }, + { x: 1.0, y: 0.0 }, + { x: 1.0, y: 1.0 }, + { x: 0.0, y: 1.0 }, + ]; + } }); }); }, + // v1.9.0 - Move tokens to use more defaults and add token outline 29(v) { - v.stores().upgrade((tx) => { + v.stores({}).upgrade((tx) => { tx.table("states") .toCollection() .modify(async (state) => { @@ -582,15 +605,38 @@ const versions = { tokenState.category = token.defaultCategory; tokenState.file = token.file; tokenState.type = "file"; + tokenState.outline = token.outline; + tokenState.width = token.width; + tokenState.height = token.height; } else { tokenState.category = "character"; tokenState.type = "file"; tokenState.file = ""; + tokenState.outline = [ + { x: 0.0, y: 0.0 }, + { x: 1.0, y: 0.0 }, + { x: 1.0, y: 1.0 }, + { x: 0.0, y: 1.0 }, + ]; + tokenState.width = 256; + tokenState.height = 256; } } else { tokenState.category = "character"; tokenState.type = "default"; tokenState.key = Case.camel(tokenState.tokenId.slice(10)); + tokenState.outline = [ + { x: 0.5, y: 0.0 }, + { x: 0.85, y: 0.15 }, + { x: 1.0, y: 0.5 }, + { x: 0.85, y: 0.85 }, + { x: 0.5, y: 1.0 }, + { x: 0.15, y: 0.85 }, + { x: 0.0, y: 0.5 }, + { x: 0.15, y: 0.15 }, + ]; + tokenState.width = 256; + tokenState.height = 256; } } }); diff --git a/src/modals/SelectTokensModal.js b/src/modals/SelectTokensModal.js index 49e5ccd..c52cdb0 100644 --- a/src/modals/SelectTokensModal.js +++ b/src/modals/SelectTokensModal.js @@ -3,6 +3,7 @@ import { Flex, Label, Button } from "theme-ui"; import { v4 as uuid } from "uuid"; import Case from "case"; import { useToasts } from "react-toast-notifications"; +import imageOutline from "image-outline"; import EditTokenModal from "./EditTokenModal"; import EditGroupModal from "./EditGroupModal"; @@ -16,6 +17,7 @@ import LoadingOverlay from "../components/LoadingOverlay"; import blobToBuffer from "../helpers/blobToBuffer"; import { useSearch, useGroup, handleItemSelect } from "../helpers/select"; import { createThumbnail } from "../helpers/image"; +import Vector2 from "../helpers/Vector2"; import useResponsiveLayout from "../hooks/useResponsiveLayout"; @@ -177,6 +179,14 @@ function SelectTokensModal({ isOpen, onRequestClose }) { }; assets.push(fileAsset); + let outline = imageOutline(image).map(({ x, y }) => ({ + x: x / image.width, + y: y / image.height, + })); + if (outline.length > 100) { + outline = Vector2.resample(outline, 100); + } + const token = { name, thumbnail: thumbnail.id, @@ -194,6 +204,7 @@ function SelectTokensModal({ isOpen, onRequestClose }) { group: "", width: image.width, height: image.height, + outline, }; handleTokenAdd(token, assets); diff --git a/src/tokens/index.js b/src/tokens/index.js index 4f6c0f8..f4174e4 100644 --- a/src/tokens/index.js +++ b/src/tokens/index.js @@ -90,6 +90,16 @@ export const tokens = Object.keys(tokenSources).map((key) => ({ hideInSidebar: false, width: 256, height: 256, + outline: [ + { x: 0.5, y: 0.0 }, + { x: 0.85, y: 0.15 }, + { x: 1.0, y: 0.5 }, + { x: 0.85, y: 0.85 }, + { x: 0.5, y: 1.0 }, + { x: 0.15, y: 0.85 }, + { x: 0.0, y: 0.5 }, + { x: 0.15, y: 0.15 }, + ], })); export const unknownSource = unknown; diff --git a/yarn.lock b/yarn.lock index 9ea015e..fe9cb37 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5119,6 +5119,13 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.5.tgz#7fdec6a28a67ae18647c51668a9ff95bb2fa7bb8" integrity sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ== +cwise-compiler@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cwise-compiler/-/cwise-compiler-1.1.3.tgz#f4d667410e850d3a313a7d2db7b1e505bb034cc5" + integrity sha1-9NZnQQ6FDToxOn0tt7HlBbsDTMU= + dependencies: + uniq "^1.0.0" + cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -5144,6 +5151,11 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +data-uri-to-buffer@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-0.0.3.tgz#18ae979a6a0ca994b0625853916d2662bbae0b1a" + integrity sha1-GK6XmmoMqZSwYlhTkW0mYruuCxo= + data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -5357,6 +5369,11 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +distance-to-line-segment@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/distance-to-line-segment/-/distance-to-line-segment-0.2.0.tgz#e45427bb8360eb59a86ffd9814a7578dd2c3d679" + integrity sha1-5FQnu4Ng61mob/2YFKdXjdLD1nk= + dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" @@ -6623,6 +6640,23 @@ get-package-type@^0.1.0: resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-pixels@^3.2.3: + version "3.3.2" + resolved "https://registry.yarnpkg.com/get-pixels/-/get-pixels-3.3.2.tgz#3f62fb8811932c69f262bba07cba72b692b4ff03" + integrity sha512-6ar+8yPxRd1pskEcl2GSEu1La0+xYRjjnkby6AYiRDDwZ0tJbPQmHnSeH9fGLskT8kvR0OukVgtZLcsENF9YKQ== + dependencies: + data-uri-to-buffer "0.0.3" + jpeg-js "^0.3.2" + mime-types "^2.0.1" + ndarray "^1.0.13" + ndarray-pack "^1.1.1" + node-bitmap "0.0.1" + omggif "^1.0.5" + parse-data-uri "^0.2.0" + pngjs "^3.3.3" + request "^2.44.0" + through "^2.3.4" + get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -7121,6 +7155,18 @@ ignore@^5.1.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +image-outline@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/image-outline/-/image-outline-0.1.0.tgz#b7818788e2ad30b4d8d57151e6e147d93e3ce9e3" + integrity sha1-t4GHiOKtMLTY1XFR5uFH2T486eM= + dependencies: + extend "^3.0.0" + get-pixels "^3.2.3" + line-simplify-rdp "^0.4.0" + marching-squares "^0.2.0" + minimist "^1.2.0" + ndarray "^1.0.18" + immer@8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656" @@ -7259,6 +7305,11 @@ invariant@^2.2.2: dependencies: loose-envify "^1.0.0" +iota-array@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/iota-array/-/iota-array-1.0.0.tgz#81ef57fe5d05814cd58c2483632a99c30a0e8087" + integrity sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc= + ip-regex@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" @@ -7340,7 +7391,7 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-buffer@^1.1.4, is-buffer@^1.1.5: +is-buffer@^1.0.2, is-buffer@^1.1.4, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== @@ -8155,6 +8206,11 @@ jest@26.6.0: import-local "^3.0.2" jest-cli "^26.6.0" +jpeg-js@^0.3.2: + version "0.3.7" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.7.tgz#471a89d06011640592d314158608690172b1028d" + integrity sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -8398,6 +8454,13 @@ line-column@^1.0.2: isarray "^1.0.0" isobject "^2.0.0" +line-simplify-rdp@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/line-simplify-rdp/-/line-simplify-rdp-0.4.0.tgz#b9632e870d2f9bc3c696b8b9de4a6259a05fa816" + integrity sha1-uWMuhw0vm8PGlri53kpiWaBfqBY= + dependencies: + distance-to-line-segment "^0.2.0" + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" @@ -8627,6 +8690,11 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +marching-squares@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/marching-squares/-/marching-squares-0.2.0.tgz#28086170bf77d8dbd578459d997a90526cf5faf0" + integrity sha1-KAhhcL932NvVeEWdmXqQUmz1+vA= + markdown-escapes@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" @@ -8749,11 +8817,23 @@ mime-db@1.44.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== +mime-db@1.47.0: + version "1.47.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" + integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== + "mime-db@>= 1.43.0 < 2": version "1.45.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea" integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== +mime-types@^2.0.1: + version "2.1.30" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" + integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== + dependencies: + mime-db "1.47.0" + mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" @@ -8977,6 +9057,22 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +ndarray-pack@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ndarray-pack/-/ndarray-pack-1.2.1.tgz#8caebeaaa24d5ecf70ff86020637977da8ee585a" + integrity sha1-jK6+qqJNXs9w/4YCBjeXfajuWFo= + dependencies: + cwise-compiler "^1.1.2" + ndarray "^1.0.13" + +ndarray@^1.0.13, ndarray@^1.0.18: + version "1.0.19" + resolved "https://registry.yarnpkg.com/ndarray/-/ndarray-1.0.19.tgz#6785b5f5dfa58b83e31ae5b2a058cfd1ab3f694e" + integrity sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ== + dependencies: + iota-array "^1.0.0" + is-buffer "^1.0.2" + negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" @@ -9005,6 +9101,11 @@ no-case@^3.0.3: lower-case "^2.0.1" tslib "^1.10.0" +node-bitmap@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/node-bitmap/-/node-bitmap-0.0.1.tgz#180eac7003e0c707618ef31368f62f84b2a69091" + integrity sha1-GA6scAPgxwdhjvMTaPYvhLKmkJE= + node-fetch@~2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" @@ -9262,6 +9363,11 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +omggif@^1.0.5: + version "1.0.10" + resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" + integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw== + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -9476,6 +9582,13 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: pbkdf2 "^3.0.3" safe-buffer "^5.1.1" +parse-data-uri@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/parse-data-uri/-/parse-data-uri-0.2.0.tgz#bf04d851dd5c87b0ab238e5d01ace494b604b4c9" + integrity sha1-vwTYUd1ch7CrI45dAazklLYEtMk= + dependencies: + data-uri-to-buffer "0.0.3" + parse-entities@^1.1.0: version "1.2.2" resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50" @@ -9698,6 +9811,11 @@ pkg-up@3.1.0: dependencies: find-up "^3.0.0" +pngjs@^3.3.3: + version "3.4.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" + integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== + pnp-webpack-plugin@1.6.4: version "1.6.4" resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" @@ -11202,7 +11320,7 @@ request-promise-native@^1.0.8: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.88.2: +request@^2.44.0, request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -12538,6 +12656,11 @@ through2@^2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" +through@^2.3.4: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + thunky@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" @@ -12853,7 +12976,7 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" -uniq@^1.0.1: +uniq@^1.0.0, uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=