diff --git a/package.json b/package.json index d2fd16c..e85c638 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "d3-force-3d", - "version": "3.0.5", + "version": "3.0.6", "description": "Force-directed graph layout in 1D, 2D or 3D using velocity Verlet integration.", "homepage": "https://github.com/vasturiano/d3-force-3d", "repository": { @@ -32,7 +32,9 @@ "main": "src/index.js", "jsdelivr": "dist/d3-force-3d.min.js", "unpkg": "dist/d3-force-3d.min.js", + "types": "dist/d3-force-3d.d.ts", "exports": { + "types": "./dist/d3-force-3d.d.ts", "umd": "./dist/d3-force-3d.min.js", "default": "./src/index.js" }, @@ -49,7 +51,9 @@ "@rollup/plugin-terser": "^0.4.0", "eslint": "^8.33.0", "mocha": "^10.2.0", - "rollup": "^3.14.0" + "rollup": "^3.14.0", + "rollup-plugin-dts": "^6.1.0", + "typescript": "^5.4.4" }, "scripts": { "test": "mocha 'test/**/*-test.js' && eslint src test", diff --git a/rollup.config.js b/rollup.config.js index 0f4063c..5bd7ac2 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,20 +1,28 @@ import nodeResolve from '@rollup/plugin-node-resolve'; -import terser from "@rollup/plugin-terser"; +import terser from '@rollup/plugin-terser'; +import dts from 'rollup-plugin-dts'; import meta from './package.json' assert { type: 'json' }; const config = { - input: "src/index.js", - external: Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)), + input: 'src/index.js', + external: Object.keys(meta.dependencies || {}).filter((key) => + /^d3-/.test(key) + ), output: { file: `dist/${meta.name}.js`, - name: "d3", - format: "umd", + name: 'd3', + format: 'umd', indent: false, extend: true, banner: `// ${meta.homepage} v${meta.version}`, - globals: Object.assign({}, ...Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)).map(key => ({[key]: "d3"}))) + globals: Object.assign( + {}, + ...Object.keys(meta.dependencies || {}) + .filter((key) => /^d3-/.test(key)) + .map((key) => ({ [key]: 'd3' })) + ), }, - plugins: [] + plugins: [], }; export default [ @@ -23,16 +31,26 @@ export default [ ...config, output: { ...config.output, - file: `dist/${meta.name}.min.js` + file: `dist/${meta.name}.min.js`, }, plugins: [ ...config.plugins, nodeResolve({ jsnext: true }), terser({ output: { - preamble: config.output.banner - } - }) - ] - } + preamble: config.output.banner, + }, + }), + ], + }, + { + input: 'src/index.d.ts', + output: [ + { + file: `dist/${meta.name}.d.ts`, + format: 'es', + }, + ], + plugins: [dts()], + }, ]; diff --git a/src/index.d.ts b/src/index.d.ts new file mode 100644 index 0000000..dde9d14 --- /dev/null +++ b/src/index.d.ts @@ -0,0 +1,294 @@ +declare module 'd3-force-3d' { + export function forceCenter(x?: number, y?: number, z?: number): ForceCenter; + + export function forceCollide( + radius?: + | number + | ((node: NodeData, index: number, nodes: NodeData[]) => number) + ): ForceCollide; + + export function forceLink(links?: LinkData[]): ForceLink; + + export function forceManyBody(): ForceManyBody; + + export function forceRadial( + radius?: + | number + | ((node: NodeData, index: number, nodes: NodeData[]) => number), + x?: number, + y?: number, + z?: number + ): ForceRadial; + + export function forceSimulation( + nodes?: NodeData[], + numDimensions?: Dimensions + ): ForceSimulation; + + export function forceX(x?: number): ForceX; + + export function forceY(y?: number): ForceY; + + export function forceZ(z?: number): ForceZ; + + interface ForceSimulation { + tick(iterations?: number): this; + + restart(): this; + + stop(): this; + + numDimensions(): Dimensions; + numDimensions(value: Dimensions): this; + + nodes(): NodeData[]; + nodes(nodes: NodeData[]): this; + + alpha(): number; + alpha(alpha: number): this; + + alphaMin(): number; + alphaMin(min: number): this; + + alphaDecay(): number; + alphaDecay(decay: number): this; + + alphaTarget(): number; + alphaTarget(target: number): this; + + velocityDecay(): number; + velocityDecay(decay: number): this; + + randomSource(): () => number; + randomSource(source: () => number): this; + + force(name: string): T; + force(name: string, force: Force | null): this; + + find(x?: number, y?: number, z?: number, radius?: number): NodeData; + + on(name: string): (...args: any[]) => void; + on(name: string, listener: (...args: any[]) => void): this; + } + + type Force = + | ForceCenter + | ForceCollide + | ForceLink + | ForceManyBody + | ForceRadial + | ForceX + | ForceY + | ForceZ; + + interface ForceCenter { + (): void; + + initialize(nodes: NodeData[]): void; + + x(): number; + x(x: number): this; + + y(): number; + y(y: number): this; + + z(): number; + z(z: number): this; + + strength(): number; + strength(strength: number): this; + } + + interface ForceCollide { + (): void; + + initialize( + nodes: NodeData[], + random?: () => number, + nDim?: Dimensions + ): void; + + iterations(): number; + iterations(iterations: number): this; + + strength(): number; + strength(strength: number): this; + + radius(): number; + radius( + radius: + | number + | ((node: NodeData, index: number, nodes: NodeData[]) => number) + ): this; + } + + interface ForceLink { + (alpha: number): void; + + initialize(nodes: NodeData[], random: () => number, dim: Dimensions): void; + + links(): LinkData[]; + links(links: LinkData[]): this; + + id(): (node: NodeData, index: number, nodes: NodeData[]) => any; + id(id: (node: NodeData, index: number, nodes: NodeData[]) => any): this; + + iterations(): number; + iterations(iterations: number): this; + + strength(): (link: LinkData, index: number, links: LinkData[]) => number; + strength( + strength: + | number + | ((link: LinkData, index: number, links: LinkData[]) => number) + ): this; + + distance(): (link: LinkData, index: number, links: LinkData[]) => number; + distance( + distance: + | number + | ((link: LinkData, index: number, links: LinkData[]) => number) + ): this; + } + + interface ForceManyBody { + (alpha: number): void; + + initialize(nodes: NodeData[], random: () => number, dim: Dimensions): void; + + strength(): (node: NodeData, index: number, nodes: NodeData[]) => number; + strength( + strength: + | number + | ((node: NodeData, index: number, nodes: NodeData[]) => number) + ): this; + + distanceMin(): number; + distanceMin(min: number): this; + + distanceMax(): number; + distanceMax(max: number): this; + + theta(): number; + theta(theta: number): this; + } + + interface ForceRadial { + (alpha: number): void; + + initialize(nodes: NodeData[], dim: Dimensions): void; + + strength(): (node: NodeData, index: number, nodes: NodeData[]) => number; + strength( + strength: + | number + | ((node: NodeData, index: number, nodes: NodeData[]) => number) + ): this; + + radius(): (node: NodeData, index: number, nodes: NodeData[]) => number; + radius( + radius: + | number + | ((node: NodeData, index: number, nodes: NodeData[]) => number) + ): this; + + x(): number; + x(x: number): this; + + y(): number; + y(y: number): this; + + z(): number; + z(z: number): this; + } + + interface ForceX { + (alpha: number): void; + + initialize(nodes: NodeData[]): void; + + strength(): number; + strength( + strength: + | number + | ((node: NodeData, index: number, nodes: NodeData[]) => number) + ): this; + + x(): number; + x( + x: number | ((node: NodeData, index: number, nodes: NodeData[]) => number) + ): this; + } + + interface ForceY { + (alpha: number): void; + + initialize(nodes: NodeData[]): void; + + strength(): number; + strength( + strength: + | number + | ((node: NodeData, index: number, nodes: NodeData[]) => number) + ): this; + + y(): number; + y( + y: number | ((node: NodeData, index: number, nodes: NodeData[]) => number) + ): this; + } + + interface ForceZ { + (alpha: number): void; + + initialize(nodes: NodeData[]): void; + + strength(): number; + strength( + strength: + | number + | ((node: NodeData, index: number, nodes: NodeData[]) => number) + ): this; + + z(): number; + z( + z: number | ((node: NodeData, index: number, nodes: NodeData[]) => number) + ): this; + } + + interface NodeData { + /** the node’s zero-based index into nodes */ + index?: number; + /** the node’s current x-position */ + x?: number; + /** the node’s current y-position (if using 2 or more dimensions) */ + y?: number; + /** the node’s current z-position (if using 3 dimensions) */ + z?: number; + /** the node’s current x-velocity */ + vx?: number; + /** the node’s current y-velocity (if using 2 or more dimensions) */ + vy?: number; + /** the node’s current z-velocity (if using 3 dimensions) */ + vz?: number; + /** the node’s fixed x-position */ + fx?: number; + /** the node’s fixed y-position */ + fy?: number; + /** the node’s fixed z-position */ + fz?: number; + [key: string]: any; + } + + interface LinkData { + /** the zero-based index into links, assigned by this method */ + index?: number; + /** the link’s source node */ + source: NodeData | any; + /** the link’s target node */ + target: NodeData | any; + [key: string]: any; + } + + type Dimensions = 1 | 2 | 3; +} diff --git a/yarn.lock b/yarn.lock index c623a71..a90f75a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,29 @@ # yarn lockfile v1 +"@babel/code-frame@^7.22.13": + version "7.24.2" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" + integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== + dependencies: + "@babel/highlight" "^7.24.2" + picocolors "^1.0.0" + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/highlight@^7.24.2": + version "7.24.2" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz#3f539503efc83d3c59080a10e6634306e0370d26" + integrity sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + "@eslint/eslintrc@^1.4.1": version "1.4.1" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.4.1.tgz#af58772019a2d271b7e2d4c23ff4ddcba3ccfb3e" @@ -68,6 +91,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/sourcemap-codec@^1.4.15": + version "1.4.15" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + "@jridgewell/trace-mapping@^0.3.9": version "0.3.17" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" @@ -167,6 +195,13 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -244,6 +279,15 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -276,6 +320,13 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -283,6 +334,11 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" @@ -381,6 +437,11 @@ escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + eslint-scope@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" @@ -621,6 +682,11 @@ grapheme-splitter@^1.0.4: resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" @@ -742,6 +808,11 @@ js-sdsl@^4.1.4: resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.3.0.tgz#aeefe32a451f7af88425b11fdb5f58c90ae1d711" integrity sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ== +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + js-yaml@4.1.0, js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" @@ -787,6 +858,13 @@ log-symbols@4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" +magic-string@^0.30.4: + version "0.30.9" + resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.9.tgz#8927ae21bfdd856310e07a1bc8dd5e73cb6c251d" + integrity sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + minimatch@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" @@ -913,6 +991,11 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -983,6 +1066,15 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +rollup-plugin-dts@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.1.0.tgz#56e9c5548dac717213c6a4aa9df523faf04f75ae" + integrity sha512-ijSCPICkRMDKDLBK9torss07+8dl9UpY9z1N/zTeA1cIqdzMlpkV3MOOC7zukyvQfDyxa1s3Dl2+DeiP/G6DOw== + dependencies: + magic-string "^0.30.4" + optionalDependencies: + "@babel/code-frame" "^7.22.13" + rollup@^3.14.0: version "3.14.0" resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.14.0.tgz#f5925255f3b6e8de1dba3916d7619c7da5708d95" @@ -1074,6 +1166,13 @@ supports-color@8.1.1: dependencies: has-flag "^4.0.0" +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -1120,6 +1219,11 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +typescript@^5.4.4: + version "5.4.4" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz#eb2471e7b0a5f1377523700a21669dce30c2d952" + integrity sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"