@datagrok/bio 2.13.3 → 2.13.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +1 -1
- package/CHANGELOG.md +23 -0
- package/detectors.js +52 -38
- package/dist/111.js +2 -0
- package/dist/111.js.map +1 -0
- package/dist/234.js +2 -0
- package/dist/234.js.map +1 -0
- package/dist/242.js +2 -0
- package/dist/242.js.map +1 -0
- package/dist/{286.js → 248.js} +1 -1
- package/dist/248.js.map +1 -0
- package/dist/284.js +3 -0
- package/dist/284.js.map +1 -0
- package/dist/317.js +2 -0
- package/dist/317.js.map +1 -0
- package/dist/589.js +2 -0
- package/dist/589.js.map +1 -0
- package/dist/603.js +2 -0
- package/dist/603.js.map +1 -0
- package/dist/682.js +2 -0
- package/dist/682.js.map +1 -0
- package/dist/705.js +2 -0
- package/dist/705.js.map +1 -0
- package/dist/{590.js → 731.js} +2 -2
- package/dist/731.js.map +1 -0
- package/dist/778.js +2 -0
- package/dist/778.js.map +1 -0
- package/dist/793.js +2 -0
- package/dist/793.js.map +1 -0
- package/dist/950.js +2 -0
- package/dist/950.js.map +1 -0
- package/dist/package-test.js +6 -7
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +6 -7
- package/dist/package.js.map +1 -1
- package/files/cache_config.json +7 -0
- package/package.json +12 -11
- package/src/analysis/sequence-activity-cliffs.ts +1 -1
- package/src/function-edtiors/split-to-monomers-editor.ts +6 -7
- package/src/package-types.ts +14 -7
- package/src/package.ts +6 -6
- package/src/substructure-search/substructure-search.ts +9 -10
- package/src/tests/WebLogo-positions-test.ts +6 -6
- package/src/tests/activity-cliffs-tests.ts +5 -2
- package/src/tests/bio-tests.ts +6 -6
- package/src/tests/checkInputColumn-tests.ts +3 -3
- package/src/tests/converters-test.ts +1 -1
- package/src/tests/detectors-tests.ts +25 -13
- package/src/tests/fasta-export-tests.ts +2 -2
- package/src/tests/mm-distance-tests.ts +1 -1
- package/src/tests/msa-tests.ts +2 -2
- package/src/tests/renderers-test.ts +5 -5
- package/src/tests/scoring.ts +26 -5
- package/src/tests/seq-handler-get-region.ts +4 -4
- package/src/tests/sequence-space-test.ts +1 -1
- package/src/tests/substructure-filters-tests.ts +4 -1
- package/src/tests/to-atomic-level-tests.ts +1 -1
- package/src/utils/cell-renderer.ts +4 -4
- package/src/utils/context-menu.ts +1 -1
- package/src/utils/convert.ts +7 -4
- package/src/utils/get-region-func-editor.ts +11 -16
- package/src/utils/get-region.ts +5 -5
- package/src/utils/macromolecule-column-widget.ts +1 -1
- package/src/utils/monomer-lib/lib-manager.ts +20 -8
- package/src/utils/monomer-lib/library-file-manager/file-manager.ts +28 -24
- package/src/utils/monomer-lib/library-file-manager/file-validator.ts +2 -1
- package/src/utils/monomer-lib/library-file-manager/ui.ts +3 -6
- package/src/utils/multiple-sequence-alignment-ui.ts +10 -11
- package/src/utils/multiple-sequence-alignment.ts +2 -2
- package/src/utils/pepsea.ts +1 -1
- package/src/utils/save-as-fasta.ts +5 -5
- package/src/viewers/vd-regions-viewer.ts +2 -2
- package/src/widgets/bio-substructure-filter.ts +7 -7
- package/src/widgets/package-settings-editor-widget.ts +6 -6
- package/src/widgets/representations.ts +1 -1
- package/tsconfig.json +4 -4
- package/dist/23.js +0 -2
- package/dist/23.js.map +0 -1
- package/dist/231.js +0 -2
- package/dist/231.js.map +0 -1
- package/dist/282.js +0 -2
- package/dist/282.js.map +0 -1
- package/dist/286.js.map +0 -1
- package/dist/356.js +0 -2
- package/dist/356.js.map +0 -1
- package/dist/36.js +0 -2
- package/dist/36.js.map +0 -1
- package/dist/40.js +0 -2
- package/dist/40.js.map +0 -1
- package/dist/413.js +0 -2
- package/dist/413.js.map +0 -1
- package/dist/42.js +0 -2
- package/dist/42.js.map +0 -1
- package/dist/427.js +0 -2
- package/dist/427.js.map +0 -1
- package/dist/545.js +0 -3
- package/dist/545.js.map +0 -1
- package/dist/590.js.map +0 -1
- package/dist/65.js +0 -2
- package/dist/65.js.map +0 -1
- package/dist/796.js +0 -2
- package/dist/796.js.map +0 -1
- package/dist/package-test.js.LICENSE.txt +0 -1
- package/dist/package.js.LICENSE.txt +0 -1
- /package/dist/{545.js.LICENSE.txt → 284.js.LICENSE.txt} +0 -0
package/dist/317.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var bio;(()=>{"use strict";var e,n,t={9260:(e,n,t)=>{var r;!function(e){e.EUCLIDEAN="EUCLIDEAN",e.MANHATTAN="MANHATTAN"}(r||(r={}));const a={[r.EUCLIDEAN]:function(e){return`\n var sum = 0.0;\n for (var i = 0u; i < ${e}; i = i + 1u) {\n sum = sum + distances[i] * distances[i] * computeInfo.weights[i] * computeInfo.weights[i];\n }\n return sqrt(sum);\n `},[r.MANHATTAN]:function(e){return`\n var sum = 0.0;\n for (var i = 0u; i < ${e}; i = i + 1u) {\n sum = sum + abs(distances[i]) * computeInfo.weights[i];\n }\n return sum;\n `}};var i;!function(e){e.HAMMING="Hamming",e.EUCLIDEAN="Euclidean",e.MANHATTAN="Manhattan",e.TANIMOTO="Tanimoto",e.LEVENSTEIN="Levenshtein",e.NEEDLEMAN_WUNSCH="Needlemann-Wunsch",e.MONOMER_CHEMICAL_DISTANCE="Monomer chemical distance",e.SOKAL="Sokal",e.COSINE="Cosine",e.ASYMMETRIC="Asymmetric",e.Difference="Difference",e.OneHot="One-Hot"}(i||(i={}));const o={[i.HAMMING]:function(e,n){return`\n let aLength: u32 = computeInfo.entrySizes[${n}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${n}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n let sizeDiff: u32 = maxLength - minLength;\n \n let maxIntDistance = ceil(maxDistance * f32(maxLength)) - f32(sizeDiff);\n\n var diff: f32 = 0.0;\n for (var i = 0u; i < ${e}; i = i + 1u) {\n diff = diff + f32(a[i] != b[i]);\n if (diff > maxIntDistance) {\n return 1.0;\n }\n }\n diff += f32(sizeDiff);\n return diff / ${e};\n `},[i.EUCLIDEAN]:function(e,n){return`\n var dist: f32 = 0.0;\n for (var i = 0u; i < ${e}; i = i + 1u) {\n dist = dist + f32(a[i] - b[i]) * f32(a[i] - b[i]);\n }\n return sqrt(dist);\n `},[i.MANHATTAN]:function(e,n){return`\n var dist: f32 = 0.0;\n for (var i = 0u; i < ${e}; i = i + 1u) {\n dist = dist + abs(f32(a[i] - b[i]));\n }\n return dist;\n `},[i.TANIMOTO]:function(e,n){return`\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${e}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n\n if (onBitsa == 0u && onBitsb == 0u) {\n return 0.0;\n }\n\n let totalOnBits = onBitsa + onBitsb;\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${e}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n\n return 1.0 - f32(commonBits) / f32(totalOnBits - commonBits);\n `},[i.LEVENSTEIN]:function(e,n){return`\n let aLength: u32 = computeInfo.entrySizes[${n}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${n}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n\n let maxIntDistance = ceil(maxDistance * f32(maxLength));\n\n // we will store two arrays as matrix and swap the working indices per pass.\n // this way we can reduce memory usage per computation to just O(aLength)\n // the grid will have aLength + 1 columns and bLength + 1 rows\n // this will be guaranteed by iteration, but the array sizes must be known at compile time, so we will use a fixed size of maxArraySize\n var dynamicPassMat: array<array<f32, ${e+1}u>, 2>; // initialize to 0\n \n var prevIndex: u32 = 0;\n var curIndex: u32 = 1; // we will swap these indices per pass\n\n // initialize the first row\n for (var i = 0u; i <= aLength; i = i + 1u) {\n dynamicPassMat[prevIndex][i] = f32(i);\n }\n\n // iterate over the rows\n for (var i = 1u; i <= bLength; i = i + 1u) {\n dynamicPassMat[curIndex][0] = f32(i);\n var minEntry: f32 = f32(maxLength);\n let prevRow = &dynamicPassMat[prevIndex];\n let curRow = &dynamicPassMat[curIndex];\n let bMon = u32(b[i - 1]);\n for (var j = 1u; j <= aLength; j = j + 1u) {\n var cost: f32 = f32(a[j - 1] != bMon);\n var res: f32 = min(\n min(\n (*prevRow)[j] + 1.0, // deletion\n (*curRow)[j - 1] + 1.0, // insertion\n ),\n (*prevRow)[j - 1] + cost // substitution\n );\n (*curRow)[j] = res;\n if (res < minEntry) {\n minEntry = res;\n }\n }\n // swap the indices\n let temp: u32 = prevIndex;\n prevIndex = curIndex;\n curIndex = temp;\n if (minEntry > maxIntDistance) {\n return 1.0;\n }\n }\n\n return dynamicPassMat[prevIndex][aLength] / f32(maxLength);\n `},[i.NEEDLEMAN_WUNSCH]:function(e,n){return`\n let aLength: u32 = computeInfo.entrySizes[${n}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${n}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n \n let maxIntDistance = ceil(maxDistance * f32(maxLength));\n // we will store two arrays as matrix and swap the working indices per pass.\n // this way we can reduce memory usage per computation to just O(aLength)\n // the grid will have aLength + 1 columns and bLength + 1 rows\n // this will be guaranteed by iteration, but the array sizes must be known at compile time, so we will use a fixed size of maxArraySize\n var dynamicPassMat: array<array<f32, ${e+1}u>, 2>; // initialize to 0\n \n // we need to keep track of which operation led to the current cell\n // i.e. whether we came from the left, top or diagonal to assign gap open/gap extend penalty\n var verticalGaps: array<u32, ${e+1}u>;\n var horizontalGaps: array<u32, ${e+1}u>;\n\n let gapOpenPenalty: f32 = suppInfo.gapOpenPenalty${n};\n let gapExtensionPenalty: f32 = suppInfo.gapExtensionPenalty${n};\n var prevIndex: u32 = 0;\n var curIndex: u32 = 1; // we will swap these indices per pass\n // initialize the first row\n for (var i = 0u; i <= aLength; i = i + 1u) {\n dynamicPassMat[prevIndex][i] = gapOpenPenalty + f32(i - 1) * gapExtensionPenalty;\n dynamicPassMat[curIndex][i] = 0.0;\n }\n dynamicPassMat[0][0] = 0.0;\n\n let simMatrix = &suppInfo.similarityMatrix${n}; // using pointers make things faster\n // iterate over the rows\n for (var i = 1u; i <= bLength; i = i + 1u) {\n let prevRow = &dynamicPassMat[prevIndex];\n let curRow = &dynamicPassMat[curIndex];\n (*curRow)[0] = gapOpenPenalty + f32(i - 1) * gapExtensionPenalty;\n var minEntry: f32 = f32(maxLength);\n let monB = u32(b[i - 1]);\n for (var j = 1u; j <= aLength; j = j + 1u) {\n let monA = u32(a[j - 1]);\n \n let cost: f32 = (*prevRow)[j - 1] + 1f - (*simMatrix)[monA][monB];\n var top = (*prevRow)[j]; // deletion\n if (verticalGaps[j] > 0) {\n top = top + gapExtensionPenalty;\n } else {\n top = top + gapOpenPenalty;\n }\n var left = (*curRow)[j - 1]; // insertion\n if (horizontalGaps[j - 1] > 0) {\n left = left + gapExtensionPenalty;\n } else {\n left = left + gapOpenPenalty;\n }\n var res: f32 = min(\n min(\n top, // deletion\n left, // insertion\n ),\n cost // substitution\n );\n (*curRow)[j] = res;\n if (res < minEntry) {\n minEntry = res;\n }\n // update the horizontal and vertical gaps\n if (res == cost) {\n verticalGaps[j] = 0;\n horizontalGaps[j] = 0;\n } else if (res == left) {\n verticalGaps[j] = 0;\n horizontalGaps[j] = 1;\n } else {\n verticalGaps[j] = 1;\n horizontalGaps[j] = 0;\n }\n }\n // swap the indices\n let temp: u32 = prevIndex;\n prevIndex = curIndex;\n curIndex = temp;\n if (minEntry > maxIntDistance) {\n return 1.0;\n }\n }\n return dynamicPassMat[prevIndex][aLength] / f32(maxLength);\n \n `},[i.MONOMER_CHEMICAL_DISTANCE]:function(e,n){return`\n let aLength: u32 = computeInfo.entrySizes[${n}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${n}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n let sizeDiff: u32 = maxLength - minLength;\n \n let maxIntDistance = ceil(maxDistance * f32(maxLength)) - f32(sizeDiff);\n\n let simMatrix = &(suppInfo.similarityMatrix${n}); // using pointers make things faster\n var diff: f32 = 0.0;\n for (var i = 0u; i < ${e}; i = i + 1u) {\n diff = diff + 1.0 - (*simMatrix)[u32(a[i])][u32(b[i])];\n if (diff > maxIntDistance) {\n return 1.0;\n }\n }\n diff += f32(sizeDiff);\n return diff / ${e};\n `},[i.SOKAL]:function(e,n){return`\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${e}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n let total = onBitsa + onBitsb;\n if (total == 0u) {\n return 1.0;\n }\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${e}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n return 1.0 - f32(commonBits) / f32(total * 2 - commonBits * 3);\n `},[i.COSINE]:function(e,n){return`\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${e}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n let total = onBitsa * onBitsb; // p.s. here total is taken by multiplying\n if (total == 0u) {\n return 1.0;\n }\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${e}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n return 1.0 - f32(commonBits) / sqrt(f32(total));\n `},[i.ASYMMETRIC]:function(e,n){return`\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${e}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n let min = min(onBitsa, onBitsb);\n if (min == 0u) {\n return 1.0;\n }\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${e}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n return 1.0 - f32(commonBits) / f32(min);\n `},[i.Difference]:function(e,n){return`\n let range = suppInfo.range${n};\n return f32(abs(f32(a[0]) - f32(b[0])) / range);\n `},[i.OneHot]:function(e,n){return`\n let aLength: u32 = computeInfo.entrySizes[${n}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${n}][bIndex];\n if (aLength != bLength) {\n return 1.0;\n }\n for (var i = 0u; i < aLength; i = i + 1u) {\n if(a[i] != b[i]) {\n return 1.0;\n }\n }\n return 0.0;\n `}},s={[i.HAMMING]:e=>Math.ceil(e/30),[i.EUCLIDEAN]:e=>Math.ceil(e/30),[i.MANHATTAN]:e=>Math.ceil(e/30),[i.TANIMOTO]:e=>Math.ceil(e/60),[i.SOKAL]:e=>Math.ceil(e/60),[i.COSINE]:e=>Math.ceil(e/60),[i.ASYMMETRIC]:e=>Math.ceil(e/60),[i.LEVENSTEIN]:e=>Math.ceil(e*e/60),[i.NEEDLEMAN_WUNSCH]:e=>Math.ceil(e*e/60),[i.MONOMER_CHEMICAL_DISTANCE]:e=>Math.ceil(e/25),[i.Difference]:e=>1,[i.OneHot]:e=>Math.ceil(e/40)},u={STRING:new Set([i.HAMMING,i.LEVENSTEIN,i.NEEDLEMAN_WUNSCH,i.MONOMER_CHEMICAL_DISTANCE,i.OneHot]),UINT32ARRAY:new Set([i.HAMMING,i.EUCLIDEAN,i.MANHATTAN,i.MONOMER_CHEMICAL_DISTANCE,i.LEVENSTEIN,i.NEEDLEMAN_WUNSCH,i.TANIMOTO,i.COSINE,i.SOKAL,i.ASYMMETRIC,i.OneHot,i.Difference]),INT32ARRAY:new Set([i.EUCLIDEAN,i.MANHATTAN,i.OneHot,i.Difference]),FLOAT32ARRAY:new Set([i.EUCLIDEAN,i.MANHATTAN,i.Difference]),NUMBER:new Set([i.EUCLIDEAN,i.MANHATTAN,i.Difference]),BITARRAY:new Set([i.TANIMOTO,i.COSINE,i.SOKAL,i.ASYMMETRIC])};var l=function(e,n,t,r){return new(t||(t=Promise))((function(a,i){function o(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){var n;e.done?a(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(o,s)}u((r=r.apply(e,n||[])).next())}))};let f=null,c=null;function d(){return l(this,void 0,void 0,(function*(){if(!f&&(f=yield navigator.gpu.requestAdapter({powerPreference:"high-performance"}),null==f))return null;let e=!1;if(c&&(c.lost.then((()=>{e=!0})),yield new Promise((e=>setTimeout(e,10)))),!c||e){const e=1e9,n=f.limits,t=n.maxBufferSize,r=n.maxStorageBufferBindingSize;try{return c=yield f.requestDevice({requiredLimits:{maxBufferSize:Math.min(t,e),maxStorageBufferBindingSize:Math.min(r,e)}}),c}catch(e){return console.error("Failed to create device with required limits",e),c=yield f.requestDevice(),c}}return c}))}function p(e,n=.8,t,a,o,l){return f=this,c=void 0,h=function*(){const f=yield d();if(!f)return null;const c=Object.values(i);if(t.some((e=>!c.includes(e))))throw new Error("Invalid distance metrics provided: "+t.join(", "));if(!Object.values(r).includes(a))throw new Error("Invalid aggregation function provided: "+a);const p=1-n;if(l.length!==e.length||l.length!==t.length||l.length!==o.length)throw new Error("Options, weigths and distance functions must be provided for each column");if(e.some((n=>n.length!==e[0].length)))throw new Error("All entry lists must be the same length");const h=e.length,g=e[0].length,y=e.map(((e,n)=>function(e,n=i.HAMMING,t,r={gapOpenPenalty:1,gapExtensionPenalty:.6}){var a,o;let l=null;const f=e.some((e=>"string"==typeof e))?(l="STRING",e.map((e=>new Uint32Array(e.split("").map((e=>e.charCodeAt(0))))))):e.some((e=>"number"==typeof e))?(l="NUMBER",e.map((e=>new Float32Array([e])))):"object"==typeof e[0]&&e.some((e=>"_data"in e&&"_length"in e))?(l="BITARRAY",e.map((e=>e._data))):e.some((e=>e instanceof Float32Array))?(l="FLOAT32ARRAY",e):e.some((e=>e instanceof Uint32Array))?(l="UINT32ARRAY",e):e.some((e=>e instanceof Int32Array))?(l="INT32ARRAY",e):void 0;if(!f||!l)throw new Error("Invalid entry type, could not determine entry type from input list");const c=f[0]instanceof Int32Array?"INT32ARRAY":f[0]instanceof Float32Array?"FLOAT32ARRAY":"UINT32ARRAY",d=new Uint32Array(f.map((e=>e.length)));if(!u[l]||!u[l].has(n))throw new Error(`Distance metric '${n}' not supported for entry type '${l}'`);const p=d.reduce(((e,n)=>Math.max(e,n)),0),m=s[n](p),h="INT32ARRAY"===c?Int32Array:"FLOAT32ARRAY"===c?Float32Array:Uint32Array,g=new h(f.length*p);f.forEach(((e,n)=>{g.set(e,n*p)}));let y="",A=0,b="FLOAT32ARRAY",w=null;if(n===i.NEEDLEMAN_WUNSCH||n===i.MONOMER_CHEMICAL_DISTANCE){let e=r.scoringMatrix&&r.alphabetIndexes?Object.keys(r.alphabetIndexes).reduce(((e,n)=>Math.max(e,n.charCodeAt(0))),0):-1;if(!r.alphabetIndexes||!r.scoringMatrix){for(let n=0;n<g.length;n++)g[n]>e&&(e=g[n]);r.scoringMatrix=new Array(e+1).fill(null).map((()=>new Array(e+1).fill(0))),r.alphabetIndexes={};for(let e=0;e<r.scoringMatrix.length;e++)r.scoringMatrix[e][e]=1,r.alphabetIndexes[String.fromCharCode(e)]=e}const n=(e+1)*(e+1),i=new Array(e+1).fill(null).map((()=>new Float32Array(e+1)));for(let n=0;n<e+1;n++)i[n][n]=1;const s=r.alphabetIndexes;for(const e of Object.keys(s))for(const n of Object.keys(s))e!==n&&(i[e.charCodeAt(0)][n.charCodeAt(0)]=r.scoringMatrix[s[e]][s[n]]);A=2+n,b="FLOAT32ARRAY",w=new Float32Array(A),w[0]=null!==(a=r.gapOpenPenalty)&&void 0!==a?a:1,w[1]=null!==(o=r.gapExtensionPenalty)&&void 0!==o?o:.6;let u=2;for(let e=0;e<i.length;e++)w.set(i[e],u),u+=i[e].length;y=`\n gapOpenPenalty${t}: f32,\n gapExtensionPenalty${t}: f32,\n similarityMatrix${t}: array<array<f32, ${e+1}>, ${e+1}>`}else if(n===i.Difference){if(!r.range||"number"!=typeof r.range||r.range<=0){const e=g.reduce(((e,n)=>Math.min(e,n)),g[0]),n=g.reduce(((e,n)=>Math.max(e,n)),g[0]);r.range=n-e}r.range<=0&&(r.range=1),A=1,b="FLOAT32ARRAY",w=new Float32Array([r.range]),y=`\n range${t}: f32`}const x=g instanceof Int32Array?"i32":g instanceof Float32Array?"f32":"u32",E=`data${t}: array<array<${x}, ${p}>, ${f.length}>`;return{flatSourceArray:g,sourceArraySize:g.length,maxEntryLen:p,arraySizes:d,complexity:m,suppInfoBuffer:w,suppInfoSize:A,suppInfoType:b,suppInfoStructWgsl:y,entryType:l,dataTypeWGSL:x,dataStructWgsl:E,EncodedArrayConstructor:h}}(e,t[n],n,l[n])));if(0===h)throw new Error("No columns provided. Please provide at least one column of data.");1===h&&(a=r.MANHATTAN);let A=y.map((e=>e.suppInfoStructWgsl)).filter((e=>!!e&&""!=e)).join(",\n"),b=!1;A&&""!=A.trim()||(b=!0,A="\ndummy: f32\n");const w=y.map((e=>e.dataStructWgsl)).filter((e=>!!e&&""!=e)).join(",\n"),x=new Uint32Array(h*g);y.forEach(((e,n)=>{x.set(e.arraySizes,n*g)}));const E=1e4,I=100,M=y.reduce(((e,n)=>e+n.complexity),0),N=Math.ceil(1e4/M),v=Math.ceil(Math.sqrt(Math.ceil(100))),B=10*v,S=g*(g-1)/2,U=Math.ceil(S/E),C=f.createShaderModule({label:"Sparse matrix compute shader",code:`\n // each thread will perform 100 iterations at one time, comparing 100 pairs of entries.\n // in total, each thread will perform at most ${U} comparisons.\n // first is the result struct, containing is, js, and distances. each array with length of 100,\n // and also integer for how many pairs were found to be below threshold.\n struct SparseResult {\n i: array<array<u32, 100>, 10000>,\n j: array<array<u32, 100>, 10000>,\n distances: array<array<f32, 100>, 10000>,\n found: array<u32, 10000>,\n done: array<u32, 10000>\n }\n // struct for the data\n struct ComputeInfo {\n // start at cols and rows, and end at cols and rows for each thread, these will be calculated on cpu and passed to gpu.\n startAtCols: array<u32, 10000>,\n startAtRows: array<u32, 10000>,\n endAtCols: array<u32, 10000>,\n endAtRows: array<u32, 10000>,\n\n // the ACTUALLY sizes of each entry\n entrySizes: array<array<u32, ${g}>, ${h}>,\n // the weights for each entry\n weights: array<f32, ${h}>,\n // the data for each entry\n ${w} // an example of the dataWgsl would be:\n //data0: array<array<u32,20>,100>,\n //data1: array<array<u32,20>,100>\n }\n\n // struct for the supplementary information\n struct SuppInfo {\n // struct containing all the supplementary info, like scoring matrix, alphabet indexes, range, etc.\n ${A}\n };\n\n @group(0) @binding(0) var<storage, read_write> computeInfo: ComputeInfo;\n @group(0) @binding(1) var<storage, read_write> suppInfo: SuppInfo;\n @group(0) @binding(2) var<storage, read_write> results: SparseResult;\n @compute @workgroup_size(10, 10) fn calcSparseMatrix(\n @builtin(global_invocation_id) id: vec3<u32>\n ) {\n ${b?"let otherDummy = suppInfo.dummy * 2;":""} // just to make sure that the suppInfo is not optimized out\n let threadCol = id.x;\n let threadRow = id.y;\n let linearIndex = threadRow * ${B} + threadCol;\n if (linearIndex >= 10000) {\n return; // if we are out of bounds, return\n } \n var startAtCol: u32 = computeInfo.startAtCols[linearIndex];\n var startAtRow: u32 = computeInfo.startAtRows[linearIndex];\n let endAtCol: u32 = min(computeInfo.endAtCols[linearIndex], ${g}u);\n let endAtRow: u32 = min(computeInfo.endAtRows[linearIndex], ${g}u);\n let is = &results.i[linearIndex];\n let js = &results.j[linearIndex];\n let distances = &results.distances[linearIndex];\n results.found[linearIndex] = 0; // initialize the found counter\n var found: u32 = 0;\n if (results.done[linearIndex] > 0) {\n return; // if we are done, return\n }\n for (var i = 0; i < ${N}; i++) {\n if (startAtCol >= endAtCol && startAtRow >= endAtRow) {\n results.done[linearIndex] = 1;\n break;\n }\n if (found >= 100) {\n break;\n }\n let dist = combinedDistance(startAtCol, startAtRow);\n if (dist <= ${p}) {\n (*is)[found] = startAtCol;\n (*js)[found] = startAtRow;\n (*distances)[found] = dist;\n found = found + 1;\n }\n startAtCol = startAtCol + 1;\n if (startAtCol >= ${g}u) {\n startAtRow += 1;\n startAtCol = startAtRow + 1;\n }\n }\n results.found[linearIndex] = found;\n // update the startAtCols and startAtRows\n computeInfo.startAtCols[linearIndex] = startAtCol;\n computeInfo.startAtRows[linearIndex] = startAtRow;\n\n }\n\n // this will generate the distance script for each distance metric and then combine them into one\n ${m(t,y.map((e=>e.maxEntryLen)),p,a)}\n\n\n `}),O=f.createComputePipeline({label:"sparse matrix compute pipeline",layout:"auto",compute:{module:C,entryPoint:"calcSparseMatrix"}}),L=new Uint32Array(E),P=new Uint32Array(E),R=new Uint32Array(E),T=new Uint32Array(E),_=Math.floor(S/E);let j=0,$=1;console.time("GPUthreadStarts");for(let e=0;e<E;e++){const n=9999===e?S-1:(e+1)*_,t=g-2-Math.floor(Math.sqrt(-8*n+4*g*(g-1)-7)/2-.5),r=n-g*t+Math.floor((t+1)*(t+2)/2);L[e]=$,P[e]=j,R[e]=r,T[e]=t,j=t,$=r}console.timeEnd("GPUthreadStarts");const D=4e4+g*h+h+y.reduce(((e,n)=>e+n.sourceArraySize),0),G=y.reduce(((e,n)=>e+n.suppInfoSize),0),z=1e6,k=D*Uint32Array.BYTES_PER_ELEMENT;let Y=k;const F=15&k;0!==F&&(Y+=16-F);const H=f.createBuffer({label:"compute info buffer",size:Y,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),K=H.getMappedRange();let W=0;new Uint32Array(K,W,E).set(L),W+=E*Uint32Array.BYTES_PER_ELEMENT,new Uint32Array(K,W,E).set(P),W+=E*Uint32Array.BYTES_PER_ELEMENT,new Uint32Array(K,W,E).set(R),W+=E*Uint32Array.BYTES_PER_ELEMENT,new Uint32Array(K,W,E).set(T),W+=E*Uint32Array.BYTES_PER_ELEMENT,new Uint32Array(K,W,x.length).set(x),W+=x.length*Uint32Array.BYTES_PER_ELEMENT,new Float32Array(K,W,h).set(o),W+=h*Float32Array.BYTES_PER_ELEMENT;for(const e of y){const n=e.EncodedArrayConstructor,t=e.sourceArraySize;new n(K,W,t).set(e.flatSourceArray),W+=t*n.BYTES_PER_ELEMENT}H.unmap();const q=G*Uint32Array.BYTES_PER_ELEMENT;let X=q;const V=15&q;0!==V&&(X+=16-V),X=Math.max(X,16);const Q=f.createBuffer({label:"supp info buffer",size:X,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),J=Q.getMappedRange();let Z=0;for(const e of y)e.suppInfoBuffer&&e.suppInfoBuffer.byteLength>0&&e.suppInfoSize>0&&(new("UINT32ARRAY"===e.suppInfoType?Uint32Array:Float32Array)(J,Z,e.suppInfoBuffer.length).set(e.suppInfoBuffer),Z+=e.suppInfoBuffer.byteLength);0===Z&&new Uint32Array(J,0,4).set([1,1,1,1]),Q.unmap();const ee=302e4*Uint32Array.BYTES_PER_ELEMENT;let ne=ee;const te=15ⅇ0!==te&&(ne+=16-te);const re=f.createBuffer({label:"results buffer",size:ne,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC}),ae=f.createBindGroup({label:"bindGroup for sparse matrix buffer",layout:O.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:H}},{binding:1,resource:{buffer:Q}},{binding:2,resource:{buffer:re}}]}),ie=f.createBuffer({label:"results out buffer",size:re.size,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),oe=[],se=[],ue=[];let le=!1;for(;!le;){const e=f.createCommandEncoder({label:"distance encoder"}),n=e.beginComputePass({label:"distance compute pass"});n.setPipeline(O),n.setBindGroup(0,ae),n.dispatchWorkgroups(v,v),n.end(),e.copyBufferToBuffer(re,0,ie,0,ie.size);const t=e.finish();f.queue.submit([t]),yield f.queue.onSubmittedWorkDone(),yield ie.mapAsync(GPUMapMode.READ);const r=ie.getMappedRange();let a=0;const i=new Uint32Array(r,a,z);a+=z*Uint32Array.BYTES_PER_ELEMENT;const o=new Uint32Array(r,a,z);a+=z*Uint32Array.BYTES_PER_ELEMENT;const s=new Float32Array(r,a,z);a+=z*Float32Array.BYTES_PER_ELEMENT;const u=new Uint32Array(r,a,E);a+=E*Uint32Array.BYTES_PER_ELEMENT,le=new Uint32Array(r,a,E).every((e=>1===e));const l=u.reduce(((e,n)=>e+n),0),c=new Uint32Array(l),d=new Uint32Array(l),p=new Float32Array(l);let m=0;for(let e=0;e<u.length;e++){const n=u[e];0!==n&&(c.set(i.subarray(e*I,e*I+n),m),d.set(o.subarray(e*I,e*I+n),m),p.set(s.subarray(e*I,e*I+n),m),m+=n)}oe.push(c),se.push(d),ue.push(p),ie.unmap()}const fe=oe.reduce(((e,n)=>e+n.length),0),ce=new Uint32Array(fe),de=new Uint32Array(fe),pe=new Float32Array(fe);let me=0;for(let e=0;e<oe.length;e++)ce.set(oe[e],me),de.set(se[e],me),pe.set(ue[e],me),me+=oe[e].length;return H.destroy(),Q.destroy(),re.destroy(),ie.destroy(),{i:ce,j:de,distance:pe}},new((p=void 0)||(p=Promise))((function(e,n){function t(e){try{a(h.next(e))}catch(e){n(e)}}function r(e){try{a(h.throw(e))}catch(e){n(e)}}function a(n){var a;n.done?e(n.value):(a=n.value,a instanceof p?a:new p((function(e){e(a)}))).then(t,r)}a((h=h.apply(f,c||[])).next())}));var f,c,p,h}function m(e,n,t,r){return e.map(((e,r)=>`\n fn distanceScript${r}(aIndex: u32, bIndex: u32) -> f32 {\n let a = computeInfo.data${r}[aIndex];\n let b = computeInfo.data${r}[bIndex];\n let maxDistance: f32 = ${t};\n ${o[e](n[r],r)}\n }\n `)).join("\n")+"\n"+`\n fn combinedDistance(aIndex: u32, bIndex: u32) -> f32 {\n var distances: array<f32, ${e.length}>;\n ${e.map(((e,n)=>`distances[${n}] = distanceScript${n}(aIndex, bIndex);`)).join("\n")}\n ${a[r](e.length)}\n }\n \n `}var h=t(5731);async function g(e,n,t){const r=e.length,a=[],i=[];for(let o=0;o<r;o++)for(let s=o+1;s<r;s++){const r=e[o],u=e[s];n[r]?.[u]>=t&&(a.push(o),i.push(s))}return function(e,n,t){const r=new Float32Array(t.length).fill(0).map((()=>10*Math.random())),a=new Float32Array(t.length).fill(0).map((()=>10*Math.random())),i=new Float32Array(t.length).fill(0),o=new Float32Array(t.length).fill(0);for(let s=0;s<100;s++){const u=1-s/100;i.fill(0),o.fill(0);for(let t=0;t<e.length;t++){const s=e[t],l=n[t],f=r[s]-r[l],c=a[s]-a[l];Math.abs(f)>=1&&(i[s]-=u*f,i[l]+=u*f),Math.abs(c)>=1&&(o[s]-=u*c,o[l]+=u*c)}for(let e=0;e<t.length;e++){const n=Math.sqrt(i[e]*i[e]+o[e]*o[e]);n>0&&(r[e]+=i[e]/n*u,a[e]+=o[e]/n*u)}}let s=r[0],u=a[0],l=r[0],f=a[0];for(let e=1;e<t.length;e++)s=Math.min(s,r[e]),u=Math.min(u,a[e]),l=Math.max(l,r[e]),f=Math.max(f,a[e]);let c=l-s,d=f-u;0===c&&(c=l);for(let e=0;e<t.length;e++)r[e]=(r[e]-s)/c/2+.5;0===d&&(d=f);for(let e=0;e<t.length;e++)a[e]=(a[e]-u)/d/2+.5;return{embedX:r,embedY:a}}(a,i,e)}function y(e,n,t,r){return a=this,i=void 0,s=function*(){const a=r,i=Math.ceil(a/100),o=Math.ceil(Math.sqrt(i)),s=10*o,u=e.createShaderModule({label:"colwise-normalize",code:`\n @group(0) @binding(0) var<storage, read_write> knnSimilarities : array<f32>;\n @group(0) @binding(1) var<storage, read> offsets : array<u32>;\n @compute @workgroup_size(10, 10) fn normalize(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n let row = id.x;\n let col = id.y;\n let index = row * ${s} + col;\n if (index >= ${r}) {\n return;\n }\n let offsetBegin = offsets[index];\n let offsetEnd = offsets[index + 1];\n var sum = 0.0;\n if (offsetEnd - offsetBegin == 0) {\n return;\n }\n for (var i = offsetBegin; i < offsetEnd; i = i + 1) {\n sum = sum + knnSimilarities[i];\n }\n if (sum > 0.0) {\n for (var i = offsetBegin; i < offsetEnd; i = i + 1) {\n knnSimilarities[i] = knnSimilarities[i] / sum;\n }\n }\n }\n \n `}),l=e.createComputePipeline({label:"hamming compute pipeline",layout:"auto",compute:{module:u,entryPoint:"normalize"}}),f=e.createBuffer({label:"simmilarities info buffer",size:n.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});new Float32Array(f.getMappedRange()).set(n),f.unmap();const c=e.createBuffer({label:"offsets info buffer",size:t.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});new Uint32Array(c.getMappedRange()).set(t),c.unmap();const d=e.createBindGroup({layout:l.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:f}},{binding:1,resource:{buffer:c}}]}),p=e.createCommandEncoder(),m=p.beginComputePass();m.setPipeline(l),m.setBindGroup(0,d),m.dispatchWorkgroups(o,o),m.end();const h=e.createBuffer({label:"out similarity buffer",size:n.byteLength,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});p.copyBufferToBuffer(f,0,h,0,n.byteLength),e.queue.submit([p.finish()]),yield e.queue.onSubmittedWorkDone(),yield h.mapAsync(GPUMapMode.READ);const g=new Float32Array(h.getMappedRange());n.set(g),h.unmap(),f.destroy(),c.destroy(),h.destroy()},new((o=void 0)||(o=Promise))((function(e,n){function t(e){try{u(s.next(e))}catch(e){n(e)}}function r(e){try{u(s.throw(e))}catch(e){n(e)}}function u(n){var a;n.done?e(n.value):(a=n.value,a instanceof o?a:new o((function(e){e(a)}))).then(t,r)}u((s=s.apply(a,i||[])).next())}));var a,i,o,s}function A(e,n=2){for(let t=0;t<e.length;t++)e[t]=Math.pow(e[t],n)}function b(e,n,t,r,a){return i=this,o=void 0,u=function*(){const i=9e4,o=Math.ceil(900),s=Math.ceil(Math.sqrt(o)),u=10*s,l=Math.floor(Math.max(Math.log10(a),2))+1,f=Math.pow(10,-l),c=new Float32Array(n.length),d=e.createShaderModule({label:"expand",code:`\n struct SparseKNN {\n knnSimilarities: array<f32, ${n.length}>,\n knnIndexes: array<u32, ${t.length}>,\n offsets: array<u32, ${r.length}>,\n rowIndexes: array<u32, ${t.length}>,\n }\n\n @group(0) @binding(0) var<storage, read_write> sparseKNN: SparseKNN;\n @group(0) @binding(1) var<storage, read_write> resultSimBlock: array<f32, 90000>;\n @group(0) @binding(2) var<storage, read_write> startAt: u32;\n @compute @workgroup_size(10, 10) fn expand(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n let col = id.x;\n let row = id.y;\n let index = row * ${u} + col;\n if (index >= 90000) {\n return;\n }\n let workingIndex = index + startAt;\n if (workingIndex >= ${t.length}) {\n return;\n }\n \n let rowIdx = sparseKNN.rowIndexes[workingIndex];\n let colIdx = sparseKNN.knnIndexes[workingIndex];\n let offsetBeginRow = sparseKNN.offsets[rowIdx];\n let offsetEndRow = sparseKNN.offsets[rowIdx + 1];\n let offsetBeginCol = sparseKNN.offsets[colIdx];\n let offsetEndCol = sparseKNN.offsets[colIdx + 1];\n var sum = 0.0;\n for (var i = offsetBeginRow; i < offsetEndRow; i = i + 1) {\n for(var j = offsetBeginCol; j < offsetEndCol; j = j + 1) {\n if (sparseKNN.knnIndexes[i] == sparseKNN.knnIndexes[j]) {\n sum = sum + sparseKNN.knnSimilarities[i] * sparseKNN.knnSimilarities[j];\n break;\n }\n }\n }\n if (sum > ${f}) {\n resultSimBlock[index] = sum;\n } else {\n resultSimBlock[index] = 0.0;\n }\n }\n `}),p=e.createComputePipeline({label:"expand compute pipeline",layout:"auto",compute:{module:d,entryPoint:"expand"}});let m=4*(n.length+t.length+r.length+t.length);const h=15&m;0!==h&&(m+=16-h);const g=e.createBuffer({label:"sparse knn buffer",size:m,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),y=g.getMappedRange();new Float32Array(y,0,n.length).set(n),new Uint32Array(y,4*n.length,t.length).set(t),new Uint32Array(y,4*(n.length+t.length),r.length).set(r);const A=function(e){const n=new Uint32Array(e[e.length-1]);for(let t=0;t<e.length-1;t++)for(let r=e[t];r<e[t+1];r++)n[r]=t;return n}(r);new Uint32Array(y,4*(n.length+t.length+r.length),A.length).set(A),g.unmap();const b=e.createBuffer({label:"start end buffer",size:4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});new Uint32Array(b.getMappedRange()).set([0]),b.unmap();const w=e.createBuffer({label:"result block buffer",size:36e4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST}),x=e.createBindGroup({layout:p.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:g}},{binding:1,resource:{buffer:w}},{binding:2,resource:{buffer:b}}]}),E=e.createBuffer({label:"out block buffer",size:w.size,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});for(let n=0;n<Math.ceil(t.length/i);n++){const r=n*i,a=Math.min(i,t.length-r);e.queue.writeBuffer(b,0,new Uint32Array([r]));const o=e.createCommandEncoder({label:"expand encoder"}),u=o.beginComputePass({label:"expand compute pass"});u.setPipeline(p),u.setBindGroup(0,x),u.dispatchWorkgroups(s,s),u.end(),o.copyBufferToBuffer(w,0,E,0,E.size),e.queue.submit([o.finish()]),yield e.queue.onSubmittedWorkDone(),yield E.mapAsync(GPUMapMode.READ);const l=new Float32Array(E.getMappedRange(),0,a);c.set(l,r),E.unmap()}return g.destroy(),b.destroy(),w.destroy(),E.destroy(),{KNNIndexes:t,KNNSimilarities:c,indexOffsets:r}},new((s=void 0)||(s=Promise))((function(e,n){function t(e){try{a(u.next(e))}catch(e){n(e)}}function r(e){try{a(u.throw(e))}catch(e){n(e)}}function a(n){var a;n.done?e(n.value):(a=n.value,a instanceof s?a:new s((function(e){e(a)}))).then(t,r)}a((u=u.apply(i,o||[])).next())}));var i,o,s,u}function w(e,n){const t=function(e,n){const t=new Uint32Array(n);for(let n=0;n<e.i.length;n++)t[e.i[n]]++,t[e.j[n]]++;for(let e=0;e<n;e++)t[e]++;return t}(e,n),r=function(e){const n=new Uint32Array(e.length+1);let t=0;for(let r=0;r<e.length;r++)n[r]=t,t+=e[r];return n[e.length]=t,n}(t),a=new Uint32Array(n).fill(1),i=new Uint32Array(2*e.i.length+n),o=new Float32Array(2*e.i.length+n);for(let e=0;e<n;e++)i[r[e]]=e,o[r[e]]=1;for(let n=0;n<e.i.length;n++){const t=e.i[n],s=e.j[n],u=1-e.distance[n];i[r[t]+a[t]]=s,o[r[t]+a[t]]=u,a[t]++,i[r[s]+a[s]]=t,o[r[s]+a[s]]=u,a[s]++}return{KNNIndexes:i,KNNSimilarities:o,indexOffsets:r}}Object.prototype.toString;const x={expandFactor:2,maxIterations:5,inflateFactor:2,multFactor:1};class E{constructor(e={}){this._options={...x,...e}}async transform(e,n){let t=this.toObjectForm(e);if(this._options.maxIterations>0){this.addLoops(t,n),this.normalize(t);for(let e=0;e<this._options.maxIterations;e++)t=this.expand(t,n),this.inflate(t),this.normalize(t)}const{clusters:r,is:a,js:i}=this.assignClusters(t,n);this.correctClusters(r);const o=await this.layout(r,t,n);return{clusters:r,embedX:o.embedX,embedY:o.embedY,is:a,js:i}}async transformWebGPU(e,n){if(0===this._options.maxIterations)return this.transform(e,n);const t=await function(e,n,t=5,r=2){return a=this,i=void 0,s=function*(){const a=yield d();if(!a)throw new Error("no gpu device found");const i=w(e,n);yield y(a,i.KNNSimilarities,i.indexOffsets,n);let o=i;for(let e=0;e<t;e++){const e=yield b(a,o.KNNSimilarities,o.KNNIndexes,o.indexOffsets,n);A(e.KNNSimilarities,r),yield y(a,e.KNNSimilarities,e.indexOffsets,n),o=e}return o},new((o=void 0)||(o=Promise))((function(e,n){function t(e){try{u(s.next(e))}catch(e){n(e)}}function r(e){try{u(s.throw(e))}catch(e){n(e)}}function u(n){var a;n.done?e(n.value):(a=n.value,a instanceof o?a:new o((function(e){e(a)}))).then(t,r)}u((s=s.apply(a,i||[])).next())}));var a,i,o,s}(e,n,this._options.maxIterations,this._options.inflateFactor),r=this.csrToSparseObject(t,n),{clusters:a,is:i,js:o}=this.assignClusters(r,n);this.correctClusters(a);const s=await this.layout(a,r,n);return{clusters:a,embedX:s.embedX,embedY:s.embedY,is:i,js:o}}correctClusters(e){const n={};for(const t of e)n[t]||(n[t]=0),n[t]++;const t=Object.keys(n).map(Number).sort(((e,t)=>n[t]-n[e])),r={};t.forEach(((e,n)=>r[e]=n+1));for(let n=0;n<e.length;n++)e[n]=r[e[n]]}csrToSparseObject(e,n){const t=Math.floor(Math.max(Math.log10(n),2))+1,r=1/Math.pow(10,t),a={};for(let t=0;t<n;t++){a[t]={};for(let n=e.indexOffsets[t];n<e.indexOffsets[t+1];n++){const i=e.KNNIndexes[n];i<=t||e.KNNSimilarities[n]<r||(a[t][i]=e.KNNSimilarities[n])}}return a}async layout(e,n,t){const r=new Float32Array(t).fill(0),a=new Float32Array(t).fill(0),i={};e.forEach(((e,n)=>{i[e]||(i[e]=[]),i[e].push(n)}));let o=0;const s=Object.keys(i);s.sort(((e,n)=>i[n].length-i[e].length));let u=6,l=0;for(const e of s){const t=i[e],s=await g(t,n,.001);o===Math.ceil(u/1.5)&&(o=0,l+=5/u,u=Math.ceil(1.5*u));const f=o%u*5/u*1.5;for(let e=0;e<s.embedX.length;e++)r[t[e]]=5*s.embedX[e]/u+f,a[t[e]]=5*s.embedY[e]/u+l;o++}return{embedX:r,embedY:a}}mergeClusters(e,n,t){const r=e[n],a=e[t];for(let n=0;n<e.length;n++)e[n]===a&&(e[n]=r)}assignClusters(e,n){let t=0;const r=[],a=[],i=Math.floor(Math.max(Math.log10(n),2))+1,o=Math.pow(10,i),s=new Array(n).fill(-1);for(const n of Object.keys(e))for(const i of Object.keys(e[n]))Math.round(e[n][i]*o)/o>0&&e[n][i]!==Number(n)&&Number(i)>Number(n)&&(r.push(Number(n)),a.push(Number(i)),-1!==s[Number(n)]&&-1!==s[Number(i)]?s[Number(n)]!==s[Number(i)]&&this.mergeClusters(s,Number(n),Number(i)):-1!==s[Number(n)]?s[Number(i)]=s[Number(n)]:-1!==s[Number(i)]?s[Number(n)]=s[Number(i)]:(t++,s[Number(n)]=t,s[Number(i)]=t));for(let e=0;e<s.length;e++)-1===s[e]&&(t++,s[e]=t);return{clusters:s,is:new Uint32Array(r),js:new Uint32Array(a)}}assignClustersCSR(e,n){let t=0;const r=[],a=[],i=Math.floor(Math.max(Math.log10(n),2))+1,o=1/Math.pow(10,i),s=new Array(n).fill(-1),u=new Uint32Array(n+1);let l=0;u[0]=0;for(let i=0;i<n;i++){for(let n=e.indexOffsets[i];n<e.indexOffsets[i+1];n++){const u=e.KNNIndexes[n];u<=i||e.KNNSimilarities[n]<=o||(r.push(i),a.push(u),l++,-1!==s[i]&&-1!==s[u]?s[i]!==s[u]&&this.mergeClusters(s,i,u):-1!==s[i]?s[u]=s[i]:-1!==s[u]?s[i]=s[u]:(t++,s[i]=t,s[u]=t))}u[i+1]=l}for(let e=0;e<s.length;e++)-1===s[e]&&(t++,s[e]=t);return{clusters:s,is:new Uint32Array(r),js:new Uint32Array(a),correctedOffsets:u}}toObjectForm(e){const n={};for(let t=0;t<e.i.length;t++)n[e.i[t]]||(n[e.i[t]]={}),n[e.i[t]][e.j[t]]=1-e.distance[t],n[e.j[t]]||(n[e.j[t]]={}),n[e.j[t]][e.i[t]]=1-e.distance[t];return n}addLoops(e,n){for(let t=0;t<n;t++)e[t]||(e[t]={}),e[t][t]=this._options.multFactor}normalize(e){for(const n of Object.keys(e)){const t=e[n];let r=0;for(const e of Object.keys(t))r+=t[e];if(0!==r)for(const a of Object.keys(t))e[n][a]/=r}}expand(e,n){const t={},r=Math.floor(Math.max(Math.log10(n),2))+1,a=Math.pow(10,r);for(let r=0;r<n;r++)if(e[r]){t[r]??(t[r]={});for(let i=r;i<n;i++){if(!e[r]?.[i])continue;const n=this.getExpandValue(e,r,i);Math.round(n*a)/a>0&&(t[r][i]=n,t[i]||(t[i]={}),t[i][r]=n)}}return t}inflate(e){for(const n of Object.keys(e)){const t=e[n];for(const r of Object.keys(t))e[n][r]=Math.pow(e[n][r],this._options.inflateFactor)}}getExpandValue(e,n,t){let r=0;const a=Object.keys(e[n]??{}),i=Object.keys(e[t]??{});for(const o of a)i.includes(o)&&(r+=e[n][o]*e[t][o]);return r}}onmessage=async e=>{const{data:n,threshold:t,weights:r,aggregationMethod:a,distanceFnArgs:i,distanceFns:o,maxIterations:s,useWebGPU:u,inflate:l}=e.data;console.time("sparse matrix");let f=null;if(u)try{f=await p(n,t/100,o,a,r,i)}catch(e){console.error(e)}f||(u&&console.error("WEBGPU sparse matrix calculation failed, falling back to CPU implementation"),f=await(new h.p).calcMultiColumn(n,o,t/100,i,r,a)),console.timeEnd("sparse matrix");const c=new E({maxIterations:s??5,inflateFactor:l??2});console.time("MCL");let d=null;if(u)try{d=await c.transformWebGPU(f,n[0].length)}catch(e){console.error("webGPU MCL failed, falling back to CPU implementation"),console.error(e)}d||(d=await c.transform(f,n[0].length)),console.timeEnd("MCL"),postMessage({res:d})}},606:(e,n,t)=>{t.d(n,{Qt:()=>a,gD:()=>r}),t(6066);const r=e=>null==e;function a(e,n,t,r){if(t>e[e.length-1])return;const a=e.findIndex((e=>t<e));e.pop(),e.splice(a,0,t),n.pop(),n.splice(a,0,r)}}},r={};function a(e){var n=r[e];if(void 0!==n)return n.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,a),i.exports}a.m=t,a.x=()=>{var e=a.O(void 0,[731],(()=>a(9260)));return a.O(e)},e=[],a.O=(n,t,r,i)=>{if(!t){var o=1/0;for(f=0;f<e.length;f++){for(var[t,r,i]=e[f],s=!0,u=0;u<t.length;u++)(!1&i||o>=i)&&Object.keys(a.O).every((e=>a.O[e](t[u])))?t.splice(u--,1):(s=!1,i<o&&(o=i));if(s){e.splice(f--,1);var l=r();void 0!==l&&(n=l)}}return n}i=i||0;for(var f=e.length;f>0&&e[f-1][2]>i;f--)e[f]=e[f-1];e[f]=[t,r,i]},a.d=(e,n)=>{for(var t in n)a.o(n,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce(((n,t)=>(a.f[t](e,n),n)),[])),a.u=e=>e+".js",a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e;a.g.importScripts&&(e=a.g.location+"");var n=a.g.document;if(!e&&n&&(n.currentScript&&(e=n.currentScript.src),!e)){var t=n.getElementsByTagName("script");if(t.length)for(var r=t.length-1;r>-1&&(!e||!/^http(s?):/.test(e));)e=t[r--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),a.p=e})(),(()=>{a.b=self.location+"";var e={317:1};a.f.i=(n,t)=>{e[n]||importScripts(a.p+a.u(n))};var n=self.webpackChunkbio=self.webpackChunkbio||[],t=n.push.bind(n);n.push=n=>{var[r,i,o]=n;for(var s in i)a.o(i,s)&&(a.m[s]=i[s]);for(o&&o(a);r.length;)e[r.pop()]=1;t(n)}})(),n=a.x,a.x=()=>a.e(731).then(n);var i=a.x();bio=i})();
|
|
2
|
+
//# sourceMappingURL=317.js.map
|
package/dist/317.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"317.js","mappings":"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","sources":["webpack://bio/webpack/runtime/chunk loaded","webpack://bio/webpack/runtime/startup chunk dependencies","webpack://bio/./node_modules/@datagrok-libraries/math/src/webGPU/multi-col-distances/webGPU-aggregation.js","webpack://bio/./node_modules/@datagrok-libraries/math/src/webGPU/multi-col-distances/webGPU-multicol-distances.js","webpack://bio/./node_modules/@datagrok-libraries/math/src/webGPU/getGPUDevice.js","webpack://bio/./node_modules/@datagrok-libraries/math/src/webGPU/sparse-matrix/webGPU-sparse-matrix.js","webpack://bio/./node_modules/@datagrok-libraries/math/src/webGPU/preprocessing/webGPU-process-info.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/MCL/bio-layout.js","webpack://bio/./node_modules/@datagrok-libraries/math/src/webGPU/MCL/colwise-normalize.js","webpack://bio/./node_modules/@datagrok-libraries/math/src/webGPU/MCL/inflate-expand.js","webpack://bio/./node_modules/@datagrok-libraries/math/src/webGPU/MCL/utils.js","webpack://bio/./node_modules/@datagrok-libraries/math/src/webGPU/umap/utils.js","webpack://bio/./node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/MCL/marcov-cluster.js","webpack://bio/./node_modules/@datagrok-libraries/math/src/webGPU/MCL/MCL-webGPU.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/MCL/mcl-worker.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/utils.js","webpack://bio/webpack/bootstrap","webpack://bio/webpack/runtime/define property getters","webpack://bio/webpack/runtime/ensure chunk","webpack://bio/webpack/runtime/get javascript chunk filename","webpack://bio/webpack/runtime/global","webpack://bio/webpack/runtime/hasOwnProperty shorthand","webpack://bio/webpack/runtime/publicPath","webpack://bio/webpack/runtime/importScripts chunk loading","webpack://bio/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","var next = __webpack_require__.x;\n__webpack_require__.x = () => {\n\treturn __webpack_require__.e(731).then(next);\n};","function euclideanAggregationWgsl(arraySize) {\n return `\n var sum = 0.0;\n for (var i = 0u; i < ${arraySize}; i = i + 1u) {\n sum = sum + distances[i] * distances[i] * computeInfo.weights[i] * computeInfo.weights[i];\n }\n return sqrt(sum);\n `;\n}\n;\nfunction manhattanAggregationWgsl(arraySize) {\n return `\n var sum = 0.0;\n for (var i = 0u; i < ${arraySize}; i = i + 1u) {\n sum = sum + abs(distances[i]) * computeInfo.weights[i];\n }\n return sum;\n `;\n}\nexport var WEBGSLAGGREGATION;\n(function (WEBGSLAGGREGATION) {\n WEBGSLAGGREGATION[\"EUCLIDEAN\"] = \"EUCLIDEAN\";\n WEBGSLAGGREGATION[\"MANHATTAN\"] = \"MANHATTAN\";\n})(WEBGSLAGGREGATION || (WEBGSLAGGREGATION = {}));\nexport const WEBGSLAGGREGATIONFUNCTIONS = {\n [WEBGSLAGGREGATION.EUCLIDEAN]: euclideanAggregationWgsl,\n [WEBGSLAGGREGATION.MANHATTAN]: manhattanAggregationWgsl\n};\n//# sourceMappingURL=webGPU-aggregation.js.map","/* eslint-disable max-len */\n// in all the functions below, the variables a and b are assumed to be arrays of uint32/f32\n//values which are infered from the code this chunk is injected into\n// also, we have access to computeInfo struct, which contains the following fields:\n// computeInfo.entrySizes: array of arrays of u32 containing the sizes of the entries\n// other fields are specific to the distance function should be injected from the main script that calls this function,\n// and should be available in the supplementaryInfo struct\n// like the similarity matrix for monomer chemical distance.\n// the getProcessInfo function should return correct buffer allocation mechanism for the supplementaryInfo,\n// for every entry list\n// the maxDistance variable is also assumed to be available in the\n// scope of the function, in case of knn it is the distance in the last postion of knn on this index,\n// in case of sparse matrix, it can be just the threshold for the distance.\n// hamming distance for sequnences of uint32 arrays of max length ${maxArraySize}\nexport function webGPUHamming(_maxArraySize, entryIndex) {\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n let sizeDiff: u32 = maxLength - minLength;\n \n let maxIntDistance = ceil(maxDistance * f32(maxLength)) - f32(sizeDiff);\n\n var diff: f32 = 0.0;\n for (var i = 0u; i < ${_maxArraySize}; i = i + 1u) {\n diff = diff + f32(a[i] != b[i]);\n if (diff > maxIntDistance) {\n return 1.0;\n }\n }\n diff += f32(sizeDiff);\n return diff / ${_maxArraySize};\n `;\n}\nexport function webGPUMonomerChemicalDistance(_maxArraySize, entryIndex) {\n // it is assumet that suppInfo struct contains correct matrix called similarityMatrix${entryIndex}, (similarityMatrix0, similarityMatrix1, etc)\n // this should be guaranteed by the getProcessInfo function.\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n let sizeDiff: u32 = maxLength - minLength;\n \n let maxIntDistance = ceil(maxDistance * f32(maxLength)) - f32(sizeDiff);\n\n let simMatrix = &(suppInfo.similarityMatrix${entryIndex}); // using pointers make things faster\n var diff: f32 = 0.0;\n for (var i = 0u; i < ${_maxArraySize}; i = i + 1u) {\n diff = diff + 1.0 - (*simMatrix)[u32(a[i])][u32(b[i])];\n if (diff > maxIntDistance) {\n return 1.0;\n }\n }\n diff += f32(sizeDiff);\n return diff / ${_maxArraySize};\n `;\n}\nexport function webGPULevenstein(maxArraySize, entryIndex) {\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n\n let maxIntDistance = ceil(maxDistance * f32(maxLength));\n\n // we will store two arrays as matrix and swap the working indices per pass.\n // this way we can reduce memory usage per computation to just O(aLength)\n // the grid will have aLength + 1 columns and bLength + 1 rows\n // this will be guaranteed by iteration, but the array sizes must be known at compile time, so we will use a fixed size of maxArraySize\n var dynamicPassMat: array<array<f32, ${maxArraySize + 1}u>, 2>; // initialize to 0\n \n var prevIndex: u32 = 0;\n var curIndex: u32 = 1; // we will swap these indices per pass\n\n // initialize the first row\n for (var i = 0u; i <= aLength; i = i + 1u) {\n dynamicPassMat[prevIndex][i] = f32(i);\n }\n\n // iterate over the rows\n for (var i = 1u; i <= bLength; i = i + 1u) {\n dynamicPassMat[curIndex][0] = f32(i);\n var minEntry: f32 = f32(maxLength);\n let prevRow = &dynamicPassMat[prevIndex];\n let curRow = &dynamicPassMat[curIndex];\n let bMon = u32(b[i - 1]);\n for (var j = 1u; j <= aLength; j = j + 1u) {\n var cost: f32 = f32(a[j - 1] != bMon);\n var res: f32 = min(\n min(\n (*prevRow)[j] + 1.0, // deletion\n (*curRow)[j - 1] + 1.0, // insertion\n ),\n (*prevRow)[j - 1] + cost // substitution\n );\n (*curRow)[j] = res;\n if (res < minEntry) {\n minEntry = res;\n }\n }\n // swap the indices\n let temp: u32 = prevIndex;\n prevIndex = curIndex;\n curIndex = temp;\n if (minEntry > maxIntDistance) {\n return 1.0;\n }\n }\n\n return dynamicPassMat[prevIndex][aLength] / f32(maxLength);\n `;\n}\nexport function webGPUNeedlemanWunsch(maxArraySize, entryIndex) {\n // version of the levenshtain where the cost of substitution is customizable\n // it is assumet that suppInfo struct contains correct matrix called similarityMatrix${entryIndex}, (similarityMatrix0, similarityMatrix1, etc)\n // and gapOpenPenalty, gapExtensionPenalty\n // this should be guaranteed by the getProcessInfo function.\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n let maxLength: u32 = max(aLength, bLength);\n let minLength: u32 = min(aLength, bLength);\n \n let maxIntDistance = ceil(maxDistance * f32(maxLength));\n // we will store two arrays as matrix and swap the working indices per pass.\n // this way we can reduce memory usage per computation to just O(aLength)\n // the grid will have aLength + 1 columns and bLength + 1 rows\n // this will be guaranteed by iteration, but the array sizes must be known at compile time, so we will use a fixed size of maxArraySize\n var dynamicPassMat: array<array<f32, ${maxArraySize + 1}u>, 2>; // initialize to 0\n \n // we need to keep track of which operation led to the current cell\n // i.e. whether we came from the left, top or diagonal to assign gap open/gap extend penalty\n var verticalGaps: array<u32, ${maxArraySize + 1}u>;\n var horizontalGaps: array<u32, ${maxArraySize + 1}u>;\n\n let gapOpenPenalty: f32 = suppInfo.gapOpenPenalty${entryIndex};\n let gapExtensionPenalty: f32 = suppInfo.gapExtensionPenalty${entryIndex};\n var prevIndex: u32 = 0;\n var curIndex: u32 = 1; // we will swap these indices per pass\n // initialize the first row\n for (var i = 0u; i <= aLength; i = i + 1u) {\n dynamicPassMat[prevIndex][i] = gapOpenPenalty + f32(i - 1) * gapExtensionPenalty;\n dynamicPassMat[curIndex][i] = 0.0;\n }\n dynamicPassMat[0][0] = 0.0;\n\n let simMatrix = &suppInfo.similarityMatrix${entryIndex}; // using pointers make things faster\n // iterate over the rows\n for (var i = 1u; i <= bLength; i = i + 1u) {\n let prevRow = &dynamicPassMat[prevIndex];\n let curRow = &dynamicPassMat[curIndex];\n (*curRow)[0] = gapOpenPenalty + f32(i - 1) * gapExtensionPenalty;\n var minEntry: f32 = f32(maxLength);\n let monB = u32(b[i - 1]);\n for (var j = 1u; j <= aLength; j = j + 1u) {\n let monA = u32(a[j - 1]);\n \n let cost: f32 = (*prevRow)[j - 1] + 1f - (*simMatrix)[monA][monB];\n var top = (*prevRow)[j]; // deletion\n if (verticalGaps[j] > 0) {\n top = top + gapExtensionPenalty;\n } else {\n top = top + gapOpenPenalty;\n }\n var left = (*curRow)[j - 1]; // insertion\n if (horizontalGaps[j - 1] > 0) {\n left = left + gapExtensionPenalty;\n } else {\n left = left + gapOpenPenalty;\n }\n var res: f32 = min(\n min(\n top, // deletion\n left, // insertion\n ),\n cost // substitution\n );\n (*curRow)[j] = res;\n if (res < minEntry) {\n minEntry = res;\n }\n // update the horizontal and vertical gaps\n if (res == cost) {\n verticalGaps[j] = 0;\n horizontalGaps[j] = 0;\n } else if (res == left) {\n verticalGaps[j] = 0;\n horizontalGaps[j] = 1;\n } else {\n verticalGaps[j] = 1;\n horizontalGaps[j] = 0;\n }\n }\n // swap the indices\n let temp: u32 = prevIndex;\n prevIndex = curIndex;\n curIndex = temp;\n if (minEntry > maxIntDistance) {\n return 1.0;\n }\n }\n return dynamicPassMat[prevIndex][aLength] / f32(maxLength);\n \n `;\n}\nexport function webGPUEuclidean(maxArraySize, _entryIndex) {\n return `\n var dist: f32 = 0.0;\n for (var i = 0u; i < ${maxArraySize}; i = i + 1u) {\n dist = dist + f32(a[i] - b[i]) * f32(a[i] - b[i]);\n }\n return sqrt(dist);\n `;\n}\nexport function webGPUManhattan(maxArraySize, _entryIndex) {\n return `\n var dist: f32 = 0.0;\n for (var i = 0u; i < ${maxArraySize}; i = i + 1u) {\n dist = dist + abs(f32(a[i] - b[i]));\n }\n return dist;\n `;\n}\nexport function webGPUOneHotDistance(_maxArraySize, entryIndex) {\n return `\n let aLength: u32 = computeInfo.entrySizes[${entryIndex}][aIndex];\n let bLength: u32 = computeInfo.entrySizes[${entryIndex}][bIndex];\n if (aLength != bLength) {\n return 1.0;\n }\n for (var i = 0u; i < aLength; i = i + 1u) {\n if(a[i] != b[i]) {\n return 1.0;\n }\n }\n return 0.0;\n `;\n}\nexport function webGPUNumericDistance(_maxArraySize, entryIndex) {\n // we assume that range${entryIndex} is available in the supplementaryInfo struct\n return `\n let range = suppInfo.range${entryIndex};\n return f32(abs(f32(a[0]) - f32(b[0])) / range);\n `;\n}\n// tanimoto distance for uint32 arrays of length ${maxArraySize}\nexport function webGPUTanimotoBitArray(maxArraySize, _entryIndex) {\n return `\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n\n if (onBitsa == 0u && onBitsb == 0u) {\n return 0.0;\n }\n\n let totalOnBits = onBitsa + onBitsb;\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n\n return 1.0 - f32(commonBits) / f32(totalOnBits - commonBits);\n `;\n}\nexport function webGPUAsymmetricBitArray(maxArraySize, _entryIndex) {\n return `\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n let min = min(onBitsa, onBitsb);\n if (min == 0u) {\n return 1.0;\n }\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n return 1.0 - f32(commonBits) / f32(min);\n `;\n}\nexport function webGPUCosineBitArray(maxArraySize, _entryIndex) {\n return `\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n let total = onBitsa * onBitsb; // p.s. here total is taken by multiplying\n if (total == 0u) {\n return 1.0;\n }\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n return 1.0 - f32(commonBits) / sqrt(f32(total));\n `;\n}\nexport function webGPUSokalBitArray(maxArraySize, _entryIndex) {\n return `\n var onBitsa: u32 = 0u;\n var onBitsb: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n onBitsa = onBitsa + countOneBits(a[i]);\n onBitsb = onBitsb + countOneBits(b[i]);\n }\n let total = onBitsa + onBitsb;\n if (total == 0u) {\n return 1.0;\n }\n var commonBits: u32 = 0u;\n for (var i = 0u; i < ${maxArraySize}u; i = i + 1u) {\n commonBits = commonBits + countOneBits(a[i] & b[i]);\n }\n return 1.0 - f32(commonBits) / f32(total * 2 - commonBits * 3);\n `;\n}\nexport var WEBGPUDISTANCE;\n(function (WEBGPUDISTANCE) {\n WEBGPUDISTANCE[\"HAMMING\"] = \"Hamming\";\n WEBGPUDISTANCE[\"EUCLIDEAN\"] = \"Euclidean\";\n WEBGPUDISTANCE[\"MANHATTAN\"] = \"Manhattan\";\n WEBGPUDISTANCE[\"TANIMOTO\"] = \"Tanimoto\";\n WEBGPUDISTANCE[\"LEVENSTEIN\"] = \"Levenshtein\";\n WEBGPUDISTANCE[\"NEEDLEMAN_WUNSCH\"] = \"Needlemann-Wunsch\";\n WEBGPUDISTANCE[\"MONOMER_CHEMICAL_DISTANCE\"] = \"Monomer chemical distance\";\n WEBGPUDISTANCE[\"SOKAL\"] = \"Sokal\";\n WEBGPUDISTANCE[\"COSINE\"] = \"Cosine\";\n WEBGPUDISTANCE[\"ASYMMETRIC\"] = \"Asymmetric\";\n WEBGPUDISTANCE[\"Difference\"] = \"Difference\";\n WEBGPUDISTANCE[\"OneHot\"] = \"One-Hot\";\n})(WEBGPUDISTANCE || (WEBGPUDISTANCE = {}));\nexport const webGPUFunctions = {\n [WEBGPUDISTANCE.HAMMING]: webGPUHamming,\n [WEBGPUDISTANCE.EUCLIDEAN]: webGPUEuclidean,\n [WEBGPUDISTANCE.MANHATTAN]: webGPUManhattan,\n [WEBGPUDISTANCE.TANIMOTO]: webGPUTanimotoBitArray,\n [WEBGPUDISTANCE.LEVENSTEIN]: webGPULevenstein,\n [WEBGPUDISTANCE.NEEDLEMAN_WUNSCH]: webGPUNeedlemanWunsch,\n [WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE]: webGPUMonomerChemicalDistance,\n [WEBGPUDISTANCE.SOKAL]: webGPUSokalBitArray,\n [WEBGPUDISTANCE.COSINE]: webGPUCosineBitArray,\n [WEBGPUDISTANCE.ASYMMETRIC]: webGPUAsymmetricBitArray,\n [WEBGPUDISTANCE.Difference]: webGPUNumericDistance,\n [WEBGPUDISTANCE.OneHot]: webGPUOneHotDistance\n};\nexport const distanceFunctionComplexity = {\n [WEBGPUDISTANCE.HAMMING]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.EUCLIDEAN]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.MANHATTAN]: (maxEntrySize) => Math.ceil(maxEntrySize / 30),\n [WEBGPUDISTANCE.TANIMOTO]: (maxEntrySize) => Math.ceil(maxEntrySize / 60),\n [WEBGPUDISTANCE.SOKAL]: (maxEntrySize) => Math.ceil(maxEntrySize / 60),\n [WEBGPUDISTANCE.COSINE]: (maxEntrySize) => Math.ceil(maxEntrySize / 60),\n [WEBGPUDISTANCE.ASYMMETRIC]: (maxEntrySize) => Math.ceil(maxEntrySize / 60),\n [WEBGPUDISTANCE.LEVENSTEIN]: (maxEntrySize) => Math.ceil(maxEntrySize * maxEntrySize / 60),\n [WEBGPUDISTANCE.NEEDLEMAN_WUNSCH]: (maxEntrySize) => Math.ceil(maxEntrySize * maxEntrySize / 60),\n [WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE]: (maxEntrySize) => Math.ceil(maxEntrySize / 25),\n [WEBGPUDISTANCE.Difference]: (_maxEntrySize) => 1,\n [WEBGPUDISTANCE.OneHot]: (_maxEntrySize) => Math.ceil(_maxEntrySize / 40),\n};\nexport const TypeSupportedDistances = {\n [\"STRING\" /* WGPUENTRYTYPE.STRING */]: new Set([WEBGPUDISTANCE.HAMMING, WEBGPUDISTANCE.LEVENSTEIN, WEBGPUDISTANCE.NEEDLEMAN_WUNSCH, WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE, WEBGPUDISTANCE.OneHot]),\n [\"UINT32ARRAY\" /* WGPUENTRYTYPE.UINT32ARRAY */]: new Set([WEBGPUDISTANCE.HAMMING, WEBGPUDISTANCE.EUCLIDEAN, WEBGPUDISTANCE.MANHATTAN, WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE, WEBGPUDISTANCE.LEVENSTEIN, WEBGPUDISTANCE.NEEDLEMAN_WUNSCH, WEBGPUDISTANCE.TANIMOTO, WEBGPUDISTANCE.COSINE, WEBGPUDISTANCE.SOKAL, WEBGPUDISTANCE.ASYMMETRIC, WEBGPUDISTANCE.OneHot, WEBGPUDISTANCE.Difference]),\n [\"INT32ARRAY\" /* WGPUENTRYTYPE.INT32ARRAY */]: new Set([WEBGPUDISTANCE.EUCLIDEAN, WEBGPUDISTANCE.MANHATTAN, WEBGPUDISTANCE.OneHot, WEBGPUDISTANCE.Difference]),\n [\"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */]: new Set([WEBGPUDISTANCE.EUCLIDEAN, WEBGPUDISTANCE.MANHATTAN, WEBGPUDISTANCE.Difference]),\n [\"NUMBER\" /* WGPUENTRYTYPE.NUMBER */]: new Set([WEBGPUDISTANCE.EUCLIDEAN, WEBGPUDISTANCE.MANHATTAN, WEBGPUDISTANCE.Difference]),\n [\"BITARRAY\" /* WGPUENTRYTYPE.BITARRAY */]: new Set([WEBGPUDISTANCE.TANIMOTO, WEBGPUDISTANCE.COSINE, WEBGPUDISTANCE.SOKAL, WEBGPUDISTANCE.ASYMMETRIC])\n};\n//# sourceMappingURL=webGPU-multicol-distances.js.map","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nlet gpuAdapter = null;\nlet gpuDevice = null;\nexport function getGPUDevice() {\n return __awaiter(this, void 0, void 0, function* () {\n if (!gpuAdapter) {\n //reason: only here we get the gpuAdapter\n // eslint-disable-next-line no-restricted-syntax\n gpuAdapter = yield navigator.gpu.requestAdapter({ powerPreference: 'high-performance' });\n if (gpuAdapter == null)\n return null;\n }\n let isLost = false;\n if (gpuDevice) {\n gpuDevice.lost.then(() => {\n isLost = true;\n });\n yield new Promise((r) => setTimeout(r, 10)); // wait to see if the device is lost\n }\n if (!gpuDevice || isLost) {\n const requiredBufferSize = 1000000000; // ~1000MB\n const adapterLimits = gpuAdapter.limits;\n const buffferSizeLimit = adapterLimits.maxBufferSize;\n const storageBufferSizeLimit = adapterLimits.maxStorageBufferBindingSize;\n try {\n gpuDevice = yield gpuAdapter.requestDevice({ requiredLimits: {\n maxBufferSize: Math.min(buffferSizeLimit, requiredBufferSize),\n maxStorageBufferBindingSize: Math.min(storageBufferSizeLimit, requiredBufferSize)\n } });\n return gpuDevice;\n }\n catch (e) {\n console.error('Failed to create device with required limits', e);\n gpuDevice = yield gpuAdapter.requestDevice();\n return gpuDevice;\n }\n }\n return gpuDevice;\n });\n}\nexport function getGPUAdapterDescription() {\n return __awaiter(this, void 0, void 0, function* () {\n if (!gpuAdapter) {\n // reason: only here we get the gpuAdapter\n // eslint-disable-next-line no-restricted-syntax\n gpuAdapter = yield navigator.gpu.requestAdapter();\n if (gpuAdapter == null)\n return null;\n }\n const info = yield gpuAdapter.requestAdapterInfo();\n if (!info)\n return null;\n const outString = replaceEmptyString(info.description, replaceEmptyString(info.vendor, 'No GPU description available'));\n return outString;\n });\n}\nfunction replaceEmptyString(str, replacement) {\n return !str || str == '' ? replacement : str;\n}\n//# sourceMappingURL=getGPUDevice.js.map","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nimport { WEBGSLAGGREGATION, WEBGSLAGGREGATIONFUNCTIONS, } from '../multi-col-distances/webGPU-aggregation';\nimport { WEBGPUDISTANCE, webGPUFunctions, } from '../multi-col-distances/webGPU-multicol-distances';\nimport { webGPUProcessInfo } from '../preprocessing/webGPU-process-info';\nimport { getGPUDevice } from '../getGPUDevice';\n/** generate sparse matrix based on list of lists of entries.\n * these entries are each encoded as Uint32Array or FLOAT32Array (depending on their type).\n * for example, sequences would be encoded as Uint32Array based on char code of the letter at each position.\n * [65, 66, 67, 68, 69] would be a sequence of 5 letters.\n * for chemical fingerprints, it would be a binary array of 0s and 1s,\n * represented as Uint32Array(_data property of DG bitarray).\n *\n * Be ware that size of entryList, distanceMetrics, weights and options must be the same.\n * if there are no options for entries i, pass an empty object.\n * for now options are needed for\n * needleman-wunsch and monomer chemical distances: see {@link BioDistanceFnOptions} as for how it should be passed\n * numeric distances (Difference): {range: number} where range is the range of the values in the column (max - min).\n * in both cases, if options are not provided, they will be calculated automatically.\n */\nexport function multiColWebGPUSparseMatrix(entryList, // list of lists of entries, for multiple columns\nthreshold = 0.8, // similarity threshold, be ware that if you use too small threshold, there might be memory overflow...\ndistanceMetrics, // distance metrics for each column\naggregationFunction, // aggregation function for the distances\nweights, // weights for each column\noptions // supplementary options for each column\n) {\n return __awaiter(this, void 0, void 0, function* () {\n const device = yield getGPUDevice();\n if (!device)\n return null; // if no device, return null, as we cannot do anything without it.\n const availableDistanceMetrics = Object.values(WEBGPUDISTANCE);\n if (distanceMetrics.some((metric) => !availableDistanceMetrics.includes(metric)))\n throw new Error('Invalid distance metrics provided: ' + distanceMetrics.join(', '));\n const availableAggregationFunctions = Object.values(WEBGSLAGGREGATION);\n if (!availableAggregationFunctions.includes(aggregationFunction))\n throw new Error('Invalid aggregation function provided: ' + aggregationFunction);\n const maxDistance = 1 - threshold; // maximum distance\n // first, check that all the supplementary options are provided and are the same length:\n if (options.length !== entryList.length ||\n options.length !== distanceMetrics.length ||\n options.length !== weights.length) {\n throw new Error('Options, weigths and distance functions must be provided for each column');\n }\n // check that all the entry lists are the same length\n if (entryList.some((list) => list.length !== entryList[0].length))\n throw new Error('All entry lists must be the same length');\n const numOfColumns = entryList.length; // number of columns\n const listSize = entryList[0].length; // size of each list (or column)\n const processInfo = entryList.map((entry, i) => {\n return webGPUProcessInfo(entry, distanceMetrics[i], i, options[i]);\n });\n if (numOfColumns === 0) {\n throw new Error('No columns provided. Please provide at least one column of data.');\n }\n if (numOfColumns === 1)\n aggregationFunction = WEBGSLAGGREGATION.MANHATTAN; // save a bit of time\n // combine all struct types into one to put into the suppInfo struct.\n let suppInfoWgsl = processInfo\n .map((info) => info.suppInfoStructWgsl)\n .filter((wgsl) => !!wgsl && wgsl != '')\n .join(',\\n');\n // structures in wgsl must have at least one member, so if we have no structures, we need to add a dummy one\n let needsDummy = false;\n if (!suppInfoWgsl || suppInfoWgsl.trim() == '') {\n needsDummy = true;\n suppInfoWgsl = '\\ndummy: f32\\n';\n }\n // combine all data wgsl struct code into one\n const dataWgsl = processInfo.map((info) => info.dataStructWgsl).filter((wgsl) => !!wgsl && wgsl != '').join(',\\n');\n // combine all array sizes into one array (easier for setting)\n const arraySizes = new Uint32Array(numOfColumns * listSize);\n processInfo.forEach((info, i) => {\n arraySizes.set(info.arraySizes, i * listSize);\n }); // array.flat is not as optimized as this\n // if we try to map large arrays directly from GPU, sometimes, device disconnects. so we need to do it in chunks, a good number\n // we found is 10000. So we will perform computations in chunks of 10000. meaning that we will dispatch 10000 threads at a time.\n const numOfThreads = 10000;\n // in this case we do not need to worry about complexity of the algorithm, as the 100 is low enaugh number, which is limited by memory usage.\n const sparseResultSizePerThread = 100; // number of iterations per thread (number of pair comparisons)\n const combinedComplexity = processInfo.reduce((a, b) => a + b.complexity, 0); // combined complexity of all the columns\n const maxIterationsPerThread = Math.ceil(10000 / combinedComplexity); // maximum number of iterations per thread\n const workGroupDivision = 10; // how many threads inside of one workgroup dimension (in this case 10 * 10 threads per workgroup)\n const threadsPerWorkgroup = workGroupDivision * workGroupDivision;\n const workgroupsDim = Math.ceil(Math.sqrt(Math.ceil(numOfThreads / threadsPerWorkgroup))); // how many workgroups per 2d dimension\n const globalThreadDimSize = workgroupsDim * workGroupDivision; // how many threads per 2d dimension\n const condensedDistanceMatrixSize = listSize * (listSize - 1) / 2; // size of the condensed distance matrix, this many comparisons will be made.\n const dmChunkSizePerThread = Math.ceil(condensedDistanceMatrixSize / numOfThreads); // how many comparisons per thread\n const module = device.createShaderModule({\n label: 'Sparse matrix compute shader',\n code: `\n // each thread will perform ${sparseResultSizePerThread} iterations at one time, comparing ${sparseResultSizePerThread} pairs of entries.\n // in total, each thread will perform at most ${dmChunkSizePerThread} comparisons.\n // first is the result struct, containing is, js, and distances. each array with length of ${sparseResultSizePerThread},\n // and also integer for how many pairs were found to be below threshold.\n struct SparseResult {\n i: array<array<u32, ${sparseResultSizePerThread}>, ${numOfThreads}>,\n j: array<array<u32, ${sparseResultSizePerThread}>, ${numOfThreads}>,\n distances: array<array<f32, ${sparseResultSizePerThread}>, ${numOfThreads}>,\n found: array<u32, ${numOfThreads}>,\n done: array<u32, ${numOfThreads}>\n }\n // struct for the data\n struct ComputeInfo {\n // start at cols and rows, and end at cols and rows for each thread, these will be calculated on cpu and passed to gpu.\n startAtCols: array<u32, ${numOfThreads}>,\n startAtRows: array<u32, ${numOfThreads}>,\n endAtCols: array<u32, ${numOfThreads}>,\n endAtRows: array<u32, ${numOfThreads}>,\n\n // the ACTUALLY sizes of each entry\n entrySizes: array<array<u32, ${listSize}>, ${numOfColumns}>,\n // the weights for each entry\n weights: array<f32, ${numOfColumns}>,\n // the data for each entry\n ${dataWgsl} // an example of the dataWgsl would be:\n //data0: array<array<u32,20>,100>,\n //data1: array<array<u32,20>,100>\n }\n\n // struct for the supplementary information\n struct SuppInfo {\n // struct containing all the supplementary info, like scoring matrix, alphabet indexes, range, etc.\n ${suppInfoWgsl}\n };\n\n @group(0) @binding(0) var<storage, read_write> computeInfo: ComputeInfo;\n @group(0) @binding(1) var<storage, read_write> suppInfo: SuppInfo;\n @group(0) @binding(2) var<storage, read_write> results: SparseResult;\n @compute @workgroup_size(${workGroupDivision}, ${workGroupDivision}) fn calcSparseMatrix(\n @builtin(global_invocation_id) id: vec3<u32>\n ) {\n ${needsDummy ? `let otherDummy = suppInfo.dummy * 2;` : ''} // just to make sure that the suppInfo is not optimized out\n let threadCol = id.x;\n let threadRow = id.y;\n let linearIndex = threadRow * ${globalThreadDimSize} + threadCol;\n if (linearIndex >= ${numOfThreads}) {\n return; // if we are out of bounds, return\n } \n var startAtCol: u32 = computeInfo.startAtCols[linearIndex];\n var startAtRow: u32 = computeInfo.startAtRows[linearIndex];\n let endAtCol: u32 = min(computeInfo.endAtCols[linearIndex], ${listSize}u);\n let endAtRow: u32 = min(computeInfo.endAtRows[linearIndex], ${listSize}u);\n let is = &results.i[linearIndex];\n let js = &results.j[linearIndex];\n let distances = &results.distances[linearIndex];\n results.found[linearIndex] = 0; // initialize the found counter\n var found: u32 = 0;\n if (results.done[linearIndex] > 0) {\n return; // if we are done, return\n }\n for (var i = 0; i < ${maxIterationsPerThread}; i++) {\n if (startAtCol >= endAtCol && startAtRow >= endAtRow) {\n results.done[linearIndex] = 1;\n break;\n }\n if (found >= ${sparseResultSizePerThread}) {\n break;\n }\n let dist = combinedDistance(startAtCol, startAtRow);\n if (dist <= ${maxDistance}) {\n (*is)[found] = startAtCol;\n (*js)[found] = startAtRow;\n (*distances)[found] = dist;\n found = found + 1;\n }\n startAtCol = startAtCol + 1;\n if (startAtCol >= ${listSize}u) {\n startAtRow += 1;\n startAtCol = startAtRow + 1;\n }\n }\n results.found[linearIndex] = found;\n // update the startAtCols and startAtRows\n computeInfo.startAtCols[linearIndex] = startAtCol;\n computeInfo.startAtRows[linearIndex] = startAtRow;\n\n }\n\n // this will generate the distance script for each distance metric and then combine them into one\n ${getCombinedDistanceScript(distanceMetrics, processInfo.map((info) => info.maxEntryLen), maxDistance, aggregationFunction)}\n\n\n `\n });\n const pipeline = device.createComputePipeline({\n label: 'sparse matrix compute pipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'calcSparseMatrix',\n },\n });\n // generate startAtCols, startAtRows, endAtCols, endAtRows\n const startAtCols = new Uint32Array(numOfThreads);\n const startAtRows = new Uint32Array(numOfThreads);\n const endAtCols = new Uint32Array(numOfThreads);\n const endAtRows = new Uint32Array(numOfThreads);\n const chunkSize = Math.floor(condensedDistanceMatrixSize / numOfThreads); // size of the chunk per thread (in total)\n let startRow = 0;\n let startCol = 1;\n console.time('GPUthreadStarts');\n for (let i = 0; i < numOfThreads; i++) {\n const endIdx = i === numOfThreads - 1 ? condensedDistanceMatrixSize - 1 : (i + 1) * chunkSize;\n // fancy formulas to calculate the start and end indices for the condensed distance matrix for each thread start\n const endRow = listSize - 2 - Math.floor(Math.sqrt(-8 * endIdx + 4 * listSize * (listSize - 1) - 7) / 2 - 0.5);\n const endCol = endIdx - listSize * endRow + Math.floor((endRow + 1) * (endRow + 2) / 2);\n startAtCols[i] = startCol;\n startAtRows[i] = startRow;\n endAtCols[i] = endCol;\n endAtRows[i] = endRow;\n startRow = endRow;\n startCol = endCol;\n // const startRow = values[0].length - 2 - Math.floor(\n // Math.sqrt(-8 * startIdx + 4 * values[0].length * (values[0].length - 1) - 7) / 2 - 0.5);\n // const startCol = startIdx - values[0].length * startRow + Math.floor((startRow + 1) * (startRow + 2) / 2);\n }\n console.timeEnd('GPUthreadStarts');\n // size of the computeInfo buffer\n const computeInfoBuffer32Size = numOfThreads * 4 + // startAtCols, startAtRows, endAtCols, endAtRows\n listSize * numOfColumns + // entrySizes\n numOfColumns + // weights\n processInfo.reduce((a, b) => a + b.sourceArraySize, 0);\n // size of the suppInfo buffer\n const suppInfoBuffer32Size = processInfo.reduce((a, b) => a + b.suppInfoSize, 0);\n // size of the results buffer\n const sparseMatrixEachArray32Size = sparseResultSizePerThread * numOfThreads;\n const resultsBuffer32Size = 3 * sparseMatrixEachArray32Size + numOfThreads + numOfThreads; // i, j, distances, found, done\n // create a buffer on the GPU to hold computeInfo\n // beware that struct must be padded to 16 bytes, so we need to calculate the size of the struct in 32bit values\n const computeInfoBufferSize = computeInfoBuffer32Size * Uint32Array.BYTES_PER_ELEMENT;\n let paddedComputeInfoBufferSize = computeInfoBufferSize;\n const remainder = computeInfoBufferSize & 15; // check if the size is a multiple of 16\n if (remainder !== 0)\n paddedComputeInfoBufferSize += 16 - remainder; // pad the size accordingly\n const computeInfoBuffer = device.createBuffer({\n label: 'compute info buffer',\n size: paddedComputeInfoBufferSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedComputeInfoArrayBuffer = computeInfoBuffer.getMappedRange(); // get full buffer\n // dynamic offset for the computeInfo buffer\n let computeInfoOffSet = 0;\n // first write the startAtCols, startAtRows, endAtCols, endAtRows\n const startAtColsBufferView = new Uint32Array(mappedComputeInfoArrayBuffer, computeInfoOffSet, numOfThreads);\n startAtColsBufferView.set(startAtCols);\n computeInfoOffSet += numOfThreads * Uint32Array.BYTES_PER_ELEMENT; // array of 32bit values\n const startAtRowsBufferView = new Uint32Array(mappedComputeInfoArrayBuffer, computeInfoOffSet, numOfThreads);\n startAtRowsBufferView.set(startAtRows);\n computeInfoOffSet += numOfThreads * Uint32Array.BYTES_PER_ELEMENT; // array of 32bit values\n const endAtColsBufferView = new Uint32Array(mappedComputeInfoArrayBuffer, computeInfoOffSet, numOfThreads);\n endAtColsBufferView.set(endAtCols);\n computeInfoOffSet += numOfThreads * Uint32Array.BYTES_PER_ELEMENT; // array of 32bit values\n const endAtRowsBufferView = new Uint32Array(mappedComputeInfoArrayBuffer, computeInfoOffSet, numOfThreads);\n endAtRowsBufferView.set(endAtRows);\n computeInfoOffSet += numOfThreads * Uint32Array.BYTES_PER_ELEMENT; // array of 32bit values\n // then write the entrySizes\n const entrySizesView = new Uint32Array(mappedComputeInfoArrayBuffer, computeInfoOffSet, arraySizes.length);\n entrySizesView.set(arraySizes);\n computeInfoOffSet += arraySizes.length * Uint32Array.BYTES_PER_ELEMENT; // array of 32bit values\n // then write the weights\n const weightsView = new Float32Array(mappedComputeInfoArrayBuffer, computeInfoOffSet, numOfColumns);\n weightsView.set(weights);\n computeInfoOffSet += numOfColumns * Float32Array.BYTES_PER_ELEMENT;\n // finally, write the data itself\n for (const info of processInfo) {\n const ArrayConstructor = info.EncodedArrayConstructor;\n const chunkSize = info.sourceArraySize;\n const dataView = new ArrayConstructor(mappedComputeInfoArrayBuffer, computeInfoOffSet, chunkSize); //new ArrayConstructor(computeInfoBuffer.getMappedRange(computeInfoOffSet, chunkByteSize));\n dataView.set(info.flatSourceArray);\n computeInfoOffSet += chunkSize * ArrayConstructor.BYTES_PER_ELEMENT;\n }\n // we are done at this point.\n computeInfoBuffer.unmap();\n // create a buffer on the GPU to hold suppInfo\n // same here, we need to pad the size of the struct to 16 bytes\n const suppInfoBufferSize = suppInfoBuffer32Size * Uint32Array.BYTES_PER_ELEMENT;\n let paddedSuppInfoBufferSize = suppInfoBufferSize;\n const suppInfoRemainder = suppInfoBufferSize & 15; // check if the size is a multiple of 16\n if (suppInfoRemainder !== 0)\n paddedSuppInfoBufferSize += 16 - suppInfoRemainder; // pad the size accordingly\n paddedSuppInfoBufferSize = Math.max(paddedSuppInfoBufferSize, 16);\n const suppInfoBuffer = device.createBuffer({\n label: 'supp info buffer',\n size: paddedSuppInfoBufferSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const mappedSuppInfoArrayBuffer = suppInfoBuffer.getMappedRange(); // get full buffer\n let suppInfoOffSet = 0;\n for (const info of processInfo) {\n if (info.suppInfoBuffer && info.suppInfoBuffer.byteLength > 0 && info.suppInfoSize > 0) {\n const ArrayConstructor = info.suppInfoType === \"UINT32ARRAY\" /* WGPUENTRYTYPE.UINT32ARRAY */ ? Uint32Array : Float32Array;\n const suppInfoView = new ArrayConstructor(mappedSuppInfoArrayBuffer, suppInfoOffSet, info.suppInfoBuffer.length); //new ArrayConstructor(suppInfoBuffer.getMappedRange(suppInfoOffSet, info.suppInfoBuffer.byteLength));\n suppInfoView.set(info.suppInfoBuffer);\n suppInfoOffSet += info.suppInfoBuffer.byteLength; // info.suppInfoBuffer.length * ArrayConstructor.BYTES_PER_ELEMENT;\n }\n }\n if (suppInfoOffSet === 0) {\n const dummyView = new Uint32Array(mappedSuppInfoArrayBuffer, 0, 4); //new Uint32Array(suppInfoBuffer.getMappedRange(0, 16));\n dummyView.set([1, 1, 1, 1]);\n }\n suppInfoBuffer.unmap();\n // create a buffer for the results\n const resultsBufferSize = resultsBuffer32Size * Uint32Array.BYTES_PER_ELEMENT;\n let paddedResultsBufferSize = resultsBufferSize;\n const resultsRemainder = resultsBufferSize & 15; // check if the size is a multiple of 16\n if (resultsRemainder !== 0)\n paddedResultsBufferSize += 16 - resultsRemainder; // pad the size accordingly\n const resultsBuffer = device.createBuffer({\n label: 'results buffer',\n size: paddedResultsBufferSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC\n });\n // Setup a bindGroup to tell the shader which\n // buffer to use for the computation\n const bindGroup = device.createBindGroup({\n label: 'bindGroup for sparse matrix buffer',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: computeInfoBuffer } },\n { binding: 1, resource: { buffer: suppInfoBuffer } },\n { binding: 2, resource: { buffer: resultsBuffer } },\n ],\n });\n //const pairComparisonsPerPass = maxIterationsPerThread * numOfThreads;\n //const passes = Math.ceil(condensedDistanceMatrixSize / pairComparisonsPerPass);\n // we will distpatch this many passes to the GPU, and it will handle indexes all by itself.\n // we already copied the start/end information to it, so it will know where to start and end on each pass.\n const resultsOutBuffer = device.createBuffer({\n label: 'results out buffer',\n size: resultsBuffer.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n const resultIs = [];\n const resultJs = [];\n const resultDistances = [];\n //let combinedFound = 0;\n let isAllDone = false;\n while (!isAllDone) {\n // Encode commands to do the computation\n const encoder = device.createCommandEncoder({\n label: 'distance encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'distance compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(workgroupsDim, workgroupsDim);\n pass.end();\n encoder.copyBufferToBuffer(resultsBuffer, 0, resultsOutBuffer, 0, resultsOutBuffer.size);\n // Finish encoding and submit the commands\n const commandBuffer = encoder.finish();\n device.queue.submit([commandBuffer]);\n // Read the results\n yield device.queue.onSubmittedWorkDone();\n yield resultsOutBuffer.mapAsync(GPUMapMode.READ);\n const resultsOutArrayBuffer = resultsOutBuffer.getMappedRange();\n // read the results\n let resultOffset = 0;\n const resultsI = new Uint32Array(resultsOutArrayBuffer, resultOffset, sparseMatrixEachArray32Size);\n resultOffset += sparseMatrixEachArray32Size * Uint32Array.BYTES_PER_ELEMENT;\n const resultsJ = new Uint32Array(resultsOutArrayBuffer, resultOffset, sparseMatrixEachArray32Size);\n resultOffset += sparseMatrixEachArray32Size * Uint32Array.BYTES_PER_ELEMENT;\n const resultsDistances = new Float32Array(resultsOutArrayBuffer, resultOffset, sparseMatrixEachArray32Size);\n resultOffset += sparseMatrixEachArray32Size * Float32Array.BYTES_PER_ELEMENT;\n const resultsFound = new Uint32Array(resultsOutArrayBuffer, resultOffset, numOfThreads);\n resultOffset += numOfThreads * Uint32Array.BYTES_PER_ELEMENT;\n const resultsDone = new Uint32Array(resultsOutArrayBuffer, resultOffset, numOfThreads);\n isAllDone = resultsDone.every((d) => d === 1);\n const totalResults = resultsFound.reduce((a, b) => a + b, 0);\n const combinedI = new Uint32Array(totalResults);\n const combinedJ = new Uint32Array(totalResults);\n const combinedDistances = new Float32Array(totalResults);\n let combinedOffset = 0;\n for (let resI = 0; resI < resultsFound.length; resI++) {\n const found = resultsFound[resI];\n if (found === 0)\n continue;\n combinedI.set(resultsI.subarray(resI * sparseResultSizePerThread, resI * sparseResultSizePerThread + found), combinedOffset);\n combinedJ.set(resultsJ.subarray(resI * sparseResultSizePerThread, resI * sparseResultSizePerThread + found), combinedOffset);\n combinedDistances.set(resultsDistances.subarray(resI * sparseResultSizePerThread, resI * sparseResultSizePerThread + found), combinedOffset);\n combinedOffset += found;\n }\n resultIs.push(combinedI);\n resultJs.push(combinedJ);\n resultDistances.push(combinedDistances);\n resultsOutBuffer.unmap();\n }\n const totalSize = resultIs.reduce((a, b) => a + b.length, 0);\n const finalI = new Uint32Array(totalSize);\n const finalJ = new Uint32Array(totalSize);\n const finalDistances = new Float32Array(totalSize);\n let finalOffset = 0;\n for (let i = 0; i < resultIs.length; i++) {\n finalI.set(resultIs[i], finalOffset);\n finalJ.set(resultJs[i], finalOffset);\n finalDistances.set(resultDistances[i], finalOffset);\n finalOffset += resultIs[i].length;\n }\n // as rule mandates, destroy all buffers.\n computeInfoBuffer.destroy();\n suppInfoBuffer.destroy();\n resultsBuffer.destroy();\n resultsOutBuffer.destroy();\n return { i: finalI, j: finalJ, distance: finalDistances };\n });\n}\nfunction getCombinedDistanceScript(distanceMetrics, maxEntryLens, maxDistance, aggregation) {\n const distanceWgsls = distanceMetrics.map((metric, i) => {\n return `\n fn distanceScript${i}(aIndex: u32, bIndex: u32) -> f32 {\n let a = computeInfo.data${i}[aIndex];\n let b = computeInfo.data${i}[bIndex];\n let maxDistance: f32 = ${maxDistance};\n ${webGPUFunctions[metric](maxEntryLens[i], i)}\n }\n `;\n });\n const allDistanceScripts = distanceWgsls.join('\\n');\n const combineDistancesScript = `\n fn combinedDistance(aIndex: u32, bIndex: u32) -> f32 {\n var distances: array<f32, ${distanceMetrics.length}>;\n ${distanceMetrics.map((_, i) => `distances[${i}] = distanceScript${i}(aIndex, bIndex);`).join('\\n')}\n ${WEBGSLAGGREGATIONFUNCTIONS[aggregation](distanceMetrics.length)}\n }\n \n `;\n return allDistanceScripts + '\\n' + combineDistancesScript;\n}\n//# sourceMappingURL=webGPU-sparse-matrix.js.map","/* eslint-disable max-len */\nimport { distanceFunctionComplexity, TypeSupportedDistances, WEBGPUDISTANCE } from '../multi-col-distances/webGPU-multicol-distances';\nexport function webGPUProcessInfo(entryList, distanceMetric = WEBGPUDISTANCE.HAMMING, entryIndex, // index of the entries in the list of lists that we want to process\noptions = { gapOpenPenalty: 1.0, gapExtensionPenalty: 0.6 }) {\n var _a, _b;\n let entryType = null;\n const encodedList = (() => {\n if (entryList.some((e) => typeof e === 'string')) {\n entryType = \"STRING\" /* WGPUENTRYTYPE.STRING */;\n return entryList.map((entry) => new Uint32Array(entry.split('').map((c) => c.charCodeAt(0))));\n }\n if (entryList.some((e) => typeof e === 'number')) {\n entryType = \"NUMBER\" /* WGPUENTRYTYPE.NUMBER */;\n return entryList.map((entry) => new Float32Array([entry]));\n }\n if (typeof entryList[0] == 'object' && entryList.some((e) => '_data' in e && '_length' in e)) {\n entryType = \"BITARRAY\" /* WGPUENTRYTYPE.BITARRAY */;\n return entryList.map((entry) => entry._data);\n }\n if (entryList.some((e) => e instanceof Float32Array)) {\n entryType = \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */;\n return entryList;\n }\n if (entryList.some((e) => e instanceof Uint32Array)) {\n entryType = \"UINT32ARRAY\" /* WGPUENTRYTYPE.UINT32ARRAY */;\n return entryList;\n }\n if (entryList.some((e) => e instanceof Int32Array)) {\n entryType = \"INT32ARRAY\" /* WGPUENTRYTYPE.INT32ARRAY */;\n return entryList;\n }\n //return entryList as Uint32Array[];\n })();\n if (!encodedList || !entryType)\n throw new Error('Invalid entry type, could not determine entry type from input list');\n const encodedListType = encodedList[0] instanceof Int32Array ? \"INT32ARRAY\" /* WGPUENTRYTYPE.INT32ARRAY */ :\n encodedList[0] instanceof Float32Array ? \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */ : \"UINT32ARRAY\" /* WGPUENTRYTYPE.UINT32ARRAY */;\n // sizes of each entries might differ, so we need to keep track of that for some distance metrics, like hamming for example\n const arraySizes = new Uint32Array(encodedList.map((arr) => arr.length));\n if (!TypeSupportedDistances[entryType] || !TypeSupportedDistances[entryType].has(distanceMetric))\n throw new Error(`Distance metric '${distanceMetric}' not supported for entry type '${entryType}'`);\n const maxEntryLen = arraySizes.reduce((a, b) => Math.max(a, b), 0);\n // get the complexity of used algorithm\n const complexity = distanceFunctionComplexity[distanceMetric](maxEntryLen);\n const EncodedArrayConstructor = encodedListType === \"INT32ARRAY\" /* WGPUENTRYTYPE.INT32ARRAY */ ? Int32Array :\n (encodedListType === \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */ ? Float32Array : Uint32Array);\n const flatSourceArray = new EncodedArrayConstructor(encodedList.length * maxEntryLen);\n // when setting, we need to set each array at a specific offset, which is controlled by maxArrayLen because each array might have different sizes.\n // this way we will get correct matrix representation in the compute shader\n encodedList.forEach((seq, i) => {\n flatSourceArray.set(seq, i * maxEntryLen);\n });\n // NB! all this before the line was generic, now we need to calculate some specific things for some specific distance metrics\n // initialize supp info line that will be included in the final shader;\n let suppInfoStructWgsl = ''; // the code that will be included in the struct of suppInfo\n let suppInfoSize = 0;\n let suppInfoType = \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */;\n let suppInfoBuffer = null;\n if (distanceMetric === WEBGPUDISTANCE.NEEDLEMAN_WUNSCH || distanceMetric === WEBGPUDISTANCE.MONOMER_CHEMICAL_DISTANCE) {\n let maxMonomerIndex = options.scoringMatrix && options.alphabetIndexes ?\n Object.keys(options.alphabetIndexes).reduce((prev, n) => Math.max(prev, n.charCodeAt(0)), 0) : -1;\n // generate default similarity matrix if it is not provided\n if (!options.alphabetIndexes || !options.scoringMatrix) {\n for (let i = 0; i < flatSourceArray.length; i++) {\n if (flatSourceArray[i] > maxMonomerIndex)\n maxMonomerIndex = flatSourceArray[i];\n }\n options.scoringMatrix =\n new Array(maxMonomerIndex + 1).fill(null).map(() => new Array(maxMonomerIndex + 1).fill(0));\n options.alphabetIndexes = {};\n for (let i = 0; i < options.scoringMatrix.length; i++) {\n options.scoringMatrix[i][i] = 1;\n options.alphabetIndexes[String.fromCharCode(i)] = i;\n }\n }\n const similarityMatrixSize = (maxMonomerIndex + 1) * (maxMonomerIndex + 1);\n const transferedSimilarityMatrix = new Array(maxMonomerIndex + 1).fill(null).map(() => new Float32Array(maxMonomerIndex + 1));\n // set diagonal to 1\n for (let i = 0; i < maxMonomerIndex + 1; i++)\n transferedSimilarityMatrix[i][i] = 1;\n const alphabetIndexes = options.alphabetIndexes;\n for (const key of Object.keys(alphabetIndexes)) {\n for (const key2 of Object.keys(alphabetIndexes)) {\n if (key === key2)\n continue;\n transferedSimilarityMatrix[key.charCodeAt(0)][key2.charCodeAt(0)] =\n options.scoringMatrix[alphabetIndexes[key]][alphabetIndexes[key2]];\n }\n }\n // in memory layout, we will have 2 float32 s for gapOpen and gapExtension penalties, and then f32 array<array<f32>> for similarity matrix.\n // because of primitives, there will be no padding, so we can calculate the size directly\n suppInfoSize = 2 + similarityMatrixSize;\n suppInfoType = \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */;\n suppInfoBuffer = new Float32Array(suppInfoSize);\n suppInfoBuffer[0] = (_a = options.gapOpenPenalty) !== null && _a !== void 0 ? _a : 1.0;\n suppInfoBuffer[1] = (_b = options.gapExtensionPenalty) !== null && _b !== void 0 ? _b : 0.6;\n let offset = 2;\n for (let i = 0; i < transferedSimilarityMatrix.length; i++) {\n suppInfoBuffer.set(transferedSimilarityMatrix[i], offset);\n offset += transferedSimilarityMatrix[i].length;\n }\n suppInfoStructWgsl = `\n gapOpenPenalty${entryIndex}: f32,\n gapExtensionPenalty${entryIndex}: f32,\n similarityMatrix${entryIndex}: array<array<f32, ${maxMonomerIndex + 1}>, ${maxMonomerIndex + 1}>`;\n }\n else if (distanceMetric === WEBGPUDISTANCE.Difference) {\n // for difference, we need range of values for normalization of the difference\n if (!options.range || typeof options.range !== 'number' || options.range <= 0) {\n const min = flatSourceArray.reduce((a, b) => Math.min(a, b), flatSourceArray[0]);\n const max = flatSourceArray.reduce((a, b) => Math.max(a, b), flatSourceArray[0]);\n options.range = max - min;\n }\n if (options.range <= 0)\n options.range = 1.0; // this means that all values are the same, and all distances will produce 0.\n suppInfoSize = 1;\n suppInfoType = \"FLOAT32ARRAY\" /* WGPUENTRYTYPE.FLOAT32ARRAY */;\n suppInfoBuffer = new Float32Array([options.range]);\n suppInfoStructWgsl = `\n range${entryIndex}: f32`;\n }\n const dataTypeWGSL = flatSourceArray instanceof Int32Array ? 'i32' : (flatSourceArray instanceof Float32Array ? 'f32' : 'u32');\n const dataStructWgsl = `data${entryIndex}: array<array<${dataTypeWGSL}, ${maxEntryLen}>, ${encodedList.length}>`;\n // for now, other distances do not require any additional information, so we can skip that\n return {\n flatSourceArray,\n sourceArraySize: flatSourceArray.length,\n maxEntryLen,\n arraySizes,\n complexity,\n suppInfoBuffer,\n suppInfoSize,\n suppInfoType: suppInfoType,\n suppInfoStructWgsl,\n entryType,\n dataTypeWGSL,\n dataStructWgsl,\n EncodedArrayConstructor\n };\n}\n//# sourceMappingURL=webGPU-process-info.js.map","export async function bioLayout(cluster, sparseObject, threshold) {\n const n = cluster.length;\n const is = [];\n const js = [];\n for (let i = 0; i < n; i++) {\n for (let j = i + 1; j < n; j++) {\n const a = cluster[i];\n const b = cluster[j];\n if (sparseObject[a]?.[b] >= threshold) {\n is.push(i);\n js.push(j);\n }\n }\n }\n return getLayoutEmbeddings(is, js, cluster);\n}\nfunction getLayoutEmbeddings(is, js, cluster) {\n const embedX = new Float32Array(cluster.length).fill(0).map(() => Math.random() * 10);\n const embedY = new Float32Array(cluster.length).fill(0).map(() => Math.random() * 10);\n const iterations = 100;\n const xVelocities = new Float32Array(cluster.length).fill(0);\n const yVelocities = new Float32Array(cluster.length).fill(0);\n for (let i = 0; i < iterations; i++) {\n const temperature = (1 - i / iterations);\n xVelocities.fill(0);\n yVelocities.fill(0);\n for (let idx = 0; idx < is.length; idx++) {\n const a = is[idx];\n const b = js[idx];\n const dx = embedX[a] - embedX[b];\n const dy = embedY[a] - embedY[b];\n // const distance = Math.sqrt(dx * dx + dy * dy);\n // const factor = (distance - 1) / distance;\n // const offsetX = dx * factor;\n // const offsetY = dy * factor;\n if (Math.abs(dx) >= 1) {\n xVelocities[a] -= temperature * dx;\n xVelocities[b] += temperature * dx;\n }\n if (Math.abs(dy) >= 1) {\n yVelocities[a] -= temperature * dy;\n yVelocities[b] += temperature * dy;\n }\n // embedY[a] += offsetY * temperature;\n // embedY[b] -= offsetY * temperature;\n }\n for (let idx = 0; idx < cluster.length; idx++) {\n const vecSize = Math.sqrt(xVelocities[idx] * xVelocities[idx] + yVelocities[idx] * yVelocities[idx]);\n if (vecSize > 0) {\n embedX[idx] += xVelocities[idx] / vecSize * temperature;\n embedY[idx] += yVelocities[idx] / vecSize * temperature;\n }\n }\n }\n // normalize\n let minX = embedX[0];\n let minY = embedY[0];\n let maxX = embedX[0];\n let maxY = embedY[0];\n for (let idx = 1; idx < cluster.length; idx++) {\n minX = Math.min(minX, embedX[idx]);\n minY = Math.min(minY, embedY[idx]);\n maxX = Math.max(maxX, embedX[idx]);\n maxY = Math.max(maxY, embedY[idx]);\n }\n let rangeX = maxX - minX;\n let rangeY = maxY - minY;\n if (rangeX === 0)\n rangeX = maxX;\n for (let idx = 0; idx < cluster.length; idx++)\n embedX[idx] = (embedX[idx] - minX) / rangeX / 2 + 0.5;\n if (rangeY === 0)\n rangeY = maxY;\n for (let idx = 0; idx < cluster.length; idx++)\n embedY[idx] = (embedY[idx] - minY) / rangeY / 2 + 0.5;\n return { embedX, embedY };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmlvLWxheW91dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImJpby1sYXlvdXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxDQUFDLEtBQUssVUFBVSxTQUFTLENBQUMsT0FBaUIsRUFBRSxZQUFnQyxFQUFFLFNBQWlCO0lBQ3BHLE1BQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFDekIsTUFBTSxFQUFFLEdBQWEsRUFBRSxDQUFDO0lBQ3hCLE1BQU0sRUFBRSxHQUFhLEVBQUUsQ0FBQztJQUN4QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDM0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUMvQixNQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckIsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JCLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ3RDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ1gsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNiLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sbUJBQW1CLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUM5QyxDQUFDO0FBRUQsU0FBUyxtQkFBbUIsQ0FBQyxFQUFZLEVBQUUsRUFBWSxFQUFFLE9BQWlCO0lBQ3hFLE1BQU0sTUFBTSxHQUFHLElBQUksWUFBWSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxD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LENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsTUFBTSxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUM7SUFDeEQsSUFBSSxNQUFNLEtBQUssQ0FBQztRQUNkLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDaEIsS0FBSyxJQUFJLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFO1FBQzNDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxNQUFNLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztJQUV4RCxPQUFPLEVBQUMsTUFBTSxFQUFFLE1BQU0sRUFBQyxDQUFDO0FBQzFCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1NwYXJzZU1hdHJpeE9iamVjdH0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBiaW9MYXlvdXQoY2x1c3RlcjogbnVtYmVyW10sIHNwYXJzZU9iamVjdDogU3BhcnNlTWF0cml4T2JqZWN0LCB0aHJlc2hvbGQ6IG51bWJlcikge1xuICBjb25zdCBuID0gY2x1c3Rlci5sZW5ndGg7XG4gIGNvbnN0IGlzOiBudW1iZXJbXSA9IFtdO1xuICBjb25zdCBqczogbnVtYmVyW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBuOyBqKyspIHtcbiAgICAgIGNvbnN0IGEgPSBjbHVzdGVyW2ldO1xuICAgICAgY29uc3QgYiA9IGNsdXN0ZXJbal07XG4gICAgICBpZiAoc3BhcnNlT2JqZWN0W2FdPy5bYl0gPj0gdGhyZXNob2xkKSB7XG4gICAgICAgIGlzLnB1c2goaSk7XG4gICAgICAgIGpzLnB1c2goaik7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBnZXRMYXlvdXRFbWJlZGRpbmdzKGlzLCBqcywgY2x1c3Rlcik7XG59XG5cbmZ1bmN0aW9uIGdldExheW91dEVtYmVkZGluZ3MoaXM6IG51bWJlcltdLCBqczogbnVtYmVyW10sIGNsdXN0ZXI6IG51bWJlcltdKSB7XG4gIGNvbnN0IGVtYmVkWCA9IG5ldyBGbG9hdDMyQXJyYXkoY2x1c3Rlci5sZW5ndGgpLmZpbGwoMCkubWFwKCgpID0+IE1hdGgucmFuZG9tKCkgKiAxMCk7XG4gIGNvbnN0IGVtYmVkWSA9IG5ldyBGbG9hdDMyQXJyYXkoY2x1c3Rlci5sZW5ndGgpLmZpbGwoMCkubWFwKCgpID0+IE1hdGgucmFuZG9tKCkgKiAxMCk7XG4gIGNvbnN0IGl0ZXJhdGlvbnMgPSAxMDA7XG4gIGNvbnN0IHhWZWxvY2l0aWVzID0gbmV3IEZsb2F0MzJBcnJheShjbHVzdGVyLmxlbmd0aCkuZmlsbCgwKTtcbiAgY29uc3QgeVZlbG9jaXRpZXMgPSBuZXcgRmxvYXQzMkFycmF5KGNsdXN0ZXIubGVuZ3RoKS5maWxsKDApO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGl0ZXJhdGlvbnM7IGkrKykge1xuICAgIGNvbnN0IHRlbXBlcmF0dXJlID0gKDEgLSBpIC8gaXRlcmF0aW9ucyk7XG4gICAgeFZlbG9jaXRpZXMuZmlsbCgwKTtcbiAgICB5VmVsb2NpdGllcy5maWxsKDApO1xuICAgIGZvciAobGV0IGlkeCA9IDA7IGlkeCA8IGlzLmxlbmd0aDsgaWR4KyspIHtcbiAgICAgIGNvbnN0IGEgPSBpc1tpZHhdO1xuICAgICAgY29uc3QgYiA9IGpzW2lkeF07XG4gICAgICBjb25zdCBkeCA9IGVtYmVkWFthXSAtIGVtYmVkWFtiXTtcbiAgICAgIGNvbnN0IGR5ID0gZW1iZWRZW2FdIC0gZW1iZWRZW2JdO1xuICAgICAgLy8gICBjb25zdCBkaXN0YW5jZSA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG4gICAgICAvLyAgIGNvbnN0IGZhY3RvciA9IChkaXN0YW5jZSAtIDEpIC8gZGlzdGFuY2U7XG4gICAgICAvLyAgIGNvbnN0IG9mZnNldFggPSBkeCAqIGZhY3RvcjtcbiAgICAgIC8vICAgY29uc3Qgb2Zmc2V0WSA9IGR5ICogZmFjdG9yO1xuICAgICAgaWYgKE1hdGguYWJzKGR4KSA+PSAxKSB7XG4gICAgICAgIHhWZWxvY2l0aWVzW2FdIC09IHRlbXBlcmF0dXJlICogZHg7XG4gICAgICAgIHhWZWxvY2l0aWVzW2JdICs9IHRlbXBlcmF0dXJlICogZHg7XG4gICAgICB9XG4gICAgICBpZiAoTWF0aC5hYnMoZHkpID49IDEpIHtcbiAgICAgICAgeVZlbG9jaXRpZXNbYV0gLT0gdGVtcGVyYXR1cmUgKiBkeTtcbiAgICAgICAgeVZlbG9jaXRpZXNbYl0gKz0gdGVtcGVyYXR1cmUgKiBkeTtcbiAgICAgIH1cbiAgICAvLyAgIGVtYmVkWVthXSArPSBvZmZzZXRZICogdGVtcGVyYXR1cmU7XG4gICAgLy8gICBlbWJlZFlbYl0gLT0gb2Zmc2V0WSAqIHRlbXBlcmF0dXJlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCBjbHVzdGVyLmxlbmd0aDsgaWR4KyspIHtcbiAgICAgIGNvbnN0IHZlY1NpemUgPSBNYXRoLnNxcnQoeFZlbG9jaXRpZXNbaWR4XSAqIHhWZWxvY2l0aWVzW2lkeF0gKyB5VmVsb2NpdGllc1tpZHhdICogeVZlbG9jaXRpZXNbaWR4XSk7XG4gICAgICBpZiAodmVjU2l6ZSA+IDApIHtcbiAgICAgICAgZW1iZWRYW2lkeF0gKz0geFZlbG9jaXRpZXNbaWR4XSAvIHZlY1NpemUgKiB0ZW1wZXJhdHVyZTtcbiAgICAgICAgZW1iZWRZW2lkeF0gKz0geVZlbG9jaXRpZXNbaWR4XSAvIHZlY1NpemUgKiB0ZW1wZXJhdHVyZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBub3JtYWxpemVcbiAgbGV0IG1pblggPSBlbWJlZFhbMF07XG4gIGxldCBtaW5ZID0gZW1iZWRZWzBdO1xuICBsZXQgbWF4WCA9IGVtYmVkWFswXTtcbiAgbGV0IG1heFkgPSBlbWJlZFlbMF07XG4gIGZvciAobGV0IGlkeCA9IDE7IGlkeCA8IGNsdXN0ZXIubGVuZ3RoOyBpZHgrKykge1xuICAgIG1pblggPSBNYXRoLm1pbihtaW5YLCBlbWJlZFhbaWR4XSk7XG4gICAgbWluWSA9IE1hdGgubWluKG1pblksIGVtYmVkWVtpZHhdKTtcbiAgICBtYXhYID0gTWF0aC5tYXgobWF4WCwgZW1iZWRYW2lkeF0pO1xuICAgIG1heFkgPSBNYXRoLm1heChtYXhZLCBlbWJlZFlbaWR4XSk7XG4gIH1cbiAgbGV0IHJhbmdlWCA9IG1heFggLSBtaW5YO1xuICBsZXQgcmFuZ2VZID0gbWF4WSAtIG1pblk7XG4gIGlmIChyYW5nZVggPT09IDApXG4gICAgcmFuZ2VYID0gbWF4WDtcbiAgZm9yIChsZXQgaWR4ID0gMDsgaWR4IDwgY2x1c3Rlci5sZW5ndGg7IGlkeCsrKVxuICAgIGVtYmVkWFtpZHhdID0gKGVtYmVkWFtpZHhdIC0gbWluWCkgLyByYW5nZVggLyAyICsgMC41O1xuICBpZiAocmFuZ2VZID09PSAwKVxuICAgIHJhbmdlWSA9IG1heFk7XG4gIGZvciAobGV0IGlkeCA9IDA7IGlkeCA8IGNsdXN0ZXIubGVuZ3RoOyBpZHgrKylcbiAgICBlbWJlZFlbaWR4XSA9IChlbWJlZFlbaWR4XSAtIG1pblkpIC8gcmFuZ2VZIC8gMiArIDAuNTtcblxuICByZXR1cm4ge2VtYmVkWCwgZW1iZWRZfTtcbn1cbiJdfQ==","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n/**\n * colwise normalize the knn similarities\n * BE WARE, modifies the input array in place\n * @param device\n * @param knnSimilarities\n * @param offsets\n * @param nRows\n */\nexport function sparseKNNNoralizeColwise(device, knnSimilarities, offsets, nRows) {\n return __awaiter(this, void 0, void 0, function* () {\n const neededThreads = nRows;\n const workGroupThreadsPerDim = 10;\n const totalWorkgroupThreads = workGroupThreadsPerDim * workGroupThreadsPerDim;\n const neededWorkGroups = Math.ceil(neededThreads / totalWorkgroupThreads);\n const workGroupDim = Math.ceil(Math.sqrt(neededWorkGroups));\n const threadsPerDim = workGroupThreadsPerDim * workGroupDim;\n const module = device.createShaderModule({\n label: 'colwise-normalize',\n code: `\n @group(0) @binding(0) var<storage, read_write> knnSimilarities : array<f32>;\n @group(0) @binding(1) var<storage, read> offsets : array<u32>;\n @compute @workgroup_size(${workGroupThreadsPerDim}, ${workGroupThreadsPerDim}) fn normalize(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n let row = id.x;\n let col = id.y;\n let index = row * ${threadsPerDim} + col;\n if (index >= ${nRows}) {\n return;\n }\n let offsetBegin = offsets[index];\n let offsetEnd = offsets[index + 1];\n var sum = 0.0;\n if (offsetEnd - offsetBegin == 0) {\n return;\n }\n for (var i = offsetBegin; i < offsetEnd; i = i + 1) {\n sum = sum + knnSimilarities[i];\n }\n if (sum > 0.0) {\n for (var i = offsetBegin; i < offsetEnd; i = i + 1) {\n knnSimilarities[i] = knnSimilarities[i] / sum;\n }\n }\n }\n \n `,\n });\n const pipeline = device.createComputePipeline({\n label: 'hamming compute pipeline',\n layout: 'auto',\n compute: {\n module,\n entryPoint: 'normalize',\n },\n });\n const simmilaritiesBuffer = device.createBuffer({\n label: 'simmilarities info buffer',\n size: knnSimilarities.byteLength,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n new Float32Array(simmilaritiesBuffer.getMappedRange()).set(knnSimilarities);\n simmilaritiesBuffer.unmap();\n const offsetsBuffer = device.createBuffer({\n label: 'offsets info buffer',\n size: offsets.byteLength,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n new Uint32Array(offsetsBuffer.getMappedRange()).set(offsets);\n offsetsBuffer.unmap();\n const bindGroup = device.createBindGroup({\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n {\n binding: 0,\n resource: {\n buffer: simmilaritiesBuffer,\n },\n },\n {\n binding: 1,\n resource: {\n buffer: offsetsBuffer,\n },\n },\n ],\n });\n const commandEncoder = device.createCommandEncoder();\n const passEncoder = commandEncoder.beginComputePass();\n passEncoder.setPipeline(pipeline);\n passEncoder.setBindGroup(0, bindGroup);\n passEncoder.dispatchWorkgroups(workGroupDim, workGroupDim);\n passEncoder.end();\n const outSimilarityBuffer = device.createBuffer({\n label: 'out similarity buffer',\n size: knnSimilarities.byteLength,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n commandEncoder.copyBufferToBuffer(simmilaritiesBuffer, 0, outSimilarityBuffer, 0, knnSimilarities.byteLength);\n device.queue.submit([commandEncoder.finish()]);\n yield device.queue.onSubmittedWorkDone();\n yield outSimilarityBuffer.mapAsync(GPUMapMode.READ);\n const arrayBuffer = new Float32Array(outSimilarityBuffer.getMappedRange());\n knnSimilarities.set(arrayBuffer);\n outSimilarityBuffer.unmap();\n simmilaritiesBuffer.destroy();\n offsetsBuffer.destroy();\n outSimilarityBuffer.destroy();\n });\n}\n//# sourceMappingURL=colwise-normalize.js.map","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n/**\n * inflation operator in place\n */\nexport function inflate(knnSimilarities, factor = 2) {\n for (let i = 0; i < knnSimilarities.length; i++)\n knnSimilarities[i] = Math.pow(knnSimilarities[i], factor);\n}\nfunction getRowIndexes(offsets) {\n const res = new Uint32Array(offsets[offsets.length - 1]);\n for (let i = 0; i < offsets.length - 1; i++) {\n for (let j = offsets[i]; j < offsets[i + 1]; j++)\n res[j] = i;\n }\n return res;\n}\n// this implementation is not looking at already zeroed out values, and only looks at live cells.\nexport function expandNoRevive(device, knnSimilarities, knnIndexes, offsets, nRows) {\n return __awaiter(this, void 0, void 0, function* () {\n const neededThreads = 90000;\n const workGroupThreadsPerDim = 10;\n const totalWorkgroupThreads = workGroupThreadsPerDim * workGroupThreadsPerDim;\n const neededWorkGroups = Math.ceil(neededThreads / totalWorkgroupThreads);\n const workGroupDim = Math.ceil(Math.sqrt(neededWorkGroups));\n const threadsPerDim = workGroupThreadsPerDim * workGroupDim;\n const order = Math.floor(Math.max(Math.log10(nRows), 2)) + 1;\n // minimum value after expansion.\n const pruneValue = Math.pow(10, -order);\n const outKNNSimilarities = new Float32Array(knnSimilarities.length);\n const module = device.createShaderModule({\n label: 'expand',\n code: `\n struct SparseKNN {\n knnSimilarities: array<f32, ${knnSimilarities.length}>,\n knnIndexes: array<u32, ${knnIndexes.length}>,\n offsets: array<u32, ${offsets.length}>,\n rowIndexes: array<u32, ${knnIndexes.length}>,\n }\n\n @group(0) @binding(0) var<storage, read_write> sparseKNN: SparseKNN;\n @group(0) @binding(1) var<storage, read_write> resultSimBlock: array<f32, ${neededThreads}>;\n @group(0) @binding(2) var<storage, read_write> startAt: u32;\n @compute @workgroup_size(${workGroupThreadsPerDim}, ${workGroupThreadsPerDim}) fn expand(\n @builtin(global_invocation_id) id: vec3<u32>,\n ) {\n let col = id.x;\n let row = id.y;\n let index = row * ${threadsPerDim} + col;\n if (index >= ${neededThreads}) {\n return;\n }\n let workingIndex = index + startAt;\n if (workingIndex >= ${knnIndexes.length}) {\n return;\n }\n \n let rowIdx = sparseKNN.rowIndexes[workingIndex];\n let colIdx = sparseKNN.knnIndexes[workingIndex];\n let offsetBeginRow = sparseKNN.offsets[rowIdx];\n let offsetEndRow = sparseKNN.offsets[rowIdx + 1];\n let offsetBeginCol = sparseKNN.offsets[colIdx];\n let offsetEndCol = sparseKNN.offsets[colIdx + 1];\n var sum = 0.0;\n for (var i = offsetBeginRow; i < offsetEndRow; i = i + 1) {\n for(var j = offsetBeginCol; j < offsetEndCol; j = j + 1) {\n if (sparseKNN.knnIndexes[i] == sparseKNN.knnIndexes[j]) {\n sum = sum + sparseKNN.knnSimilarities[i] * sparseKNN.knnSimilarities[j];\n break;\n }\n }\n }\n if (sum > ${pruneValue}) {\n resultSimBlock[index] = sum;\n } else {\n resultSimBlock[index] = 0.0;\n }\n }\n `\n });\n const pipeline = device.createComputePipeline({\n label: 'expand compute pipeline',\n layout: 'auto',\n compute: {\n module: module,\n entryPoint: 'expand',\n },\n });\n const sparseKNNBuffer32Size = knnSimilarities.length + knnIndexes.length + offsets.length + knnIndexes.length;\n let sparseKNNBufferByteSize = sparseKNNBuffer32Size * 4;\n const remainder = sparseKNNBufferByteSize & 15;\n if (remainder !== 0)\n sparseKNNBufferByteSize += 16 - remainder;\n const sparseKNNBuffer = device.createBuffer({\n label: 'sparse knn buffer',\n size: sparseKNNBufferByteSize,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n const sparseKNNArrayBuffer = sparseKNNBuffer.getMappedRange();\n // set similarities\n new Float32Array(sparseKNNArrayBuffer, 0, knnSimilarities.length).set(knnSimilarities);\n // set indexes\n new Uint32Array(sparseKNNArrayBuffer, knnSimilarities.length * 4, knnIndexes.length).set(knnIndexes);\n // set offsets\n new Uint32Array(sparseKNNArrayBuffer, (knnSimilarities.length + knnIndexes.length) * 4, offsets.length).set(offsets);\n // set row indexes\n const rowIndexes = getRowIndexes(offsets);\n new Uint32Array(sparseKNNArrayBuffer, (knnSimilarities.length + knnIndexes.length + offsets.length) * 4, rowIndexes.length).set(rowIndexes);\n sparseKNNBuffer.unmap();\n const startBuffer = device.createBuffer({\n label: 'start end buffer',\n size: 4,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n mappedAtCreation: true,\n });\n new Uint32Array(startBuffer.getMappedRange()).set([0]);\n startBuffer.unmap();\n const resultBlockBuffer = device.createBuffer({\n label: 'result block buffer',\n size: neededThreads * 4,\n usage: GPUBufferUsage.STORAGE |\n GPUBufferUsage.COPY_SRC |\n GPUBufferUsage.COPY_DST,\n });\n const bindGroup = device.createBindGroup({\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: sparseKNNBuffer } },\n { binding: 1, resource: { buffer: resultBlockBuffer } },\n { binding: 2, resource: { buffer: startBuffer } },\n ],\n });\n const outBlockBuffer = device.createBuffer({\n label: 'out block buffer',\n size: resultBlockBuffer.size,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST\n });\n for (let i = 0; i < Math.ceil(knnIndexes.length / neededThreads); i++) {\n const start = i * neededThreads;\n const curLength = Math.min(neededThreads, knnIndexes.length - start);\n device.queue.writeBuffer(startBuffer, 0, new Uint32Array([start]));\n const encoder = device.createCommandEncoder({\n label: 'expand encoder',\n });\n const pass = encoder.beginComputePass({\n label: 'expand compute pass',\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(workGroupDim, workGroupDim);\n pass.end();\n encoder.copyBufferToBuffer(resultBlockBuffer, 0, outBlockBuffer, 0, outBlockBuffer.size);\n device.queue.submit([encoder.finish()]);\n //console.time('onSubmittedWorkDone');\n yield device.queue.onSubmittedWorkDone();\n //console.timeEnd('onSubmittedWorkDone');\n yield outBlockBuffer.mapAsync(GPUMapMode.READ);\n const outBlock = new Float32Array(outBlockBuffer.getMappedRange(), 0, curLength);\n //console.time('fillout');\n outKNNSimilarities.set(outBlock, start);\n //console.timeEnd('fillout');\n outBlockBuffer.unmap();\n }\n // destroy\n sparseKNNBuffer.destroy();\n startBuffer.destroy();\n resultBlockBuffer.destroy();\n outBlockBuffer.destroy();\n return { KNNIndexes: knnIndexes, KNNSimilarities: outKNNSimilarities, indexOffsets: offsets };\n });\n}\n//# sourceMappingURL=inflate-expand.js.map","import { toOffsetForm } from '../umap/utils';\nexport function countOccurancesAddLoops(sparseMatrix, nRows) {\n const res = new Uint32Array(nRows);\n for (let i = 0; i < sparseMatrix.i.length; i++) {\n res[sparseMatrix.i[i]]++;\n res[sparseMatrix.j[i]]++;\n }\n // add loops\n for (let i = 0; i < nRows; i++)\n res[i]++;\n return res;\n}\n/**\n * BE WARE, this function is ment for half sparse matrices only!!!\n * @param sparseMatrix\n * @param nRows\n * @returns\n */\nexport function toSparseKNNSimilarityForm(sparseMatrix, nRows) {\n const occurenceCount = countOccurancesAddLoops(sparseMatrix, nRows);\n const offsetForm = toOffsetForm(occurenceCount);\n const insertCounter = new Uint32Array(nRows).fill(1); // for counting how many things we inserted into the knn arrays.\n // we initialize these counters to one because first we insert the self loops\n // dont be confused by the name knn, k here is variable, its just the thing that in this form, we know that at index i\n // we have some k(variable) ammount of sparse neigbours\n // we know for a fact that sparse matrix will not contain any duplicates, we add nRows to account for self loops\n const KNNIndexes = new Uint32Array(sparseMatrix.i.length * 2 + nRows);\n const KNNSimilarities = new Float32Array(sparseMatrix.i.length * 2 + nRows);\n // insert self loops at the start of each offset\n for (let i = 0; i < nRows; i++) {\n KNNIndexes[offsetForm[i]] = i;\n KNNSimilarities[offsetForm[i]] = 1;\n }\n for (let i = 0; i < sparseMatrix.i.length; i++) {\n const row = sparseMatrix.i[i];\n const col = sparseMatrix.j[i];\n const similarity = 1 - sparseMatrix.distance[i];\n KNNIndexes[offsetForm[row] + insertCounter[row]] = col;\n KNNSimilarities[offsetForm[row] + insertCounter[row]] = similarity;\n insertCounter[row]++;\n KNNIndexes[offsetForm[col] + insertCounter[col]] = row;\n KNNSimilarities[offsetForm[col] + insertCounter[col]] = similarity;\n insertCounter[col]++;\n }\n return { KNNIndexes, KNNSimilarities, indexOffsets: offsetForm };\n}\nexport function knnToSparseForm(knnIndexes, knnSims) {\n const lengths = knnIndexes.map((x) => x.length);\n const totalLength = lengths.reduce((a, b) => a + b, 0);\n const offsets = toOffsetForm(lengths);\n const outIndexes = new Uint32Array(totalLength);\n const outSims = new Float32Array(totalLength);\n for (let i = 0; i < knnIndexes.length; i++) {\n outIndexes.set(knnIndexes[i], offsets[i]);\n outSims.set(knnSims[i], offsets[i]);\n }\n return { KNNIndexes: outIndexes, KNNSimilarities: outSims, indexOffsets: offsets };\n}\n//# sourceMappingURL=utils.js.map","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nimport { levenbergMarquardt } from 'ml-levenberg-marquardt';\nexport function linear(x1, x2, n) {\n const step = (x2 - x1) / (n - 1);\n return Array.from({ length: n }, (_, i) => x1 + step * i);\n}\n/**\n * Fit a, b params for the differentiable curve used in lower\n * dimensional fuzzy simplicial complex construction. We want the\n * smooth curve (from a pre-defined family with simple gradient) that\n * best matches an offset exponential decay.\n */\nexport function findABParams(spread, minDist) {\n const curve = ([a, b]) => (x) => {\n return 1.0 / (1.0 + a * Math.pow(x, (2 * b)));\n };\n const xv = linear(0, spread * 3, 300)\n .map((val) => (val < minDist ? 1.0 : val));\n const yv = new Array(xv.length).fill(0).map((val, index) => {\n const gte = xv[index] >= minDist;\n return gte ? Math.exp(-(xv[index] - minDist) / spread) : val;\n });\n const initialValues = [0.5, 0.5];\n const data = { x: xv, y: yv };\n // Default options for the algorithm (from github example)\n const options = {\n damping: 1.5,\n initialValues,\n gradientDifference: 10e-2,\n maxIterations: 100,\n errorTolerance: 10e-3,\n };\n // eslint-disable-next-line new-cap\n const { parameterValues } = levenbergMarquardt(data, curve, options);\n const [a, b] = parameterValues;\n return { a, b };\n}\n/**\n * heuristic for number of epochs of umap, differs from cpu version, because of the way gpu passes data\n * @param entryLen number of entries\n * @returns\n */\nexport function getNEpochs(entryLen) {\n //\n const length = entryLen;\n if (length <= 2500)\n return 1000;\n else if (length <= 5000)\n return 800;\n else if (length <= 7500)\n return 650;\n else\n return 400;\n}\n/** helper function that transforms array of sizes to offset form */\nexport function toOffsetForm(ar) {\n const res = new Uint32Array(ar.length + 1);\n let offset = 0;\n for (let i = 0; i < ar.length; i++) {\n res[i] = offset;\n offset += ar[i];\n }\n res[ar.length] = offset;\n return res;\n}\n/** multiplies flat representation of sparse knn info by scalar.\n * also no point of doing this on gpu, can be done on cpu pretty quickly.\n * if there will be need for it, it can be done on gpu as well very very easily.\n * @param values values array\n * @param scalar\n */\nexport function multiplyScalar(values, scalar) {\n for (let i = 0; i < values.length; i++)\n values[i] = values[i] * scalar;\n}\n/**\n * generate transpose of knn from the transposition info taken from sparse knn info\n * using this information avoids billions of array.push calls, is much cleaner, allows typed array use and is faster.\n * no point of doing this on gpu, can be done on cpu as we already have all the info needed.\n * @param knnIndexes\n * @param knnDistances\n * @param knnSparseInfo\n * @param knnSize\n * @returns\n */\nexport function transposeKNN(knnIndexes, knnDistances, knnSparseInfo, knnSize = 15) {\n return __awaiter(this, void 0, void 0, function* () {\n const numOfEntries = knnIndexes.length;\n const fullKnnEntrySize = knnSize * numOfEntries;\n const transposeSizes = knnSparseInfo.resultTransposeSizesArray;\n const transposeOffsets = toOffsetForm(transposeSizes);\n const offsetsCopy = new Uint32Array(transposeOffsets.length);\n offsetsCopy.set(transposeOffsets); // will be used for dynamic indexing\n const transposeKNNIndexes = new Int32Array(fullKnnEntrySize).fill(0);\n const transposeKNNDistances = new Float32Array(fullKnnEntrySize).fill(0);\n for (let i = 0; i < numOfEntries; i++) {\n for (let j = 0; j < knnSize; j++) {\n const otherIndex = knnIndexes[i][j];\n const otherIndexOffset = offsetsCopy[otherIndex];\n transposeKNNIndexes[otherIndexOffset] = i;\n transposeKNNDistances[otherIndexOffset] = knnDistances[i][j];\n offsetsCopy[otherIndex] += 1;\n }\n }\n return { transposeKNNIndexes, transposeKNNDistances, transposeOffsets };\n });\n}\n//# sourceMappingURL=utils.js.map","// eslint-disable-next-line @typescript-eslint/unbound-method\nconst toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array, except those that contain bigint values).\n *\n * @param value - Object to check.\n * @returns True if the object is an array or a typed array.\n */\nexport function isAnyArray(value) {\n const tag = toString.call(value);\n return tag.endsWith('Array]') && !tag.includes('Big');\n}\n//# sourceMappingURL=index.js.map","import { bioLayout } from './bio-layout';\nimport { markovClusterWebGPU } from '@datagrok-libraries/math/src/webGPU/MCL/MCL-webGPU';\nexport const defaultMCLOptions = {\n expandFactor: 2,\n maxIterations: 5,\n inflateFactor: 2,\n multFactor: 1,\n};\nexport class MCLSparseReducer {\n constructor(opts = {}) {\n this._options = { ...defaultMCLOptions, ...opts };\n }\n async transform(sparseMatrix, nRows) {\n // testWorkerMultiply();\n // return new Int32Array(nRows);\n let sparseObject = this.toObjectForm(sparseMatrix);\n if (this._options.maxIterations > 0) {\n this.addLoops(sparseObject, nRows);\n this.normalize(sparseObject);\n for (let i = 0; i < this._options.maxIterations; i++) {\n sparseObject = this.expand(sparseObject, nRows);\n this.inflate(sparseObject);\n this.normalize(sparseObject);\n }\n }\n const { clusters, is, js } = this.assignClusters(sparseObject, nRows);\n this.correctClusters(clusters);\n const embeddings = await this.layout(clusters, sparseObject, nRows);\n return { clusters, embedX: embeddings.embedX, embedY: embeddings.embedY, is, js };\n }\n async transformWebGPU(sparseMatrix, nRows) {\n if (this._options.maxIterations === 0)\n return this.transform(sparseMatrix, nRows);\n const mclRes = await markovClusterWebGPU(sparseMatrix, nRows, this._options.maxIterations, this._options.inflateFactor);\n const sparseObject = this.csrToSparseObject(mclRes, nRows);\n const { clusters, is, js } = this.assignClusters(sparseObject, nRows);\n this.correctClusters(clusters);\n const embeddings = await this.layout(clusters, sparseObject, nRows);\n return { clusters, embedX: embeddings.embedX, embedY: embeddings.embedY, is, js };\n }\n correctClusters(clusters) {\n const clusterSizeMap = {};\n for (const cluster of clusters) {\n if (!clusterSizeMap[cluster])\n clusterSizeMap[cluster] = 0;\n clusterSizeMap[cluster]++;\n }\n const sortedIndexes = Object.keys(clusterSizeMap).map(Number).sort((a, b) => clusterSizeMap[b] - clusterSizeMap[a]);\n const clusterMap = {};\n sortedIndexes.forEach((clusterIdx, i) => clusterMap[clusterIdx] = i + 1);\n for (let i = 0; i < clusters.length; i++)\n clusters[i] = clusterMap[clusters[i]];\n // let curCluster = 1;\n // for (let i = 0; i < clusters.length; i++) {\n // if (!clusterMap[clusters[i]]) {\n // clusterMap[clusters[i]] = curCluster;\n // clusters[i] = curCluster;\n // curCluster++;\n // } else {\n // clusters[i] = clusterMap[clusters[i]];\n // }\n // }\n }\n csrToSparseObject(mclRes, nRows) {\n const order = Math.floor(Math.max(Math.log10(nRows), 2)) + 1;\n const minOrder = 1 / Math.pow(10, order);\n const sparseObject = {};\n for (let i = 0; i < nRows; i++) {\n sparseObject[i] = {};\n for (let k = mclRes.indexOffsets[i]; k < mclRes.indexOffsets[i + 1]; k++) {\n const j = mclRes.KNNIndexes[k];\n if (j <= i || mclRes.KNNSimilarities[k] < minOrder)\n continue;\n sparseObject[i][j] = mclRes.KNNSimilarities[k];\n }\n }\n return sparseObject;\n }\n async layout(clusters, sparseMatrix, nRows) {\n const embedX = new Float32Array(nRows).fill(0);\n const embedY = new Float32Array(nRows).fill(0);\n const clusterMap = {};\n clusters.forEach((cluster, i) => {\n if (!clusterMap[cluster])\n clusterMap[cluster] = [];\n clusterMap[cluster].push(i);\n });\n // const nClusters = Object.keys(clusterMap).length;\n // const perRow = Math.floor(Math.sqrt(nClusters));\n let clusterNum = 0;\n const sortedClusterNames = Object.keys(clusterMap);\n sortedClusterNames.sort((a, b) => clusterMap[b].length - clusterMap[a].length);\n let perRow = 6;\n let yOffset = 0;\n const layoutSize = 5;\n for (const clusterName of sortedClusterNames) {\n const cluster = clusterMap[clusterName];\n const embeddings = await bioLayout(cluster, sparseMatrix, 0.001);\n if (clusterNum === Math.ceil(perRow / 1.5)) {\n clusterNum = 0;\n yOffset += layoutSize / perRow;\n perRow = Math.ceil(perRow * 1.5);\n }\n const offsetX = ((clusterNum % perRow) * layoutSize / perRow) * 1.5;\n // const offsetY = Math.floor(clusterNum / perRow) * 2;\n for (let i = 0; i < embeddings.embedX.length; i++) {\n embedX[cluster[i]] = embeddings.embedX[i] * layoutSize / perRow + offsetX;\n embedY[cluster[i]] = embeddings.embedY[i] * layoutSize / perRow + yOffset;\n }\n clusterNum++;\n }\n return { embedX, embedY };\n }\n mergeClusters(clusters, i, j) {\n const iCluster = clusters[i];\n const jCluster = clusters[j];\n for (let k = 0; k < clusters.length; k++) {\n if (clusters[k] === jCluster)\n clusters[k] = iCluster;\n }\n }\n assignClusters(sparseMatrix, nRows) {\n let clusterNum = 0;\n const is = [];\n const js = [];\n const order = Math.floor(Math.max(Math.log10(nRows), 2)) + 1;\n const minOrder = Math.pow(10, order);\n const clusters = new Array(nRows).fill(-1);\n for (const i of Object.keys(sparseMatrix)) {\n for (const j of Object.keys(sparseMatrix[i])) {\n if (Math.round(sparseMatrix[i][j] * minOrder) / minOrder > 0 &&\n sparseMatrix[i][j] !== Number(i) && Number(j) > Number(i)) {\n is.push(Number(i));\n js.push(Number(j));\n if (clusters[Number(i)] !== -1 && clusters[Number(j)] !== -1) {\n if (clusters[Number(i)] !== clusters[Number(j)])\n this.mergeClusters(clusters, Number(i), Number(j));\n }\n else if (clusters[Number(i)] !== -1) {\n clusters[Number(j)] = clusters[Number(i)];\n }\n else if (clusters[Number(j)] !== -1) {\n clusters[Number(i)] = clusters[Number(j)];\n }\n else {\n clusterNum++;\n clusters[Number(i)] = clusterNum;\n clusters[Number(j)] = clusterNum;\n }\n }\n }\n }\n for (let i = 0; i < clusters.length; i++) {\n if (clusters[i] === -1) {\n clusterNum++;\n clusters[i] = clusterNum;\n }\n }\n return { clusters, is: new Uint32Array(is), js: new Uint32Array(js) };\n }\n /** same as assign clusters but working on the level of CSR format returned from webGPU */\n assignClustersCSR(mclRes, nRows) {\n let clusterNum = 0;\n const is = [];\n const js = [];\n const order = Math.floor(Math.max(Math.log10(nRows), 2)) + 1;\n const minOrder = 1 / Math.pow(10, order);\n const clusters = new Array(nRows).fill(-1);\n const correctedOffsets = new Uint32Array(nRows + 1);\n let offsetCounter = 0;\n correctedOffsets[0] = 0;\n for (let i = 0; i < nRows; i++) {\n for (let k = mclRes.indexOffsets[i]; k < mclRes.indexOffsets[i + 1]; k++) {\n const j = mclRes.KNNIndexes[k];\n if (j <= i || mclRes.KNNSimilarities[k] <= minOrder)\n continue;\n is.push(i);\n js.push(j);\n offsetCounter++;\n if (clusters[i] !== -1 && clusters[j] !== -1) {\n if (clusters[i] !== clusters[j])\n this.mergeClusters(clusters, i, j);\n }\n else if (clusters[i] !== -1) {\n clusters[j] = clusters[i];\n }\n else if (clusters[j] !== -1) {\n clusters[i] = clusters[j];\n }\n else {\n clusterNum++;\n clusters[i] = clusterNum;\n clusters[j] = clusterNum;\n }\n }\n correctedOffsets[i + 1] = offsetCounter;\n }\n for (let i = 0; i < clusters.length; i++) {\n if (clusters[i] === -1) {\n clusterNum++;\n clusters[i] = clusterNum;\n }\n }\n return { clusters, is: new Uint32Array(is), js: new Uint32Array(js), correctedOffsets };\n }\n toObjectForm(sparseMatrix) {\n const sparseObject = {};\n for (let i = 0; i < sparseMatrix.i.length; i++) {\n if (!sparseObject[sparseMatrix.i[i]])\n sparseObject[sparseMatrix.i[i]] = {};\n sparseObject[sparseMatrix.i[i]][sparseMatrix.j[i]] = 1 - sparseMatrix.distance[i];\n if (!sparseObject[sparseMatrix.j[i]])\n sparseObject[sparseMatrix.j[i]] = {};\n sparseObject[sparseMatrix.j[i]][sparseMatrix.i[i]] = 1 - sparseMatrix.distance[i];\n }\n return sparseObject;\n }\n addLoops(sparseObject, nRows) {\n for (let i = 0; i < nRows; i++) {\n if (!sparseObject[i])\n sparseObject[i] = {};\n sparseObject[i][i] = this._options.multFactor;\n }\n }\n normalize(sparseObject) {\n for (const i of Object.keys(sparseObject)) {\n const row = sparseObject[i];\n let sum = 0;\n for (const j of Object.keys(row))\n sum += row[j];\n if (sum === 0)\n continue;\n for (const j of Object.keys(row))\n sparseObject[i][j] /= sum;\n }\n }\n expand(sparseObject, nRows) {\n const expandedObject = {};\n const order = Math.floor(Math.max(Math.log10(nRows), 2)) + 1;\n const minOrder = Math.pow(10, order);\n for (let i = 0; i < nRows; i++) {\n if (!sparseObject[i])\n continue;\n // const row = sparseObject[i];\n expandedObject[i] ?? (expandedObject[i] = {});\n for (let j = i; j < nRows; j++) {\n if (!sparseObject[i]?.[j])\n continue;\n const val = this.getExpandValue(sparseObject, i, j); //pruning step\n if (Math.round(val * minOrder) / minOrder > 0) {\n expandedObject[i][j] = val;\n if (!expandedObject[j])\n expandedObject[j] = {};\n expandedObject[j][i] = val;\n }\n }\n }\n return expandedObject;\n }\n // private prune(row: SparseMatrixObject[number]) {\n // }\n inflate(sparseObject) {\n for (const i of Object.keys(sparseObject)) {\n const row = sparseObject[i];\n for (const j of Object.keys(row))\n sparseObject[i][j] = Math.pow(sparseObject[i][j], this._options.inflateFactor);\n }\n }\n getExpandValue(sparseObject, i, j) {\n let val = 0;\n const currentIndexes = Object.keys(sparseObject[i] ?? {});\n const otherIndexes = Object.keys(sparseObject[j] ?? {});\n for (const k of currentIndexes) {\n if (otherIndexes.includes(k))\n val += sparseObject[i][k] * sparseObject[j][k];\n }\n return val;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFyY292LWNsdXN0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYXJjb3YtY2x1c3Rlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sY0FBYyxDQUFDO0FBR3ZDLE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLG9EQUFvRCxDQUFDO0FBQ3ZGLE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFlO0lBQzNDLFlBQVksRUFBRSxDQUFDO0lBQ2YsYUFBYSxFQUFFLENBQUM7SUFDaEIsYUFBYSxFQUFFLENBQUM7SUFDaEIsVUFBVSxFQUFFLENBQUM7Q0FDZCxDQUFDO0FBRUYsTUFBTSxPQUFPLGdCQUFnQjtJQUczQixZQUFZLE9BQTRCLEVBQUU7UUFDeEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFDLEdBQUcsaUJBQWlCLEVBQUUsR0FBRyxJQUFJLEVBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRU0sS0FBSyxDQUFDLFNBQVMsQ0FBQyxZQUFnQyxFQUFFLEtBQWE7UUFDcEUsd0JBQXdCO1FBQ3hCLGdDQUFnQztRQUNoQyxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ25ELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUM3QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDckQsWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUNoRCxJQUFJLENBQUMsT0FBTyxDQUFD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LEVBQUUsQ0FBTTtRQUNyRSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDWixNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMxRCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN4RCxLQUFLLE1BQU0sQ0FBQyxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQy9CLElBQUksWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQzFCLEdBQUcsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBUSxDQUFDLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQVEsQ0FBQyxDQUFDO1FBQ2pFLENBQUM7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7U3BhcnNlTWF0cml4UmVzdWx0fSBmcm9tICcuLi9kaXN0YW5jZS1tYXRyaXgvc3BhcnNlLW1hdHJpeC1zZXJ2aWNlJztcbmltcG9ydCB7YmlvTGF5b3V0fSBmcm9tICcuL2Jpby1sYXlvdXQnO1xuaW1wb3J0IHtNQ0xPcHRpb25zLCBTcGFyc2VNYXRyaXhPYmplY3R9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHtNQ0xPcFJldHVyblR5cGV9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvbWF0aC9zcmMvd2ViR1BVL01DTC90eXBlcyc7XG5pbXBvcnQge21hcmtvdkNsdXN0ZXJXZWJHUFV9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvbWF0aC9zcmMvd2ViR1BVL01DTC9NQ0wtd2ViR1BVJztcbmV4cG9ydCBjb25zdCBkZWZhdWx0TUNMT3B0aW9uczogTUNMT3B0aW9ucyA9IHtcbiAgZXhwYW5kRmFjdG9yOiAyLFxuICBtYXhJdGVyYXRpb25zOiA1LFxuICBpbmZsYXRlRmFjdG9yOiAyLFxuICBtdWx0RmFjdG9yOiAxLFxufTtcblxuZXhwb3J0IGNsYXNzIE1DTFNwYXJzZVJlZHVjZXIge1xuICBwcml2YXRlIF9vcHRpb25zOiBNQ0xPcHRpb25zO1xuXG4gIGNvbnN0cnVjdG9yKG9wdHM6IFBhcnRpYWw8TUNMT3B0aW9ucz4gPSB7fSkge1xuICAgIHRoaXMuX29wdGlvbnMgPSB7Li4uZGVmYXVsdE1DTE9wdGlvbnMsIC4uLm9wdHN9O1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHRyYW5zZm9ybShzcGFyc2VNYXRyaXg6IFNwYXJzZU1hdHJpeFJlc3VsdCwgblJvd3M6IG51bWJlcikge1xuICAgIC8vIHRlc3RXb3JrZXJNdWx0aXBseSgpO1xuICAgIC8vIHJldHVybiBuZXcgSW50MzJBcnJheShuUm93cyk7XG4gICAgbGV0IHNwYXJzZU9iamVjdCA9IHRoaXMudG9PYmplY3RGb3JtKHNwYXJzZU1hdHJpeCk7XG4gICAgaWYgKHRoaXMuX29wdGlvbnMubWF4SXRlcmF0aW9ucyA+IDApIHtcbiAgICAgIHRoaXMuYWRkTG9vcHMoc3BhcnNlT2JqZWN0LCBuUm93cyk7XG4gICAgICB0aGlzLm5vcm1hbGl6ZShzcGFyc2VPYmplY3QpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9vcHRpb25zLm1heEl0ZXJhdGlvbnM7IGkrKykge1xuICAgICAgICBzcGFyc2VPYmplY3QgPSB0aGlzLmV4cGFuZChzcGFyc2VPYmplY3QsIG5Sb3dzKTtcbiAgICAgICAgdGhpcy5pbmZsYXRlKHNwYXJzZU9iamVjdCk7XG4gICAgICAgIHRoaXMubm9ybWFsaXplKHNwYXJzZU9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHtjbHVzdGVycywgaXMsIGpzfSA9IHRoaXMuYXNzaWduQ2x1c3RlcnMoc3BhcnNlT2JqZWN0LCBuUm93cyk7XG4gICAgdGhpcy5jb3JyZWN0Q2x1c3RlcnMoY2x1c3RlcnMpO1xuICAgIGNvbnN0IGVtYmVkZGluZ3MgPSBhd2FpdCB0aGlzLmxheW91dChjbHVzdGVycywgc3BhcnNlT2JqZWN0LCBuUm93cyk7XG4gICAgcmV0dXJuIHtjbHVzdGVycywgZW1iZWRYOiBlbWJlZGRpbmdzLmVtYmVkWCwgZW1iZWRZOiBlbWJlZGRpbmdzLmVtYmVkWSwgaXMsIGpzfTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyB0cmFuc2Zvcm1XZWJHUFUoc3BhcnNlTWF0cml4OiBTcGFyc2VNYXRyaXhSZXN1bHQsIG5Sb3dzOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5fb3B0aW9ucy5tYXhJdGVyYXRpb25zID09PSAwKVxuICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtKHNwYXJzZU1hdHJpeCwgblJvd3MpO1xuXG4gICAgY29uc3QgbWNsUmVzID0gYXdhaXQgbWFya292Q2x1c3RlcldlYkdQVShcbiAgICAgIHNwYXJzZU1hdHJpeCwgblJvd3MsIHRoaXMuX29wdGlvbnMubWF4SXRlcmF0aW9ucywgdGhpcy5fb3B0aW9ucy5pbmZsYXRlRmFjdG9yXG4gICAgKTtcbiAgICBjb25zdCBzcGFyc2VPYmplY3QgPSB0aGlzLmNzclRvU3BhcnNlT2JqZWN0KG1jbFJlcywgblJvd3MpO1xuICAgIGNvbnN0IHtjbHVzdGVycywgaXMsIGpzfSA9IHRoaXMuYXNzaWduQ2x1c3RlcnMoc3BhcnNlT2JqZWN0LCBuUm93cyk7XG4gICAgdGhpcy5jb3JyZWN0Q2x1c3RlcnMoY2x1c3RlcnMpO1xuICAgIGNvbnN0IGVtYmVkZGluZ3MgPSBhd2FpdCB0aGlzLmxheW91dChjbHVzdGVycywgc3BhcnNlT2JqZWN0LCBuUm93cyk7XG4gICAgcmV0dXJuIHtjbHVzdGVycywgZW1iZWRYOiBlbWJlZGRpbmdzLmVtYmVkWCwgZW1iZWRZOiBlbWJlZGRpbmdzLmVtYmVkWSwgaXMsIGpzfTtcbiAgfVxuXG4gIHByaXZhdGUgY29ycmVjdENsdXN0ZXJzKGNsdXN0ZXJzOiBudW1iZXJbXSkge1xuICAgIGNvbnN0IGNsdXN0ZXJTaXplTWFwOiB7W186IG51bWJlcl06IG51bWJlcn0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGNsdXN0ZXIgb2YgY2x1c3RlcnMpIHtcbiAgICAgIGlmICghY2x1c3RlclNpemVNYXBbY2x1c3Rlcl0pXG4gICAgICAgIGNsdXN0ZXJTaXplTWFwW2NsdXN0ZXJdID0gMDtcbiAgICAgIGNsdXN0ZXJTaXplTWFwW2NsdXN0ZXJdKys7XG4gICAgfVxuICAgIGNvbnN0IHNvcnRlZEluZGV4ZXMgPSBPYmplY3Qua2V5cyhjbHVzdGVyU2l6ZU1hcCkubWFwKE51bWJlcikuc29ydCgoYSwgYikgPT4gY2x1c3RlclNpemVNYXBbYl0gLSBjbHVzdGVyU2l6ZU1hcFthXSk7XG4gICAgY29uc3QgY2x1c3Rlck1hcDoge1tfOiBudW1iZXJdOiBudW1iZXJ9ID0ge307XG4gICAgc29ydGVkSW5kZXhlcy5mb3JFYWNoKChjbHVzdGVySWR4LCBpKSA9PiBjbHVzdGVyTWFwW2NsdXN0ZXJJZHhdID0gaSArIDEpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2x1c3RlcnMubGVuZ3RoOyBpKyspXG4gICAgICBjbHVzdGVyc1tpXSA9IGNsdXN0ZXJNYXBbY2x1c3RlcnNbaV1dO1xuICAgIC8vIGxldCBjdXJDbHVzdGVyID0gMTtcbiAgICAvLyBmb3IgKGxldCBpID0gMDsgaSA8IGNsdXN0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgLy8gICBpZiAoIWNsdXN0ZXJNYXBbY2x1c3RlcnNbaV1dKSB7XG4gICAgLy8gICAgIGNsdXN0ZXJNYXBbY2x1c3RlcnNbaV1dID0gY3VyQ2x1c3RlcjtcbiAgICAvLyAgICAgY2x1c3RlcnNbaV0gPSBjdXJDbHVzdGVyO1xuICAgIC8vICAgICBjdXJDbHVzdGVyKys7XG4gICAgLy8gICB9IGVsc2Uge1xuICAgIC8vICAgICBjbHVzdGVyc1tpXSA9IGNsdXN0ZXJNYXBbY2x1c3RlcnNbaV1dO1xuICAgIC8vICAgfVxuICAgIC8vIH1cbiAgfVxuXG4gIHByaXZhdGUgY3NyVG9TcGFyc2VPYmplY3QobWNsUmVzOiBNQ0xPcFJldHVyblR5cGUsIG5Sb3dzOiBudW1iZXIpIHtcbiAgICBjb25zdCBvcmRlciA9IE1hdGguZmxvb3IoTWF0aC5tYXgoTWF0aC5sb2cxMChuUm93cyksIDIpKSArIDE7XG4gICAgY29uc3QgbWluT3JkZXIgPSAxIC8gTWF0aC5wb3coMTAsIG9yZGVyKTtcbiAgICBjb25zdCBzcGFyc2VPYmplY3Q6IFNwYXJzZU1hdHJpeE9iamVjdCA9IHt9O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgblJvd3M7IGkrKykge1xuICAgICAgc3BhcnNlT2JqZWN0W2ldID0ge307XG4gICAgICBmb3IgKGxldCBrID0gbWNsUmVzLmluZGV4T2Zmc2V0c1tpXTsgayA8IG1jbFJlcy5pbmRleE9mZnNldHNbaSArIDFdOyBrKyspIHtcbiAgICAgICAgY29uc3QgaiA9IG1jbFJlcy5LTk5JbmRleGVzW2tdO1xuICAgICAgICBpZiAoaiA8PSBpIHx8IG1jbFJlcy5LTk5TaW1pbGFyaXRpZXNba10gPCBtaW5PcmRlcilcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgc3BhcnNlT2JqZWN0W2ldW2pdID0gbWNsUmVzLktOTlNpbWlsYXJpdGllc1trXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNwYXJzZU9iamVjdDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbGF5b3V0KGNsdXN0ZXJzOiBudW1iZXJbXSwgc3BhcnNlTWF0cml4OiBTcGFyc2VNYXRyaXhPYmplY3QsIG5Sb3dzOiBudW1iZXIpIHtcbiAgICBjb25zdCBlbWJlZFggPSBuZXcgRmxvYXQzMkFycmF5KG5Sb3dzKS5maWxsKDApO1xuICAgIGNvbnN0IGVtYmVkWSA9IG5ldyBGbG9hdDMyQXJyYXkoblJvd3MpLmZpbGwoMCk7XG4gICAgY29uc3QgY2x1c3Rlck1hcDoge1tfOiBudW1iZXJdOiBudW1iZXJbXX0gPSB7fTtcbiAgICBjbHVzdGVycy5mb3JFYWNoKChjbHVzdGVyLCBpKSA9PiB7XG4gICAgICBpZiAoIWNsdXN0ZXJNYXBbY2x1c3Rlcl0pXG4gICAgICAgIGNsdXN0ZXJNYXBbY2x1c3Rlcl0gPSBbXTtcbiAgICAgIGNsdXN0ZXJNYXBbY2x1c3Rlcl0ucHVzaChpKTtcbiAgICB9KTtcbiAgICAvLyBjb25zdCBuQ2x1c3RlcnMgPSBPYmplY3Qua2V5cyhjbHVzdGVyTWFwKS5sZW5ndGg7XG4gICAgLy8gY29uc3QgcGVyUm93ID0gTWF0aC5mbG9vcihNYXRoLnNxcnQobkNsdXN0ZXJzKSk7XG4gICAgbGV0IGNsdXN0ZXJOdW0gPSAwO1xuICAgIGNvbnN0IHNvcnRlZENsdXN0ZXJOYW1lcyA9IE9iamVjdC5rZXlzKGNsdXN0ZXJNYXApO1xuICAgIHNvcnRlZENsdXN0ZXJOYW1lcy5zb3J0KChhLCBiKSA9PiBjbHVzdGVyTWFwW2IgYXMgYW55XS5sZW5ndGggLSBjbHVzdGVyTWFwW2EgYXMgYW55XS5sZW5ndGgpO1xuICAgIGxldCBwZXJSb3cgPSA2O1xuXG4gICAgbGV0IHlPZmZzZXQgPSAwO1xuICAgIGNvbnN0IGxheW91dFNpemUgPSA1O1xuICAgIGZvciAoY29uc3QgY2x1c3Rlck5hbWUgb2Ygc29ydGVkQ2x1c3Rlck5hbWVzKSB7XG4gICAgICBjb25zdCBjbHVzdGVyID0gY2x1c3Rlck1hcFtjbHVzdGVyTmFtZSBhcyBhbnldITtcbiAgICAgIGNvbnN0IGVtYmVkZGluZ3MgPSBhd2FpdCBiaW9MYXlvdXQoY2x1c3Rlciwgc3BhcnNlTWF0cml4LCAwLjAwMSk7XG4gICAgICBpZiAoY2x1c3Rlck51bSA9PT0gTWF0aC5jZWlsKHBlclJvdyAvIDEuNSkpIHtcbiAgICAgICAgY2x1c3Rlck51bSA9IDA7XG4gICAgICAgIHlPZmZzZXQgKz0gbGF5b3V0U2l6ZSAvIHBlclJvdztcbiAgICAgICAgcGVyUm93ID0gTWF0aC5jZWlsKHBlclJvdyAqIDEuNSk7XG4gICAgICB9XG4gICAgICBjb25zdCBvZmZzZXRYID0gKChjbHVzdGVyTnVtICUgcGVyUm93KSAqIGxheW91dFNpemUgLyBwZXJSb3cpICogMS41O1xuICAgICAgLy8gY29uc3Qgb2Zmc2V0WSA9IE1hdGguZmxvb3IoY2x1c3Rlck51bSAvIHBlclJvdykgKiAyO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVtYmVkZGluZ3MuZW1iZWRYLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGVtYmVkWFtjbHVzdGVyW2ldXSA9IGVtYmVkZGluZ3MuZW1iZWRYW2ldICogbGF5b3V0U2l6ZSAvIHBlclJvdyArIG9mZnNldFg7XG4gICAgICAgIGVtYmVkWVtjbHVzdGVyW2ldXSA9IGVtYmVkZGluZ3MuZW1iZWRZW2ldICogbGF5b3V0U2l6ZSAvIHBlclJvdyArIHlPZmZzZXQ7XG4gICAgICB9XG4gICAgICBjbHVzdGVyTnVtKys7XG4gICAgfVxuICAgIHJldHVybiB7ZW1iZWRYLCBlbWJlZFl9O1xuICB9XG5cbiAgcHJpdmF0ZSBtZXJnZUNsdXN0ZXJzKGNsdXN0ZXJzOiBudW1iZXJbXSwgaTogbnVtYmVyLCBqOiBudW1iZXIpIHtcbiAgICBjb25zdCBpQ2x1c3RlciA9IGNsdXN0ZXJzW2ldO1xuICAgIGNvbnN0IGpDbHVzdGVyID0gY2x1c3RlcnNbal07XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBjbHVzdGVycy5sZW5ndGg7IGsrKykge1xuICAgICAgaWYgKGNsdXN0ZXJzW2tdID09PSBqQ2x1c3RlcilcbiAgICAgICAgY2x1c3RlcnNba10gPSBpQ2x1c3RlcjtcbiAgICB9XG4gIH1cbiAgcHVibGljIGFzc2lnbkNsdXN0ZXJzKHNwYXJzZU1hdHJpeDogU3BhcnNlTWF0cml4T2JqZWN0LCBuUm93czogbnVtYmVyKSB7XG4gICAgbGV0IGNsdXN0ZXJOdW0gPSAwO1xuICAgIGNvbnN0IGlzOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IGpzOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IG9yZGVyID0gTWF0aC5mbG9vcihNYXRoLm1heChNYXRoLmxvZzEwKG5Sb3dzKSwgMikpICsgMTtcbiAgICBjb25zdCBtaW5PcmRlciA9IE1hdGgucG93KDEwLCBvcmRlcik7XG4gICAgY29uc3QgY2x1c3RlcnM6IG51bWJlcltdID0gbmV3IEFycmF5KG5Sb3dzKS5maWxsKC0xKTtcbiAgICBmb3IgKGNvbnN0IGkgb2YgT2JqZWN0LmtleXMoc3BhcnNlTWF0cml4KSkge1xuICAgICAgZm9yIChjb25zdCBqIG9mIE9iamVjdC5rZXlzKHNwYXJzZU1hdHJpeFtpIGFzIGFueV0pKSB7XG4gICAgICAgIGlmIChNYXRoLnJvdW5kKHNwYXJzZU1hdHJpeFtpIGFzIGFueV1baiBhcyBhbnldICogbWluT3JkZXIpIC8gbWluT3JkZXIgPiAwICYmXG4gICAgICAgICAgc3BhcnNlTWF0cml4W2kgYXMgYW55XVtqIGFzIGFueV0gIT09IE51bWJlcihpKSAmJiBOdW1iZXIoaikgPiBOdW1iZXIoaSkpIHtcbiAgICAgICAgICBpcy5wdXNoKE51bWJlcihpKSk7XG4gICAgICAgICAganMucHVzaChOdW1iZXIoaikpO1xuICAgICAgICAgIGlmIChjbHVzdGVyc1tOdW1iZXIoaSldICE9PSAtMSAmJiBjbHVzdGVyc1tOdW1iZXIoaildICE9PSAtMSkge1xuICAgICAgICAgICAgaWYgKGNsdXN0ZXJzW051bWJlcihpKV0gIT09IGNsdXN0ZXJzW051bWJlcihqKV0pXG4gICAgICAgICAgICAgIHRoaXMubWVyZ2VDbHVzdGVycyhjbHVzdGVycywgTnVtYmVyKGkpLCBOdW1iZXIoaikpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY2x1c3RlcnNbTnVtYmVyKGkpXSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNsdXN0ZXJzW051bWJlcihqKV0gPSBjbHVzdGVyc1tOdW1iZXIoaSldO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY2x1c3RlcnNbTnVtYmVyKGopXSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNsdXN0ZXJzW051bWJlcihpKV0gPSBjbHVzdGVyc1tOdW1iZXIoaildO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjbHVzdGVyTnVtKys7XG4gICAgICAgICAgICBjbHVzdGVyc1tOdW1iZXIoaSldID0gY2x1c3Rlck51bTtcbiAgICAgICAgICAgIGNsdXN0ZXJzW051bWJlcihqKV0gPSBjbHVzdGVyTnVtO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGxldCBpPTA7IGkgPCBjbHVzdGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGNsdXN0ZXJzW2ldID09PSAtMSkge1xuICAgICAgICBjbHVzdGVyTnVtICsrO1xuICAgICAgICBjbHVzdGVyc1tpXSA9IGNsdXN0ZXJOdW07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7Y2x1c3RlcnMsIGlzOiBuZXcgVWludDMyQXJyYXkoaXMpLCBqczogbmV3IFVpbnQzMkFycmF5KGpzKX07XG4gIH1cblxuICAvKiogc2FtZSBhcyBhc3NpZ24gY2x1c3RlcnMgYnV0IHdvcmtpbmcgb24gdGhlIGxldmVsIG9mIENTUiBmb3JtYXQgcmV0dXJuZWQgZnJvbSB3ZWJHUFUgKi9cbiAgcHJpdmF0ZSBhc3NpZ25DbHVzdGVyc0NTUihtY2xSZXM6IE1DTE9wUmV0dXJuVHlwZSwgblJvd3M6IG51bWJlcikge1xuICAgIGxldCBjbHVzdGVyTnVtID0gMDtcbiAgICBjb25zdCBpczogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCBqczogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCBvcmRlciA9IE1hdGguZmxvb3IoTWF0aC5tYXgoTWF0aC5sb2cxMChuUm93cyksIDIpKSArIDE7XG4gICAgY29uc3QgbWluT3JkZXIgPSAxIC8gTWF0aC5wb3coMTAsIG9yZGVyKTtcbiAgICBjb25zdCBjbHVzdGVyczogbnVtYmVyW10gPSBuZXcgQXJyYXkoblJvd3MpLmZpbGwoLTEpO1xuICAgIGNvbnN0IGNvcnJlY3RlZE9mZnNldHMgPSBuZXcgVWludDMyQXJyYXkoblJvd3MgKyAxKTtcbiAgICBsZXQgb2Zmc2V0Q291bnRlciA9IDA7XG4gICAgY29ycmVjdGVkT2Zmc2V0c1swXSA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuUm93czsgaSsrKSB7XG4gICAgICBmb3IgKGxldCBrID0gbWNsUmVzLmluZGV4T2Zmc2V0c1tpXTsgayA8IG1jbFJlcy5pbmRleE9mZnNldHNbaSArIDFdOyBrKyspIHtcbiAgICAgICAgY29uc3QgaiA9IG1jbFJlcy5LTk5JbmRleGVzW2tdO1xuICAgICAgICBpZiAoaiA8PSBpIHx8IG1jbFJlcy5LTk5TaW1pbGFyaXRpZXNba10gPD0gbWluT3JkZXIpXG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIGlzLnB1c2goaSk7XG4gICAgICAgIGpzLnB1c2goaik7XG4gICAgICAgIG9mZnNldENvdW50ZXIrKztcbiAgICAgICAgaWYgKGNsdXN0ZXJzW2ldICE9PSAtMSAmJiBjbHVzdGVyc1tqXSAhPT0gLTEpIHtcbiAgICAgICAgICBpZiAoY2x1c3RlcnNbaV0gIT09IGNsdXN0ZXJzW2pdKVxuICAgICAgICAgICAgdGhpcy5tZXJnZUNsdXN0ZXJzKGNsdXN0ZXJzLCBpLCBqKTtcbiAgICAgICAgfSBlbHNlIGlmIChjbHVzdGVyc1tpXSAhPT0gLTEpIHtcbiAgICAgICAgICBjbHVzdGVyc1tqXSA9IGNsdXN0ZXJzW2ldO1xuICAgICAgICB9IGVsc2UgaWYgKGNsdXN0ZXJzW2pdICE9PSAtMSkge1xuICAgICAgICAgIGNsdXN0ZXJzW2ldID0gY2x1c3RlcnNbal07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2x1c3Rlck51bSsrO1xuICAgICAgICAgIGNsdXN0ZXJzW2ldID0gY2x1c3Rlck51bTtcbiAgICAgICAgICBjbHVzdGVyc1tqXSA9IGNsdXN0ZXJOdW07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvcnJlY3RlZE9mZnNldHNbaSArIDFdID0gb2Zmc2V0Q291bnRlcjtcbiAgICB9XG4gICAgZm9yIChsZXQgaT0wOyBpIDwgY2x1c3RlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChjbHVzdGVyc1tpXSA9PT0gLTEpIHtcbiAgICAgICAgY2x1c3Rlck51bSArKztcbiAgICAgICAgY2x1c3RlcnNbaV0gPSBjbHVzdGVyTnVtO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge2NsdXN0ZXJzLCBpczogbmV3IFVpbnQzMkFycmF5KGlzKSwganM6IG5ldyBVaW50MzJBcnJheShqcyksIGNvcnJlY3RlZE9mZnNldHN9O1xuICB9XG5cbiAgcHVibGljIHRvT2JqZWN0Rm9ybShzcGFyc2VNYXRyaXg6IFNwYXJzZU1hdHJpeFJlc3VsdCk6IFNwYXJzZU1hdHJpeE9iamVjdCB7XG4gICAgY29uc3Qgc3BhcnNlT2JqZWN0OiB7W186IG51bWJlcl06IHtbXzogbnVtYmVyXTogbnVtYmVyfX0gPSB7fTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNwYXJzZU1hdHJpeC5pLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIXNwYXJzZU9iamVjdFtzcGFyc2VNYXRyaXguaVtpXV0pXG4gICAgICAgIHNwYXJzZU9iamVjdFtzcGFyc2VNYXRyaXguaVtpXV0gPSB7fTtcbiAgICAgIHNwYXJzZU9iamVjdFtzcGFyc2VNYXRyaXguaVtpXV1bc3BhcnNlTWF0cml4LmpbaV1dID0gMSAtIHNwYXJzZU1hdHJpeC5kaXN0YW5jZVtpXTtcbiAgICAgIGlmICghc3BhcnNlT2JqZWN0W3NwYXJzZU1hdHJpeC5qW2ldXSlcbiAgICAgICAgc3BhcnNlT2JqZWN0W3NwYXJzZU1hdHJpeC5qW2ldXSA9IHt9O1xuICAgICAgc3BhcnNlT2JqZWN0W3NwYXJzZU1hdHJpeC5qW2ldXVtzcGFyc2VNYXRyaXguaVtpXV0gPSAxIC0gc3BhcnNlTWF0cml4LmRpc3RhbmNlW2ldO1xuICAgIH1cbiAgICByZXR1cm4gc3BhcnNlT2JqZWN0O1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRMb29wcyhzcGFyc2VPYmplY3Q6IFNwYXJzZU1hdHJpeE9iamVjdCwgblJvd3M6IG51bWJlcikge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgblJvd3M7IGkrKykge1xuICAgICAgaWYgKCFzcGFyc2VPYmplY3RbaV0pXG4gICAgICAgIHNwYXJzZU9iamVjdFtpXSA9IHt9O1xuICAgICAgc3BhcnNlT2JqZWN0W2ldW2ldID0gdGhpcy5fb3B0aW9ucy5tdWx0RmFjdG9yO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbm9ybWFsaXplKHNwYXJzZU9iamVjdDogU3BhcnNlTWF0cml4T2JqZWN0KSB7XG4gICAgZm9yIChjb25zdCBpIG9mIE9iamVjdC5rZXlzKHNwYXJzZU9iamVjdCkpIHtcbiAgICAgIGNvbnN0IHJvdyA9IHNwYXJzZU9iamVjdFtpIGFzIGFueV07XG4gICAgICBsZXQgc3VtID0gMDtcbiAgICAgIGZvciAoY29uc3QgaiBvZiBPYmplY3Qua2V5cyhyb3cpKVxuICAgICAgICBzdW0gKz0gcm93W2ogYXMgYW55XTtcbiAgICAgIGlmIChzdW0gPT09IDApIGNvbnRpbnVlO1xuICAgICAgZm9yIChjb25zdCBqIG9mIE9iamVjdC5rZXlzKHJvdykpXG4gICAgICAgIHNwYXJzZU9iamVjdFtpIGFzIGFueV1baiBhcyBhbnldIC89IHN1bTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGV4cGFuZChzcGFyc2VPYmplY3Q6IFNwYXJzZU1hdHJpeE9iamVjdCwgblJvd3M6IG51bWJlcikge1xuICAgIGNvbnN0IGV4cGFuZGVkT2JqZWN0OiBTcGFyc2VNYXRyaXhPYmplY3QgPSB7fTtcbiAgICBjb25zdCBvcmRlciA9IE1hdGguZmxvb3IoTWF0aC5tYXgoTWF0aC5sb2cxMChuUm93cyksIDIpKSArIDE7XG4gICAgY29uc3QgbWluT3JkZXIgPSBNYXRoLnBvdygxMCwgb3JkZXIpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgblJvd3M7IGkrKykge1xuICAgICAgaWYgKCFzcGFyc2VPYmplY3RbaV0pXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgLy8gY29uc3Qgcm93ID0gc3BhcnNlT2JqZWN0W2ldO1xuICAgICAgZXhwYW5kZWRPYmplY3RbaV0gPz89IHt9O1xuICAgICAgZm9yIChsZXQgaiA9IGk7IGogPCBuUm93czsgaisrKSB7XG4gICAgICAgIGlmICghc3BhcnNlT2JqZWN0W2ldPy5bal0pXG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIGNvbnN0IHZhbCA9IHRoaXMuZ2V0RXhwYW5kVmFsdWUoc3BhcnNlT2JqZWN0LCBpLCBqKTsgLy9wcnVuaW5nIHN0ZXBcbiAgICAgICAgaWYgKE1hdGgucm91bmQodmFsICogbWluT3JkZXIpIC8gbWluT3JkZXIgPiAwKSB7XG4gICAgICAgICAgZXhwYW5kZWRPYmplY3RbaV1bal0gPSB2YWw7XG4gICAgICAgICAgaWYgKCFleHBhbmRlZE9iamVjdFtqXSlcbiAgICAgICAgICAgIGV4cGFuZGVkT2JqZWN0W2pdID0ge307XG4gICAgICAgICAgZXhwYW5kZWRPYmplY3Rbal1baV0gPSB2YWw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGV4cGFuZGVkT2JqZWN0O1xuICB9XG5cbiAgLy8gcHJpdmF0ZSBwcnVuZShyb3c6IFNwYXJzZU1hdHJpeE9iamVjdFtudW1iZXJdKSB7XG5cbiAgLy8gfVxuXG4gIHByaXZhdGUgaW5mbGF0ZShzcGFyc2VPYmplY3Q6IFNwYXJzZU1hdHJpeE9iamVjdCkge1xuICAgIGZvciAoY29uc3QgaSBvZiBPYmplY3Qua2V5cyhzcGFyc2VPYmplY3QpKSB7XG4gICAgICBjb25zdCByb3cgPSBzcGFyc2VPYmplY3RbaSBhcyBhbnldO1xuICAgICAgZm9yIChjb25zdCBqIG9mIE9iamVjdC5rZXlzKHJvdykpXG4gICAgICAgIHNwYXJzZU9iamVjdFtpIGFzIGFueV1baiBhcyBhbnldID0gTWF0aC5wb3coc3BhcnNlT2JqZWN0W2kgYXMgYW55XVtqIGFzIGFueV0sIHRoaXMuX29wdGlvbnMuaW5mbGF0ZUZhY3Rvcik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRFeHBhbmRWYWx1ZShzcGFyc2VPYmplY3Q6IFNwYXJzZU1hdHJpeE9iamVjdCwgaTogYW55LCBqOiBhbnkpIHtcbiAgICBsZXQgdmFsID0gMDtcbiAgICBjb25zdCBjdXJyZW50SW5kZXhlcyA9IE9iamVjdC5rZXlzKHNwYXJzZU9iamVjdFtpXSA/PyB7fSk7XG4gICAgY29uc3Qgb3RoZXJJbmRleGVzID0gT2JqZWN0LmtleXMoc3BhcnNlT2JqZWN0W2pdID8/IHt9KTtcbiAgICBmb3IgKGNvbnN0IGsgb2YgY3VycmVudEluZGV4ZXMpIHtcbiAgICAgIGlmIChvdGhlckluZGV4ZXMuaW5jbHVkZXMoaykpXG4gICAgICAgIHZhbCArPSBzcGFyc2VPYmplY3RbaV1bayBhcyBhbnldICogc3BhcnNlT2JqZWN0W2pdW2sgYXMgYW55XTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbDtcbiAgfVxufVxuXG4iXX0=","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\n/* eslint-disable max-len */\nimport { getGPUDevice } from '../getGPUDevice';\nimport { sparseKNNNoralizeColwise } from './colwise-normalize';\nimport { expandNoRevive, inflate } from './inflate-expand';\nimport { toSparseKNNSimilarityForm } from './utils';\nexport function markovClusterWebGPU(sparseMatrix, nRows, maxIterations = 5, inflateFactor = 2) {\n return __awaiter(this, void 0, void 0, function* () {\n const device = yield getGPUDevice();\n if (!device)\n throw new Error('no gpu device found');\n // self loops are already added here\n const sparseKNNForm = toSparseKNNSimilarityForm(sparseMatrix, nRows);\n // first, we normilize the similarities\n yield sparseKNNNoralizeColwise(device, sparseKNNForm.KNNSimilarities, sparseKNNForm.indexOffsets, nRows);\n let res = sparseKNNForm;\n // then we expand the similarities\n for (let i = 0; i < maxIterations; i++) {\n //console.log(checkSorted(res.KNNIndexes, res.indexOffsets));\n const expandRes = yield expandNoRevive(device, res.KNNSimilarities, res.KNNIndexes, res.indexOffsets, nRows);\n // then we inflate the similarities\n inflate(expandRes.KNNSimilarities, inflateFactor);\n // then we normilize the similarities again\n yield sparseKNNNoralizeColwise(device, expandRes.KNNSimilarities, expandRes.indexOffsets, nRows);\n res = expandRes;\n }\n return res;\n });\n}\n//# sourceMappingURL=MCL-webGPU.js.map","import { multiColWebGPUSparseMatrix } from '@datagrok-libraries/math/src/webGPU/sparse-matrix/webGPU-sparse-matrix';\nimport { SparseMatrixService } from '../distance-matrix/sparse-matrix-service';\nimport { MCLSparseReducer } from './marcov-cluster';\nonmessage = async (event) => {\n const { data, threshold, weights, aggregationMethod, distanceFnArgs, distanceFns, maxIterations, useWebGPU, inflate } = event.data;\n console.time('sparse matrix');\n let sparse = null;\n if (useWebGPU) {\n try {\n sparse = await multiColWebGPUSparseMatrix(data, threshold / 100, distanceFns, aggregationMethod, weights, distanceFnArgs);\n }\n catch (e) {\n console.error(e);\n }\n }\n if (!sparse) { // falsback to CPU\n if (useWebGPU)\n console.error('WEBGPU sparse matrix calculation failed, falling back to CPU implementation');\n sparse = await new SparseMatrixService()\n .calcMultiColumn(data, distanceFns, threshold / 100, distanceFnArgs, weights, aggregationMethod);\n }\n console.timeEnd('sparse matrix');\n //const res = await new MCLSparseReducer({maxIterations: maxIterations ?? 5}).transform(sparse, data[0].length);\n const reducer = new MCLSparseReducer({ maxIterations: maxIterations ?? 5, inflateFactor: inflate ?? 2 });\n console.time('MCL');\n let res = null;\n if (useWebGPU) {\n try {\n res = await reducer.transformWebGPU(sparse, data[0].length);\n }\n catch (e) {\n console.error('webGPU MCL failed, falling back to CPU implementation');\n console.error(e);\n }\n }\n if (!res)\n res = await reducer.transform(sparse, data[0].length);\n console.timeEnd('MCL');\n postMessage({ res });\n};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNsLXdvcmtlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1jbC13b3JrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLDBCQUEwQixFQUFDLE1BQU0sd0VBQXdFLENBQUM7QUFDbEgsT0FBTyxFQUFxQixtQkFBbUIsRUFBQyxNQUFNLDBDQUEwQyxDQUFDO0FBR2pHLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBRWxELFNBQVMsR0FBRyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7SUFDMUIsTUFBTSxFQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUMsR0FNL0csS0FBSyxDQUFDLElBQUksQ0FBQztJQUVmLE9BQU8sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDOUIsSUFBSSxNQUFNLEdBQThCLElBQUksQ0FBQztJQUM3QyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ2QsSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLE1BQU0sMEJBQTBCLENBQ3ZDLElBQUksRUFBRSxTQUFTLEdBQUcsR0FBRyxFQUFFLFdBQWtCLEVBQUUsaUJBQXdCLEVBQUUsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQ2xHLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQixDQUFDO0lBQ0gsQ0FBQztJQUNELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLGtCQUFrQjtRQUMvQixJQUFJLFNBQVM7WUFDWCxPQUFPLENBQUMsS0FBSyxDQUFDLDZFQUE2RSxDQUFDLENBQUM7UUFFL0YsTUFBTSxHQUFHLE1BQU0sSUFBSSxtQkFBbUIsRUFBRTthQUNyQyxlQUFlLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxTQUFTLEdBQUcsR0FBRyxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUNyRyxDQUFDO0lBQ0QsT0FBTyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUVqQyxnSEFBZ0g7SUFDaEgsTUFBTSxPQUFPLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxFQUFDLGFBQWEsRUFBRSxhQUFhLElBQUksQ0FBQyxFQUFFLGFBQWEsRUFBRSxPQUFPLElBQUksQ0FBQyxFQUFDLENBQUMsQ0FBQztJQUN2RyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BCLElBQUksR0FBRyxHQUFRLElBQUksQ0FBQztJQUNwQixJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ2QsSUFBSSxDQUFDO1lBQ0gsR0FBRyxHQUFHLE1BQU0sT0FBTyxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzlELENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO1lBQ3ZFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkIsQ0FBQztJQUNILENBQUM7SUFDRCxJQUFJLENBQUMsR0FBRztRQUNOLEdBQUcsR0FBRyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN4RCxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRXZCLFdBQVcsQ0FBQyxFQUFDLEdBQUcsRUFBQyxDQUFDLENBQUM7QUFDckIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHttdWx0aUNvbFdlYkdQVVNwYXJzZU1hdHJpeH0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy9tYXRoL3NyYy93ZWJHUFUvc3BhcnNlLW1hdHJpeC93ZWJHUFUtc3BhcnNlLW1hdHJpeCc7XG5pbXBvcnQge1NwYXJzZU1hdHJpeFJlc3VsdCwgU3BhcnNlTWF0cml4U2VydmljZX0gZnJvbSAnLi4vZGlzdGFuY2UtbWF0cml4L3NwYXJzZS1tYXRyaXgtc2VydmljZSc7XG5pbXBvcnQge0Rpc3RhbmNlQWdncmVnYXRpb25NZXRob2R9IGZyb20gJy4uL2Rpc3RhbmNlLW1hdHJpeC90eXBlcyc7XG5pbXBvcnQge0tub3duTWV0cmljc30gZnJvbSAnLi4vdHlwZWQtbWV0cmljcyc7XG5pbXBvcnQge01DTFNwYXJzZVJlZHVjZXJ9IGZyb20gJy4vbWFyY292LWNsdXN0ZXInO1xuXG5vbm1lc3NhZ2UgPSBhc3luYyAoZXZlbnQpID0+IHtcbiAgY29uc3Qge2RhdGEsIHRocmVzaG9sZCwgd2VpZ2h0cywgYWdncmVnYXRpb25NZXRob2QsIGRpc3RhbmNlRm5BcmdzLCBkaXN0YW5jZUZucywgbWF4SXRlcmF0aW9ucywgdXNlV2ViR1BVLCBpbmZsYXRlfTpcbiAgIHtcbiAgICBkYXRhOiBhbnlbXVtdLCB0aHJlc2hvbGQ6IG51bWJlcixcbiAgICB3ZWlnaHRzOiBudW1iZXJbXSwgYWdncmVnYXRpb25NZXRob2Q6IERpc3RhbmNlQWdncmVnYXRpb25NZXRob2QsXG4gICAgZGlzdGFuY2VGbnM6IEtub3duTWV0cmljc1tdLCBkaXN0YW5jZUZuQXJnczogYW55W10sIG1heEl0ZXJhdGlvbnM6IG51bWJlcixcbiAgICB1c2VXZWJHUFU/OiBib29sZWFuLCBpbmZsYXRlPzogbnVtYmVyXG4gIH0gPSBldmVudC5kYXRhO1xuXG4gIGNvbnNvbGUudGltZSgnc3BhcnNlIG1hdHJpeCcpO1xuICBsZXQgc3BhcnNlOiBTcGFyc2VNYXRyaXhSZXN1bHQgfCBudWxsID0gbnVsbDtcbiAgaWYgKHVzZVdlYkdQVSkge1xuICAgIHRyeSB7XG4gICAgICBzcGFyc2UgPSBhd2FpdCBtdWx0aUNvbFdlYkdQVVNwYXJzZU1hdHJpeChcbiAgICAgICAgZGF0YSwgdGhyZXNob2xkIC8gMTAwLCBkaXN0YW5jZUZucyBhcyBhbnksIGFnZ3JlZ2F0aW9uTWV0aG9kIGFzIGFueSwgd2VpZ2h0cywgZGlzdGFuY2VGbkFyZ3MpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgfVxuICB9XG4gIGlmICghc3BhcnNlKSB7IC8vIGZhbHNiYWNrIHRvIENQVVxuICAgIGlmICh1c2VXZWJHUFUpXG4gICAgICBjb25zb2xlLmVycm9yKCdXRUJHUFUgc3BhcnNlIG1hdHJpeCBjYWxjdWxhdGlvbiBmYWlsZWQsIGZhbGxpbmcgYmFjayB0byBDUFUgaW1wbGVtZW50YXRpb24nKTtcblxuICAgIHNwYXJzZSA9IGF3YWl0IG5ldyBTcGFyc2VNYXRyaXhTZXJ2aWNlKClcbiAgICAgIC5jYWxjTXVsdGlDb2x1bW4oZGF0YSwgZGlzdGFuY2VGbnMsIHRocmVzaG9sZCAvIDEwMCwgZGlzdGFuY2VGbkFyZ3MsIHdlaWdodHMsIGFnZ3JlZ2F0aW9uTWV0aG9kKTtcbiAgfVxuICBjb25zb2xlLnRpbWVFbmQoJ3NwYXJzZSBtYXRyaXgnKTtcblxuICAvL2NvbnN0IHJlcyA9IGF3YWl0IG5ldyBNQ0xTcGFyc2VSZWR1Y2VyKHttYXhJdGVyYXRpb25zOiBtYXhJdGVyYXRpb25zID8/IDV9KS50cmFuc2Zvcm0oc3BhcnNlLCBkYXRhWzBdLmxlbmd0aCk7XG4gIGNvbnN0IHJlZHVjZXIgPSBuZXcgTUNMU3BhcnNlUmVkdWNlcih7bWF4SXRlcmF0aW9uczogbWF4SXRlcmF0aW9ucyA/PyA1LCBpbmZsYXRlRmFjdG9yOiBpbmZsYXRlID8/IDJ9KTtcbiAgY29uc29sZS50aW1lKCdNQ0wnKTtcbiAgbGV0IHJlczogYW55ID0gbnVsbDtcbiAgaWYgKHVzZVdlYkdQVSkge1xuICAgIHRyeSB7XG4gICAgICByZXMgPSBhd2FpdCByZWR1Y2VyLnRyYW5zZm9ybVdlYkdQVShzcGFyc2UsIGRhdGFbMF0ubGVuZ3RoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCd3ZWJHUFUgTUNMIGZhaWxlZCwgZmFsbGluZyBiYWNrIHRvIENQVSBpbXBsZW1lbnRhdGlvbicpO1xuICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFyZXMpXG4gICAgcmVzID0gYXdhaXQgcmVkdWNlci50cmFuc2Zvcm0oc3BhcnNlLCBkYXRhWzBdLmxlbmd0aCk7XG4gIGNvbnNvbGUudGltZUVuZCgnTUNMJyk7XG5cbiAgcG9zdE1lc3NhZ2Uoe3Jlc30pO1xufTtcbiJdfQ==","import { DistanceAggregationMethods } from './types';\nexport const isNil = (x) => x === null || x === undefined;\nexport function insertSmaller(distancesAr, indexes, num, index) {\n if (num > distancesAr[distancesAr.length - 1])\n return;\n const newPosition = distancesAr.findIndex((v) => num < v);\n distancesAr.pop();\n distancesAr.splice(newPosition, 0, num);\n indexes.pop();\n indexes.splice(newPosition, 0, index);\n}\nexport function insertLarger(distancesAr, indexes, num, index) {\n if (num < distancesAr[distancesAr.length - 1])\n return;\n const newPosition = distancesAr.findIndex((v) => num > v);\n distancesAr.pop();\n distancesAr.splice(newPosition, 0, num);\n indexes.pop();\n indexes.splice(newPosition, 0, index);\n}\nexport function getAggregationFunction(aggregationMethod, weights) {\n switch (aggregationMethod) {\n case DistanceAggregationMethods.MANHATTAN:\n return (vs) => vs.reduce((acc, val, idx) => acc + val * weights[idx], 0);\n default:\n return (vs) => {\n // euclidean\n const sum = vs.reduce((acc, val, idx) => acc + (val * weights[idx]) ** 2, 0);\n return Math.sqrt(sum);\n };\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQTRCLDBCQUEwQixFQUFDLE1BQU0sU0FBUyxDQUFDO0FBRTlFLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssU0FBUyxDQUFDO0FBRS9ELE1BQU0sVUFBVSxhQUFhLENBQUMsV0FBcUIsRUFBRSxPQUFpQixFQUFFLEdBQVcsRUFBRSxLQUFhO0lBQ2hHLElBQUksR0FBRyxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFDLENBQUMsQ0FBQztRQUN6QyxPQUFPO0lBRVQsTUFBTSxXQUFXLEdBQUcsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzFELFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNsQixXQUFXLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDeEMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ2QsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ3hDLENBQUM7QUFFRCxNQUFNLFVBQVUsWUFBWSxDQUFDLFdBQXFCLEVBQUUsT0FBaUIsRUFBRSxHQUFXLEVBQUUsS0FBYTtJQUMvRixJQUFJLEdBQUcsR0FBRyxXQUFXLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBQyxDQUFDLENBQUM7UUFDekMsT0FBTztJQUVULE1BQU0sV0FBVyxHQUFHLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUMxRCxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDbEIsV0FBVyxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3hDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNkLE9BQU8sQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUN4QyxDQUFDO0FBRUQsTUFBTSxVQUFVLHNCQUFzQixDQUNwQyxpQkFBNEMsRUFBRSxPQUFpQjtJQUUvRCxRQUFRLGlCQUFpQixFQUFFLENBQUM7UUFDMUIsS0FBSywwQkFBMEIsQ0FBQyxTQUFTO1lBQ3ZDLE9BQU8sQ0FBQyxFQUFZLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDckY7WUFDRSxPQUFPLENBQUMsRUFBWSxFQUFFLEVBQUU7Z0JBQ3RCLFlBQVk7Z0JBQ1osTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUM3RSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEIsQ0FBQyxDQUFDO0lBQ04sQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0Rpc3RhbmNlQWdncmVnYXRpb25NZXRob2QsIERpc3RhbmNlQWdncmVnYXRpb25NZXRob2RzfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGNvbnN0IGlzTmlsID0gKHg6IGFueSkgPT4geCA9PT0gbnVsbCB8fCB4ID09PSB1bmRlZmluZWQ7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbnNlcnRTbWFsbGVyKGRpc3RhbmNlc0FyOiBudW1iZXJbXSwgaW5kZXhlczogbnVtYmVyW10sIG51bTogbnVtYmVyLCBpbmRleDogbnVtYmVyKSB7XG4gIGlmIChudW0gPiBkaXN0YW5jZXNBcltkaXN0YW5jZXNBci5sZW5ndGgtMV0pXG4gICAgcmV0dXJuO1xuXG4gIGNvbnN0IG5ld1Bvc2l0aW9uID0gZGlzdGFuY2VzQXIuZmluZEluZGV4KCh2KSA9PiBudW0gPCB2KTtcbiAgZGlzdGFuY2VzQXIucG9wKCk7XG4gIGRpc3RhbmNlc0FyLnNwbGljZShuZXdQb3NpdGlvbiwgMCwgbnVtKTtcbiAgaW5kZXhlcy5wb3AoKTtcbiAgaW5kZXhlcy5zcGxpY2UobmV3UG9zaXRpb24sIDAsIGluZGV4KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydExhcmdlcihkaXN0YW5jZXNBcjogbnVtYmVyW10sIGluZGV4ZXM6IG51bWJlcltdLCBudW06IG51bWJlciwgaW5kZXg6IG51bWJlcikge1xuICBpZiAobnVtIDwgZGlzdGFuY2VzQXJbZGlzdGFuY2VzQXIubGVuZ3RoLTFdKVxuICAgIHJldHVybjtcblxuICBjb25zdCBuZXdQb3NpdGlvbiA9IGRpc3RhbmNlc0FyLmZpbmRJbmRleCgodikgPT4gbnVtID4gdik7XG4gIGRpc3RhbmNlc0FyLnBvcCgpO1xuICBkaXN0YW5jZXNBci5zcGxpY2UobmV3UG9zaXRpb24sIDAsIG51bSk7XG4gIGluZGV4ZXMucG9wKCk7XG4gIGluZGV4ZXMuc3BsaWNlKG5ld1Bvc2l0aW9uLCAwLCBpbmRleCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRBZ2dyZWdhdGlvbkZ1bmN0aW9uKFxuICBhZ2dyZWdhdGlvbk1ldGhvZDogRGlzdGFuY2VBZ2dyZWdhdGlvbk1ldGhvZCwgd2VpZ2h0czogbnVtYmVyW11cbik6ICh2YWx1ZXM6IG51bWJlcltdKSA9PiBudW1iZXIge1xuICBzd2l0Y2ggKGFnZ3JlZ2F0aW9uTWV0aG9kKSB7XG4gICAgY2FzZSBEaXN0YW5jZUFnZ3JlZ2F0aW9uTWV0aG9kcy5NQU5IQVRUQU46XG4gICAgICByZXR1cm4gKHZzOiBudW1iZXJbXSkgPT4gdnMucmVkdWNlKChhY2MsIHZhbCwgaWR4KSA9PiBhY2MgKyB2YWwgKiB3ZWlnaHRzW2lkeF0sIDApO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gKHZzOiBudW1iZXJbXSkgPT4ge1xuICAgICAgICAvLyBldWNsaWRlYW5cbiAgICAgICAgY29uc3Qgc3VtID0gdnMucmVkdWNlKChhY2MsIHZhbCwgaWR4KSA9PiBhY2MgKyAodmFsICogd2VpZ2h0c1tpZHhdKSAqKiAyLCAwKTtcbiAgICAgICAgcmV0dXJuIE1hdGguc3FydChzdW0pO1xuICAgICAgfTtcbiAgfVxufVxuIl19","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n// the startup function\n__webpack_require__.x = () => {\n\t// Load entry module and return exports\n\t// This entry module depends on other loaded chunks and execution need to be delayed\n\tvar __webpack_exports__ = __webpack_require__.O(undefined, [731], () => (__webpack_require__(9260)))\n\t__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n\treturn __webpack_exports__;\n};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = (chunkId) => {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks and sibling chunks for the entrypoint\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".js\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","var scriptUrl;\nif (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + \"\";\nvar document = __webpack_require__.g.document;\nif (!scriptUrl && document) {\n\tif (document.currentScript)\n\t\tscriptUrl = document.currentScript.src;\n\tif (!scriptUrl) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tif(scripts.length) {\n\t\t\tvar i = scripts.length - 1;\n\t\t\twhile (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;\n\t\t}\n\t}\n}\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","__webpack_require__.b = self.location + \"\";\n\n// object to store loaded chunks\n// \"1\" means \"already loaded\"\nvar installedChunks = {\n\t317: 1\n};\n\n// importScripts chunk loading\nvar installChunk = (data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\tfor(var moduleId in moreModules) {\n\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t}\n\t}\n\tif(runtime) runtime(__webpack_require__);\n\twhile(chunkIds.length)\n\t\tinstalledChunks[chunkIds.pop()] = 1;\n\tparentChunkLoadingFunction(data);\n};\n__webpack_require__.f.i = (chunkId, promises) => {\n\t// \"1\" is the signal for \"already loaded\"\n\tif(!installedChunks[chunkId]) {\n\t\tif(true) { // all chunks have JS\n\t\t\timportScripts(__webpack_require__.p + __webpack_require__.u(chunkId));\n\t\t}\n\t}\n};\n\nvar chunkLoadingGlobal = self[\"webpackChunkbio\"] = self[\"webpackChunkbio\"] || [];\nvar parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);\nchunkLoadingGlobal.push = installChunk;\n\n// no HMR\n\n// no HMR manifest","// run startup\nvar __webpack_exports__ = __webpack_require__.x();\n"],"names":["deferred","next","WEBGSLAGGREGATION","WEBGSLAGGREGATIONFUNCTIONS","EUCLIDEAN","arraySize","MANHATTAN","WEBGPUDISTANCE","webGPUFunctions","HAMMING","_maxArraySize","entryIndex","maxArraySize","_entryIndex","TANIMOTO","LEVENSTEIN","NEEDLEMAN_WUNSCH","MONOMER_CHEMICAL_DISTANCE","SOKAL","COSINE","ASYMMETRIC","Difference","OneHot","distanceFunctionComplexity","maxEntrySize","Math","ceil","_maxEntrySize","TypeSupportedDistances","Set","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","e","rejected","result","done","then","apply","gpuAdapter","gpuDevice","getGPUDevice","this","navigator","gpu","requestAdapter","powerPreference","isLost","lost","r","setTimeout","requiredBufferSize","adapterLimits","limits","buffferSizeLimit","maxBufferSize","storageBufferSizeLimit","maxStorageBufferBindingSize","requestDevice","requiredLimits","min","console","error","multiColWebGPUSparseMatrix","entryList","threshold","distanceMetrics","aggregationFunction","weights","options","device","availableDistanceMetrics","Object","values","some","metric","includes","Error","join","maxDistance","length","list","numOfColumns","listSize","processInfo","map","entry","i","distanceMetric","gapOpenPenalty","gapExtensionPenalty","_a","_b","entryType","encodedList","Uint32Array","split","c","charCodeAt","Float32Array","_data","Int32Array","encodedListType","arraySizes","arr","has","maxEntryLen","reduce","a","b","max","complexity","EncodedArrayConstructor","flatSourceArray","forEach","seq","set","suppInfoStructWgsl","suppInfoSize","suppInfoType","suppInfoBuffer","maxMonomerIndex","scoringMatrix","alphabetIndexes","keys","prev","n","Array","fill","String","fromCharCode","similarityMatrixSize","transferedSimilarityMatrix","key","key2","offset","range","dataTypeWGSL","dataStructWgsl","sourceArraySize","webGPUProcessInfo","suppInfoWgsl","info","filter","wgsl","needsDummy","trim","dataWgsl","numOfThreads","sparseResultSizePerThread","combinedComplexity","maxIterationsPerThread","workgroupsDim","sqrt","globalThreadDimSize","condensedDistanceMatrixSize","dmChunkSizePerThread","module","createShaderModule","label","code","getCombinedDistanceScript","pipeline","createComputePipeline","layout","compute","entryPoint","startAtCols","startAtRows","endAtCols","endAtRows","chunkSize","floor","startRow","startCol","time","endIdx","endRow","endCol","timeEnd","computeInfoBuffer32Size","suppInfoBuffer32Size","sparseMatrixEachArray32Size","computeInfoBufferSize","BYTES_PER_ELEMENT","paddedComputeInfoBufferSize","remainder","computeInfoBuffer","createBuffer","size","usage","GPUBufferUsage","STORAGE","COPY_SRC","COPY_DST","mappedAtCreation","mappedComputeInfoArrayBuffer","getMappedRange","computeInfoOffSet","ArrayConstructor","unmap","suppInfoBufferSize","paddedSuppInfoBufferSize","suppInfoRemainder","mappedSuppInfoArrayBuffer","suppInfoOffSet","byteLength","resultsBufferSize","paddedResultsBufferSize","resultsRemainder","resultsBuffer","bindGroup","createBindGroup","getBindGroupLayout","entries","binding","resource","buffer","resultsOutBuffer","MAP_READ","resultIs","resultJs","resultDistances","isAllDone","encoder","createCommandEncoder","pass","beginComputePass","setPipeline","setBindGroup","dispatchWorkgroups","end","copyBufferToBuffer","commandBuffer","finish","queue","submit","onSubmittedWorkDone","mapAsync","GPUMapMode","READ","resultsOutArrayBuffer","resultOffset","resultsI","resultsJ","resultsDistances","resultsFound","every","d","totalResults","combinedI","combinedJ","combinedDistances","combinedOffset","resI","found","subarray","push","totalSize","finalI","finalJ","finalDistances","finalOffset","destroy","j","distance","maxEntryLens","aggregation","_","async","bioLayout","cluster","sparseObject","is","js","embedX","random","embedY","xVelocities","yVelocities","temperature","idx","dx","dy","abs","vecSize","minX","minY","maxX","maxY","rangeX","rangeY","getLayoutEmbeddings","sparseKNNNoralizeColwise","knnSimilarities","offsets","nRows","neededThreads","neededWorkGroups","workGroupThreadsPerDim","workGroupDim","threadsPerDim","simmilaritiesBuffer","offsetsBuffer","commandEncoder","passEncoder","outSimilarityBuffer","arrayBuffer","inflate","factor","pow","expandNoRevive","knnIndexes","order","log10","pruneValue","outKNNSimilarities","sparseKNNBufferByteSize","sparseKNNBuffer","sparseKNNArrayBuffer","rowIndexes","res","getRowIndexes","startBuffer","resultBlockBuffer","outBlockBuffer","start","curLength","writeBuffer","outBlock","KNNIndexes","KNNSimilarities","indexOffsets","toSparseKNNSimilarityForm","sparseMatrix","occurenceCount","countOccurancesAddLoops","offsetForm","ar","insertCounter","row","col","similarity","prototype","toString","defaultMCLOptions","expandFactor","maxIterations","inflateFactor","multFactor","MCLSparseReducer","constructor","opts","_options","transform","toObjectForm","addLoops","normalize","expand","clusters","assignClusters","correctClusters","embeddings","transformWebGPU","mclRes","sparseKNNForm","expandRes","markovClusterWebGPU","csrToSparseObject","clusterSizeMap","sortedIndexes","Number","sort","clusterMap","clusterIdx","minOrder","k","clusterNum","sortedClusterNames","perRow","yOffset","clusterName","offsetX","mergeClusters","iCluster","jCluster","round","assignClustersCSR","correctedOffsets","offsetCounter","sum","expandedObject","val","getExpandValue","currentIndexes","otherIndexes","onmessage","event","data","aggregationMethod","distanceFnArgs","distanceFns","useWebGPU","sparse","calcMultiColumn","reducer","postMessage","isNil","x","insertSmaller","distancesAr","indexes","num","index","newPosition","findIndex","v","pop","splice","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","__webpack_modules__","m","__webpack_exports__","O","chunkIds","fn","priority","notFulfilled","Infinity","definition","o","defineProperty","enumerable","get","f","chunkId","all","promises","u","g","globalThis","Function","window","obj","prop","hasOwnProperty","call","scriptUrl","importScripts","location","document","currentScript","src","scripts","getElementsByTagName","test","replace","p","self","installedChunks","chunkLoadingGlobal","parentChunkLoadingFunction","bind","moreModules","runtime"],"sourceRoot":""}
|