@daneren2005/shared-memory-objects 1.0.0 → 1.1.0
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/LICENSE +21 -0
- package/dist/allocated-memory.js +38 -0
- package/dist/allocated-memory.js.map +1 -0
- package/dist/cached-item-list.js +76 -0
- package/dist/cached-item-list.js.map +1 -0
- package/dist/interfaces/pow2.js +2 -0
- package/dist/interfaces/pow2.js.map +1 -0
- package/dist/interfaces/typed-array-constructor.js +2 -0
- package/dist/interfaces/typed-array-constructor.js.map +1 -0
- package/dist/interfaces/typed-array.js +2 -0
- package/dist/interfaces/typed-array.js.map +1 -0
- package/dist/local-pool.js +95 -0
- package/dist/local-pool.js.map +1 -0
- package/dist/lock/read-write-lock.js +25 -0
- package/dist/lock/read-write-lock.js.map +1 -0
- package/dist/lock/simple-lock.js +14 -0
- package/dist/lock/simple-lock.js.map +1 -0
- package/dist/memory-buffer.js +327 -0
- package/dist/memory-buffer.js.map +1 -0
- package/dist/memory-heap.js +116 -0
- package/dist/memory-heap.js.map +1 -0
- package/dist/serialize-object.js +59 -0
- package/dist/serialize-object.js.map +1 -0
- package/dist/shared-list.js +165 -0
- package/dist/shared-list.js.map +1 -0
- package/dist/shared-map.js +140 -0
- package/dist/shared-map.js.map +1 -0
- package/dist/shared-pointer-list.js +50 -0
- package/dist/shared-pointer-list.js.map +1 -0
- package/dist/shared-pool.js +165 -0
- package/dist/shared-pool.js.map +1 -0
- package/dist/shared-string.js +79 -0
- package/dist/shared-string.js.map +1 -0
- package/dist/shared-vector.js +165 -0
- package/dist/shared-vector.js.map +1 -0
- package/dist/utils/16-from-32-array.js +20 -0
- package/dist/utils/16-from-32-array.js.map +1 -0
- package/dist/utils/16-from-64-array.js +12 -0
- package/dist/utils/16-from-64-array.js.map +1 -0
- package/dist/utils/atomic-math.js +36 -0
- package/dist/utils/atomic-math.js.map +1 -0
- package/dist/utils/float32-atomics.js +28 -0
- package/dist/utils/float32-atomics.js.map +1 -0
- package/dist/utils/float64-atomics.js +28 -0
- package/dist/utils/float64-atomics.js.map +1 -0
- package/dist/utils/pointer.js +44 -0
- package/dist/utils/pointer.js.map +1 -0
- package/dist/utils/typedarray.js +46 -0
- package/dist/utils/typedarray.js.map +1 -0
- package/package.json +6 -11
- package/dist/shared-memory-objects.js +0 -1578
- package/dist/shared-memory-objects.js.map +0 -1
- package/dist/shared-memory-objects.umd.cjs +0 -2
- package/dist/shared-memory-objects.umd.cjs.map +0 -1
- package/dist/src/main.d.ts +0 -22
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Scott Jackson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { createPointer as r } from "./utils/pointer.js";
|
|
2
|
+
class u {
|
|
3
|
+
memory;
|
|
4
|
+
bufferPosition;
|
|
5
|
+
get bufferByteOffset() {
|
|
6
|
+
return this.data.byteOffset;
|
|
7
|
+
}
|
|
8
|
+
get pointer() {
|
|
9
|
+
return r(this.bufferPosition, this.bufferByteOffset);
|
|
10
|
+
}
|
|
11
|
+
buffer;
|
|
12
|
+
data;
|
|
13
|
+
constructor(t, e) {
|
|
14
|
+
this.memory = t, "buffer" in e ? (this.data = e.data, this.buffer = e.buffer, this.bufferPosition = this.memory.buffers.indexOf(e.buffer)) : (this.bufferPosition = e.bufferPosition, this.buffer = t.buffers[e.bufferPosition], this.data = new Uint32Array(this.buffer.buf, e.bufferByteOffset));
|
|
15
|
+
}
|
|
16
|
+
getArray(t, e, f) {
|
|
17
|
+
return new t(this.data.buffer, this.data.byteOffset + e * t.BYTES_PER_ELEMENT, f);
|
|
18
|
+
}
|
|
19
|
+
getArrayMemory(t, e) {
|
|
20
|
+
return {
|
|
21
|
+
bufferPosition: this.bufferPosition,
|
|
22
|
+
bufferByteOffset: this.bufferByteOffset + t * this.data.BYTES_PER_ELEMENT
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
free() {
|
|
26
|
+
this.buffer.free(this.data.byteOffset);
|
|
27
|
+
}
|
|
28
|
+
getSharedMemory() {
|
|
29
|
+
return {
|
|
30
|
+
bufferPosition: this.bufferPosition,
|
|
31
|
+
bufferByteOffset: this.bufferByteOffset
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
u as default
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=allocated-memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allocated-memory.js","sources":["../src/allocated-memory.ts"],"sourcesContent":["import type { TypedArray } from './interfaces/typed-array';\nimport type { TypedArrayConstructor } from './interfaces/typed-array-constructor';\nimport type MemoryBuffer from './memory-buffer';\nimport type MemoryHeap from './memory-heap';\nimport { createPointer } from './utils/pointer';\n\nexport default class AllocatedMemory {\n\tprivate readonly memory: MemoryHeap;\n\n\treadonly bufferPosition: number;\n\tget bufferByteOffset(): number {\n\t\treturn this.data.byteOffset;\n\t}\n\tget pointer(): number {\n\t\treturn createPointer(this.bufferPosition, this.bufferByteOffset);\n\t}\n\tprivate buffer: MemoryBuffer;\n\tdata: Uint32Array;\n\n\tconstructor(memory: MemoryHeap, config: AllocatedMemoryConfig | SharedAllocatedMemory) {\n\t\tthis.memory = memory;\n\n\t\tif('buffer' in config) {\n\t\t\tthis.data = config.data;\n\t\t\tthis.buffer = config.buffer;\n\t\t\tthis.bufferPosition = this.memory.buffers.indexOf(config.buffer);\n\t\t} else {\n\t\t\tthis.bufferPosition = config.bufferPosition;\n\t\t\tthis.buffer = memory.buffers[config.bufferPosition];\n\n\t\t\t// Making sure these are the correct size is slow but in dev we want to make sure we aren't allowing to go out of bounds\n\t\t\tif(import.meta.env.MODE === 'production') {\n\t\t\t\tthis.data = new Uint32Array(this.buffer.buf, config.bufferByteOffset);\n\t\t\t} else {\n\t\t\t\tthis.data = new Uint32Array(this.buffer.buf, config.bufferByteOffset, this.buffer.lengthOf(config.bufferByteOffset));\n\t\t\t}\n\t\t}\n\t}\n\n\tgetArray<T extends TypedArray>(type: TypedArrayConstructor<T>, offset: number, length: number): T {\n\t\tif(import.meta.env.MODE === 'development' || import.meta.env.MODE === 'test') {\n\t\t\tif((offset + length) * type.BYTES_PER_ELEMENT > this.data.byteLength) {\n\t\t\t\tconst message = `Trying to grab more memory from AllocatedMemory.getArray then we have: ${offset * type.BYTES_PER_ELEMENT} + ${length * type.BYTES_PER_ELEMENT} > ${this.data.byteLength}`;\n\t\t\t\tif(import.meta.env.MODE === 'test') {\n\t\t\t\t\tthrow new Error(message);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(message);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn new type(this.data.buffer, this.data.byteOffset + offset * type.BYTES_PER_ELEMENT, length);\n\t}\n\tgetArrayMemory(offset: number, length: number): SharedAllocatedMemory {\n\t\tif(import.meta.env.MODE === 'development') {\n\t\t\tif(offset + length > this.data.length) {\n\t\t\t\tconsole.warn(`Trying to grab more memory from AllocatedMemory.getArrayMemory then we have: ${offset} + ${length} > ${this.data.length}`);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tbufferPosition: this.bufferPosition,\n\t\t\tbufferByteOffset: this.bufferByteOffset + offset * this.data.BYTES_PER_ELEMENT\n\t\t};\n\t}\n\n\tfree() {\n\t\t// NOTE: From worker thread you can't pass the array, you have to pass an explicit address to free\n\t\tthis.buffer.free(this.data.byteOffset);\n\t}\n\n\tgetSharedMemory(): SharedAllocatedMemory {\n\t\treturn {\n\t\t\tbufferPosition: this.bufferPosition,\n\t\t\tbufferByteOffset: this.bufferByteOffset\n\t\t};\n\t}\n}\n\ninterface AllocatedMemoryConfig {\n\tdata: Uint32Array\n\tbuffer: MemoryBuffer\n}\n\ninterface SharedAllocatedMemory {\n\tbufferPosition: number\n\tbufferByteOffset: number\n}\nexport type { SharedAllocatedMemory };"],"names":["AllocatedMemory","createPointer","memory","config","type","offset","length"],"mappings":";AAMA,MAAqBA,EAAgB;AAAA,EACnB;AAAA,EAER;AAAA,EACT,IAAI,mBAA2B;AAC9B,WAAO,KAAK,KAAK;AAAA,EAClB;AAAA,EACA,IAAI,UAAkB;AACrB,WAAOC,EAAc,KAAK,gBAAgB,KAAK,gBAAgB;AAAA,EAChE;AAAA,EACQ;AAAA,EACR;AAAA,EAEA,YAAYC,GAAoBC,GAAuD;AACtF,SAAK,SAASD,GAEX,YAAYC,KACd,KAAK,OAAOA,EAAO,MACnB,KAAK,SAASA,EAAO,QACrB,KAAK,iBAAiB,KAAK,OAAO,QAAQ,QAAQA,EAAO,MAAM,MAE/D,KAAK,iBAAiBA,EAAO,gBAC7B,KAAK,SAASD,EAAO,QAAQC,EAAO,cAAc,GAIjD,KAAK,OAAO,IAAI,YAAY,KAAK,OAAO,KAAKA,EAAO,gBAAgB;AAAA,EAKvE;AAAA,EAEA,SAA+BC,GAAgCC,GAAgBC,GAAmB;AAYjG,WAAO,IAAIF,EAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,aAAaC,IAASD,EAAK,mBAAmBE,CAAM;AAAA,EACjG;AAAA,EACA,eAAeD,GAAgBC,GAAuC;AAOrE,WAAO;AAAA,MACN,gBAAgB,KAAK;AAAA,MACrB,kBAAkB,KAAK,mBAAmBD,IAAS,KAAK,KAAK;AAAA,IAAA;AAAA,EAE/D;AAAA,EAEA,OAAO;AAEN,SAAK,OAAO,KAAK,KAAK,KAAK,UAAU;AAAA,EACtC;AAAA,EAEA,kBAAyC;AACxC,WAAO;AAAA,MACN,gBAAgB,KAAK;AAAA,MACrB,kBAAkB,KAAK;AAAA,IAAA;AAAA,EAEzB;AACD;"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import h from "./shared-list.js";
|
|
2
|
+
class c {
|
|
3
|
+
static ALLOCATE_COUNT = h.ALLOCATE_COUNT;
|
|
4
|
+
heap;
|
|
5
|
+
list;
|
|
6
|
+
cache = /* @__PURE__ */ new Map();
|
|
7
|
+
constructor(t, e) {
|
|
8
|
+
e ? this.list = new h(t, e) : this.list = new h(t), this.heap = t, this.list.onDelete = (i) => {
|
|
9
|
+
let r = Atomics.load(i, 0);
|
|
10
|
+
if (r) {
|
|
11
|
+
let s = this.cache.get(r);
|
|
12
|
+
s || (s = this.initItem(r)), s && (s.free(), this.cache.delete(r));
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
get length() {
|
|
17
|
+
return this.list.length;
|
|
18
|
+
}
|
|
19
|
+
clear() {
|
|
20
|
+
this.list.clear(), this.cache.clear();
|
|
21
|
+
}
|
|
22
|
+
insert(t) {
|
|
23
|
+
this.list.insert(t.pointer), this.cache.set(t.pointer, t);
|
|
24
|
+
}
|
|
25
|
+
delete(t) {
|
|
26
|
+
return this.cache.delete(t.pointer), this.list.deleteValue(t.pointer);
|
|
27
|
+
}
|
|
28
|
+
getByPointer(t) {
|
|
29
|
+
let e = this.cache.get(t);
|
|
30
|
+
return e || (e = this.initItem(t), e && this.cache.set(t, e)), e;
|
|
31
|
+
}
|
|
32
|
+
*[Symbol.iterator]() {
|
|
33
|
+
let t = this.list[Symbol.iterator]();
|
|
34
|
+
for (let { data: e, deleteCurrent: i } of t) {
|
|
35
|
+
let r = Atomics.load(e, 0);
|
|
36
|
+
if (!r)
|
|
37
|
+
continue;
|
|
38
|
+
let s = this.cache.get(r);
|
|
39
|
+
s || (s = this.initItem(r), s && this.cache.set(r, s)), s && (yield {
|
|
40
|
+
item: s,
|
|
41
|
+
deleteCurrent: i
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
forEach(t, e) {
|
|
46
|
+
for (let { item: i } of this)
|
|
47
|
+
(!e || e(i)) && t(i);
|
|
48
|
+
}
|
|
49
|
+
find(t) {
|
|
50
|
+
for (let { item: e } of this)
|
|
51
|
+
if (t(e))
|
|
52
|
+
return e;
|
|
53
|
+
}
|
|
54
|
+
filter(t) {
|
|
55
|
+
let e = [];
|
|
56
|
+
for (let { item: i } of this)
|
|
57
|
+
t(i) && e.push(i);
|
|
58
|
+
return e;
|
|
59
|
+
}
|
|
60
|
+
map(t) {
|
|
61
|
+
const e = [];
|
|
62
|
+
for (let { item: i } of this)
|
|
63
|
+
e.push(t(i));
|
|
64
|
+
return e;
|
|
65
|
+
}
|
|
66
|
+
getSharedMemory() {
|
|
67
|
+
return this.list.getSharedMemory();
|
|
68
|
+
}
|
|
69
|
+
free() {
|
|
70
|
+
this.list.free(), this.cache.clear();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export {
|
|
74
|
+
c as default
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=cached-item-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cached-item-list.js","sources":["../src/cached-item-list.ts"],"sourcesContent":["import type { SharedAllocatedMemory } from './allocated-memory';\nimport type MemoryHeap from './memory-heap';\nimport SharedList, { type SharedListMemory } from './shared-list';\n\nexport default abstract class CachedItemList<T extends Item> implements Iterable<{ item: T, deleteCurrent: () => void }> {\n\tstatic readonly ALLOCATE_COUNT = SharedList.ALLOCATE_COUNT;\n\n\tprotected heap: MemoryHeap;\n\tprotected list: SharedList;\n\tprotected cache: Map<number, T> = new Map();\n\n\tconstructor(heap: MemoryHeap, config?: CachedListConfig | SharedListMemory) {\n\t\tif(config) {\n\t\t\tthis.list = new SharedList(heap, config);\n\t\t} else {\n\t\t\tthis.list = new SharedList(heap);\n\t\t}\n\t\tthis.heap = heap;\n\n\t\tthis.list.onDelete = (pointerData: Uint32Array) => {\n\t\t\tlet pointer = Atomics.load(pointerData, 0);\n\t\t\tif(pointer) {\n\t\t\t\tlet item = this.cache.get(pointer);\n\t\t\t\tif(!item) {\n\t\t\t\t\titem = this.initItem(pointer);\n\t\t\t\t}\n\n\t\t\t\tif(item) {\n\t\t\t\t\titem.free();\n\t\t\t\t\tthis.cache.delete(pointer);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\tget length() {\n\t\treturn this.list.length;\n\t}\n\n\tclear() {\n\t\tthis.list.clear();\n\t\tthis.cache.clear();\n\t}\n\n\tinsert(item: T) {\n\t\tthis.list.insert(item.pointer);\n\t\tthis.cache.set(item.pointer, item);\n\t}\n\tdelete(item: T) {\n\t\tthis.cache.delete(item.pointer);\n\t\treturn this.list.deleteValue(item.pointer);\n\t}\n\n\tgetByPointer(pointer: number): T | undefined {\n\t\tlet item = this.cache.get(pointer);\n\t\tif(!item) {\n\t\t\titem = this.initItem(pointer);\n\t\t\tif(item) {\n\t\t\t\tthis.cache.set(pointer, item);\n\t\t\t}\n\t\t}\n\n\t\treturn item;\n\t}\n\tprotected abstract initItem(pointer: number): T | undefined\n\n\t*[Symbol.iterator]() {\n\t\tlet iterator = this.list[Symbol.iterator]();\n\n\t\tfor(let { data: pointerData, deleteCurrent } of iterator) {\n\t\t\tlet pointer = Atomics.load(pointerData, 0);\n\t\t\tif(!pointer) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet item = this.cache.get(pointer);\n\t\t\tif(!item) {\n\t\t\t\titem = this.initItem(pointer);\n\t\t\t\tif(item) {\n\t\t\t\t\tthis.cache.set(pointer, item);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(item) {\n\t\t\t\tyield {\n\t\t\t\t\titem,\n\t\t\t\t\tdeleteCurrent\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\tforEach(callback: (item: T) => void, filter?: (item: T) => boolean) {\n\t\tfor(let { item } of this) {\n\t\t\tif(!filter || filter(item)) {\n\t\t\t\tcallback(item);\n\t\t\t}\n\t\t}\n\t}\n\n\tfind(callback: (item: T) => boolean): T | undefined {\n\t\tfor(let { item } of this) {\n\t\t\tif(callback(item)) {\n\t\t\t\treturn item;\n\t\t\t}\n\t\t}\n\t}\n\tfilter(callback: (entity: T) => boolean): Array<T> {\n\t\tlet items = [];\n\t\tfor(let { item } of this) {\n\t\t\tif(callback(item)) {\n\t\t\t\titems.push(item);\n\t\t\t}\n\t\t}\n\n\t\treturn items;\n\t}\n\tmap<X>(callback: (item: T) => X): Array<X> {\n\t\tconst array: Array<X> = [];\n\t\tfor(let { item } of this) {\n\t\t\tarray.push(callback(item));\n\t\t}\n\n\t\treturn array;\n\t}\n\n\tgetSharedMemory() {\n\t\treturn this.list.getSharedMemory();\n\t}\n\n\tfree() {\n\t\tthis.list.free();\n\t\tthis.cache.clear();\n\t}\n}\n\nexport interface CachedListConfig {\n\tinitWithBlock: SharedAllocatedMemory\n}\n\ninterface Item {\n\tpointer: number\n\tfree: () => void\n}"],"names":["CachedItemList","SharedList","heap","config","pointerData","pointer","item","iterator","deleteCurrent","callback","filter","items","array"],"mappings":";AAIA,MAA8BA,EAA2F;AAAA,EACxH,OAAgB,iBAAiBC,EAAW;AAAA,EAElC;AAAA,EACA;AAAA,EACA,4BAA4B,IAAA;AAAA,EAEtC,YAAYC,GAAkBC,GAA8C;AAC3E,IAAGA,IACF,KAAK,OAAO,IAAIF,EAAWC,GAAMC,CAAM,IAEvC,KAAK,OAAO,IAAIF,EAAWC,CAAI,GAEhC,KAAK,OAAOA,GAEZ,KAAK,KAAK,WAAW,CAACE,MAA6B;AAClD,UAAIC,IAAU,QAAQ,KAAKD,GAAa,CAAC;AACzC,UAAGC,GAAS;AACX,YAAIC,IAAO,KAAK,MAAM,IAAID,CAAO;AACjC,QAAIC,MACHA,IAAO,KAAK,SAASD,CAAO,IAG1BC,MACFA,EAAK,KAAA,GACL,KAAK,MAAM,OAAOD,CAAO;AAAA,MAE3B;AAAA,IACD;AAAA,EACD;AAAA,EAEA,IAAI,SAAS;AACZ,WAAO,KAAK,KAAK;AAAA,EAClB;AAAA,EAEA,QAAQ;AACP,SAAK,KAAK,MAAA,GACV,KAAK,MAAM,MAAA;AAAA,EACZ;AAAA,EAEA,OAAOC,GAAS;AACf,SAAK,KAAK,OAAOA,EAAK,OAAO,GAC7B,KAAK,MAAM,IAAIA,EAAK,SAASA,CAAI;AAAA,EAClC;AAAA,EACA,OAAOA,GAAS;AACf,gBAAK,MAAM,OAAOA,EAAK,OAAO,GACvB,KAAK,KAAK,YAAYA,EAAK,OAAO;AAAA,EAC1C;AAAA,EAEA,aAAaD,GAAgC;AAC5C,QAAIC,IAAO,KAAK,MAAM,IAAID,CAAO;AACjC,WAAIC,MACHA,IAAO,KAAK,SAASD,CAAO,GACzBC,KACF,KAAK,MAAM,IAAID,GAASC,CAAI,IAIvBA;AAAA,EACR;AAAA,EAGA,EAAE,OAAO,QAAQ,IAAI;AACpB,QAAIC,IAAW,KAAK,KAAK,OAAO,QAAQ,EAAA;AAExC,aAAQ,EAAE,MAAMH,GAAa,eAAAI,EAAA,KAAmBD,GAAU;AACzD,UAAIF,IAAU,QAAQ,KAAKD,GAAa,CAAC;AACzC,UAAG,CAACC;AACH;AAGD,UAAIC,IAAO,KAAK,MAAM,IAAID,CAAO;AACjC,MAAIC,MACHA,IAAO,KAAK,SAASD,CAAO,GACzBC,KACF,KAAK,MAAM,IAAID,GAASC,CAAI,IAI3BA,MACF,MAAM;AAAA,QACL,MAAAA;AAAA,QACA,eAAAE;AAAA,MAAA;AAAA,IAGH;AAAA,EACD;AAAA,EACA,QAAQC,GAA6BC,GAA+B;AACnE,aAAQ,EAAE,MAAAJ,EAAA,KAAU;AACnB,OAAG,CAACI,KAAUA,EAAOJ,CAAI,MACxBG,EAASH,CAAI;AAAA,EAGhB;AAAA,EAEA,KAAKG,GAA+C;AACnD,aAAQ,EAAE,MAAAH,EAAA,KAAU;AACnB,UAAGG,EAASH,CAAI;AACf,eAAOA;AAAA,EAGV;AAAA,EACA,OAAOG,GAA4C;AAClD,QAAIE,IAAQ,CAAA;AACZ,aAAQ,EAAE,MAAAL,EAAA,KAAU;AACnB,MAAGG,EAASH,CAAI,KACfK,EAAM,KAAKL,CAAI;AAIjB,WAAOK;AAAA,EACR;AAAA,EACA,IAAOF,GAAoC;AAC1C,UAAMG,IAAkB,CAAA;AACxB,aAAQ,EAAE,MAAAN,EAAA,KAAU;AACnB,MAAAM,EAAM,KAAKH,EAASH,CAAI,CAAC;AAG1B,WAAOM;AAAA,EACR;AAAA,EAEA,kBAAkB;AACjB,WAAO,KAAK,KAAK,gBAAA;AAAA,EAClB;AAAA,EAEA,OAAO;AACN,SAAK,KAAK,KAAA,GACV,KAAK,MAAM,MAAA;AAAA,EACZ;AACD;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pow2.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-array-constructor.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-array.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import n from "./allocated-memory.js";
|
|
2
|
+
import { getPointer as o } from "./utils/pointer.js";
|
|
3
|
+
class g {
|
|
4
|
+
memory;
|
|
5
|
+
pointers = [];
|
|
6
|
+
recycledIndexes = [];
|
|
7
|
+
totalLength = 0;
|
|
8
|
+
maxChunkSize = 100;
|
|
9
|
+
dataLength = 1;
|
|
10
|
+
byteMultipler = 1;
|
|
11
|
+
typeConstructor;
|
|
12
|
+
fullDataBlocks = {};
|
|
13
|
+
get length() {
|
|
14
|
+
return this.totalLength - this.recycledIndexes.length;
|
|
15
|
+
}
|
|
16
|
+
get bufferLength() {
|
|
17
|
+
return this.maxChunkSize * this.pointers.length;
|
|
18
|
+
}
|
|
19
|
+
constructor(t, e) {
|
|
20
|
+
this.memory = t;
|
|
21
|
+
const a = e?.dataLength ?? 1, h = e?.maxChunkSize ?? 100;
|
|
22
|
+
this.dataLength = a, this.maxChunkSize = h, this.typeConstructor = e.type, this.typeConstructor === Float64Array && (this.byteMultipler = 2);
|
|
23
|
+
let i = t.allocUI32(h * a * this.byteMultipler);
|
|
24
|
+
this.pointers.push(i.pointer);
|
|
25
|
+
let s = new this.typeConstructor(i.data.buffer, i.bufferByteOffset, this.dataLength * this.maxChunkSize);
|
|
26
|
+
this.fullDataBlocks[0] = s;
|
|
27
|
+
}
|
|
28
|
+
at(t) {
|
|
29
|
+
let e = this.fullDataBlocks[Math.floor(t / this.maxChunkSize)];
|
|
30
|
+
return this.getDataBlock(e, t % this.maxChunkSize);
|
|
31
|
+
}
|
|
32
|
+
get(t, e = 0) {
|
|
33
|
+
const a = this.dataLength;
|
|
34
|
+
if (e >= a)
|
|
35
|
+
throw new Error(`${e} is out of dataLength bounds ${a}`);
|
|
36
|
+
return this.fullDataBlocks[Math.floor(t / this.maxChunkSize)][t % this.maxChunkSize * a + e];
|
|
37
|
+
}
|
|
38
|
+
push(t) {
|
|
39
|
+
const e = typeof t == "number";
|
|
40
|
+
if (!e && t.length > this.dataLength)
|
|
41
|
+
throw new Error(`Can't insert ${t.length} array into shared list of ${this.dataLength} dataLength`);
|
|
42
|
+
let a = this.recycledIndexes.pop();
|
|
43
|
+
a === void 0 && (a = this.totalLength++);
|
|
44
|
+
let h = Math.floor(a / this.maxChunkSize);
|
|
45
|
+
if (h >= this.pointers.length) {
|
|
46
|
+
let l = this.memory.allocUI32(this.maxChunkSize * this.dataLength * this.byteMultipler);
|
|
47
|
+
this.pointers.push(l.pointer);
|
|
48
|
+
let u = new this.typeConstructor(l.data.buffer, l.bufferByteOffset, this.dataLength * this.maxChunkSize);
|
|
49
|
+
this.fullDataBlocks[h] = u;
|
|
50
|
+
}
|
|
51
|
+
let i = this.fullDataBlocks[h], s = a % this.maxChunkSize, r = this.dataLength * s;
|
|
52
|
+
return e ? i[r] = t : i.set(t, r), a;
|
|
53
|
+
}
|
|
54
|
+
deleteIndex(t) {
|
|
55
|
+
this.recycledIndexes.push(t);
|
|
56
|
+
}
|
|
57
|
+
clear() {
|
|
58
|
+
this.totalLength = 0, this.recycledIndexes = [];
|
|
59
|
+
}
|
|
60
|
+
*[Symbol.iterator]() {
|
|
61
|
+
const t = {};
|
|
62
|
+
for (let h of this.recycledIndexes)
|
|
63
|
+
t[h] = !0;
|
|
64
|
+
let e = this.getFullDataBlock(0), a = 0;
|
|
65
|
+
for (let h = 0; h < this.totalLength; h++)
|
|
66
|
+
if (!t[h]) {
|
|
67
|
+
let i = Math.floor(h / this.maxChunkSize);
|
|
68
|
+
i !== a && (e = this.getFullDataBlock(h), a = i), yield this.getDataBlock(e, h % this.maxChunkSize);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
getFullDataBlock(t) {
|
|
72
|
+
let e = Math.floor(t / this.maxChunkSize), a = this.fullDataBlocks[e];
|
|
73
|
+
if (a)
|
|
74
|
+
return a;
|
|
75
|
+
if (e >= this.pointers.length) {
|
|
76
|
+
let s = this.memory.allocUI32(this.maxChunkSize * this.dataLength * this.byteMultipler);
|
|
77
|
+
this.pointers.push(s.pointer);
|
|
78
|
+
}
|
|
79
|
+
let h = new n(this.memory, o(this.pointers[e])), i = new this.typeConstructor(h.data.buffer, h.bufferByteOffset, this.dataLength * this.maxChunkSize);
|
|
80
|
+
return this.fullDataBlocks[e] = i, i;
|
|
81
|
+
}
|
|
82
|
+
getDataBlock(t, e) {
|
|
83
|
+
const a = e * this.dataLength;
|
|
84
|
+
return t.subarray(a, a + this.dataLength);
|
|
85
|
+
}
|
|
86
|
+
free() {
|
|
87
|
+
for (let t of this.pointers)
|
|
88
|
+
new n(this.memory, o(t)).free();
|
|
89
|
+
this.pointers = [], this.recycledIndexes = [], this.totalLength = 0, this.fullDataBlocks = {};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
g as default
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=local-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-pool.js","sources":["../src/local-pool.ts"],"sourcesContent":["import AllocatedMemory from './allocated-memory';\nimport type { TypedArrayConstructor } from './interfaces/typed-array-constructor';\nimport type MemoryHeap from './memory-heap';\nimport { getPointer } from './utils/pointer';\n\n// Array with stable indexes and maximum contiguous memory sizes (necessary to fit large data sets into max 1MB buffers)\n// Can only do insert/deletions from a single thread - useful if other threads are known to be read-only\nexport default class LocalPool<T extends Uint32Array | Int32Array | Float32Array | Float64Array = Uint32Array> implements Iterable<T> {\n\tprivate memory: MemoryHeap;\n\tprivate pointers: Array<number> = [];\n\tprivate recycledIndexes: Array<number> = [];\n\tprivate totalLength = 0;\n\treadonly maxChunkSize: number = 100;\n\treadonly dataLength: number = 1;\n\treadonly byteMultipler: number = 1;\n\tprivate typeConstructor: TypedArrayConstructor<T>;\n\tprivate fullDataBlocks: { [key: number]: T } = {};\n\n\tget length(): number {\n\t\treturn this.totalLength - this.recycledIndexes.length;\n\t}\n\tget bufferLength(): number {\n\t\treturn this.maxChunkSize * this.pointers.length;\n\t}\n\n\tconstructor(memory: MemoryHeap, config: LocalPoolConfig<T>) {\n\t\tthis.memory = memory;\n\n\t\tconst dataLength = config?.dataLength ?? 1;\n\t\tconst maxLength = config?.maxChunkSize ?? 100;\n\t\tthis.dataLength = dataLength;\n\t\tthis.maxChunkSize = maxLength;\n\n\t\tthis.typeConstructor = config.type;\n\t\t// @ts-expect-error\n\t\tif(this.typeConstructor === Float64Array) {\n\t\t\tthis.byteMultipler = 2;\n\t\t}\n\n\t\tlet firstArray = memory.allocUI32(maxLength * dataLength * this.byteMultipler);\n\t\tthis.pointers.push(firstArray.pointer);\n\t\tlet data: T = new this.typeConstructor(firstArray.data.buffer, firstArray.bufferByteOffset, this.dataLength * this.maxChunkSize) as T;\n\t\tthis.fullDataBlocks[0] = data;\n\t}\n\n\tat(index: number): T {\n\t\tlet dataBlock = this.fullDataBlocks[Math.floor(index / this.maxChunkSize)];\n\t\treturn this.getDataBlock(dataBlock, index % this.maxChunkSize);\n\t}\n\tget(index: number, dataIndex = 0): number {\n\t\tconst dataLength = this.dataLength;\n\t\tif(dataIndex >= dataLength) {\n\t\t\tthrow new Error(`${dataIndex} is out of dataLength bounds ${dataLength}`);\n\t\t}\n\n\t\tlet dataBlock = this.fullDataBlocks[Math.floor(index / this.maxChunkSize)];\n\t\treturn dataBlock[(index % this.maxChunkSize) * dataLength + dataIndex];\n\t}\n\n\tpush(values: number | Array<number>): number {\n\t\tconst isSingleNumber = typeof values === 'number';\n\t\tif(!isSingleNumber && values.length > this.dataLength) {\n\t\t\tthrow new Error(`Can't insert ${values.length} array into shared list of ${this.dataLength} dataLength`);\n\t\t}\n\n\t\tlet newIndex = this.recycledIndexes.pop();\n\t\tif(newIndex === undefined) {\n\t\t\tnewIndex = this.totalLength++;\n\t\t}\n\t\t\n\t\t\n\t\tlet pointerIndex = Math.floor(newIndex / this.maxChunkSize);\n\t\tif(pointerIndex >= this.pointers.length) {\n\t\t\tlet newArray = this.memory.allocUI32(this.maxChunkSize * this.dataLength * this.byteMultipler);\n\t\t\tthis.pointers.push(newArray.pointer);\n\t\t\tlet data: T = new this.typeConstructor(newArray.data.buffer, newArray.bufferByteOffset, this.dataLength * this.maxChunkSize) as T;\n\t\t\tthis.fullDataBlocks[pointerIndex] = data;\n\t\t}\n\n\t\tlet dataBlock = this.fullDataBlocks[pointerIndex];\n\t\tlet blockIndex = newIndex % this.maxChunkSize;\n\t\tlet startIndex = this.dataLength * blockIndex;\n\t\tif(isSingleNumber) {\n\t\t\tdataBlock[startIndex] = values;\n\t\t} else {\n\t\t\tdataBlock.set(values, startIndex);\n\t\t}\n\n\t\treturn newIndex;\n\t}\n\n\tdeleteIndex(index: number) {\n\t\tthis.recycledIndexes.push(index);\n\t}\n\n\tclear() {\n\t\tthis.totalLength = 0;\n\t\tthis.recycledIndexes = [];\n\t}\n\n\t*[Symbol.iterator]() {\n\t\tconst recycledValues: { [key: number]: true } = {};\n\t\tfor(let value of this.recycledIndexes) {\n\t\t\trecycledValues[value] = true;\n\t\t}\n\n\t\tlet dataBlock = this.getFullDataBlock(0);\n\t\tlet dataBlockIndex = 0;\n\t\tfor(let i = 0; i < this.totalLength; i++) {\n\t\t\tif(!recycledValues[i]) {\n\t\t\t\tlet newDataBlockIndex = Math.floor(i / this.maxChunkSize);\n\t\t\t\tif(newDataBlockIndex !== dataBlockIndex) {\n\t\t\t\t\tdataBlock = this.getFullDataBlock(i);\n\t\t\t\t\tdataBlockIndex = newDataBlockIndex;\n\t\t\t\t}\n\t\t\t\tyield this.getDataBlock(dataBlock, i % this.maxChunkSize);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getFullDataBlock(index: number) {\n\t\tlet pointerIndex = Math.floor(index / this.maxChunkSize);\n\t\tlet cachedDataBlock = this.fullDataBlocks[pointerIndex];\n\t\tif(cachedDataBlock) {\n\t\t\treturn cachedDataBlock;\n\t\t}\n\t\tif(pointerIndex >= this.pointers.length) {\n\t\t\tlet newArray = this.memory.allocUI32(this.maxChunkSize * this.dataLength * this.byteMultipler);\n\t\t\tthis.pointers.push(newArray.pointer);\n\t\t}\n\n\t\tlet array = new AllocatedMemory(this.memory, getPointer(this.pointers[pointerIndex]));\n\t\tlet data: T = new this.typeConstructor(array.data.buffer, array.bufferByteOffset, this.dataLength * this.maxChunkSize) as T;\n\t\tthis.fullDataBlocks[pointerIndex] = data;\n\t\treturn data;\n\t}\n\n\tprivate getDataBlock(rawData: T, index: number): T {\n\t\tconst start = index * this.dataLength;\n\t\treturn rawData.subarray(start, start + this.dataLength) as T;\n\t}\n\n\tfree() {\n\t\tfor(let pointer of this.pointers) {\n\t\t\tlet memory = new AllocatedMemory(this.memory, getPointer(pointer));\n\t\t\tmemory.free();\n\t\t}\n\t\tthis.pointers = [];\n\t\tthis.recycledIndexes = [];\n\t\tthis.totalLength = 0;\n\t\tthis.fullDataBlocks = {};\n\t}\n}\n\ninterface LocalPoolConfig<T extends Uint32Array | Int32Array | Float32Array | Float64Array> {\n\tmaxChunkSize?: number\n\ttype: TypedArrayConstructor<T>\n\tdataLength?: number\n}\nexport type { LocalPoolConfig };"],"names":["LocalPool","memory","config","dataLength","maxLength","firstArray","data","index","dataBlock","dataIndex","values","isSingleNumber","newIndex","pointerIndex","newArray","blockIndex","startIndex","recycledValues","value","dataBlockIndex","i","newDataBlockIndex","cachedDataBlock","array","AllocatedMemory","getPointer","rawData","start","pointer"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
function n(o, c = 0) {
|
|
2
|
+
for (; Atomics.compareExchange(o, c, 0, 1) === 2; )
|
|
3
|
+
Atomics.wait(o, c, 2);
|
|
4
|
+
Atomics.add(o, c + 1, 1);
|
|
5
|
+
}
|
|
6
|
+
function t(o, c = 0) {
|
|
7
|
+
let E = Atomics.compareExchange(o, c, 0, 2);
|
|
8
|
+
for (; E !== 0; )
|
|
9
|
+
Atomics.wait(o, c, E), E = Atomics.compareExchange(o, c, 0, 2);
|
|
10
|
+
}
|
|
11
|
+
function e(o, c = 0) {
|
|
12
|
+
Atomics.sub(o, c + 1, 1) - 1 <= 0 && (Atomics.compareExchange(o, c, 1, 0) !== 1 && console.warn("We are unlocking when it was not read locked!"), Atomics.notify(o, c));
|
|
13
|
+
}
|
|
14
|
+
function i(o, c = 0) {
|
|
15
|
+
Atomics.compareExchange(o, c, 2, 0) !== 2 && console.warn("We are unlocking when it was not write locked!"), Atomics.notify(o, c);
|
|
16
|
+
}
|
|
17
|
+
const C = 2;
|
|
18
|
+
export {
|
|
19
|
+
C as READ_WRITE_LOCK_ALLOCATE_COUNT,
|
|
20
|
+
n as readLock,
|
|
21
|
+
e as readUnlock,
|
|
22
|
+
t as writeLock,
|
|
23
|
+
i as writeUnlock
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=read-write-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-write-lock.js","sources":["../../src/lock/read-write-lock.ts"],"sourcesContent":["const UNLOCKED = 0;\nconst READ_LOCKED = 1;\nconst WRITE_LOCKED = 2;\n\nexport function readLock(data: Int32Array, index: number = 0) {\n\t// Wait over and over again until we get that it was unlocked or read locked\n\twhile(Atomics.compareExchange(data, index, UNLOCKED, READ_LOCKED) === WRITE_LOCKED) {\n\t\tAtomics.wait(data, index, WRITE_LOCKED);\n\t}\n\n\tAtomics.add(data, index + 1, 1);\n}\nexport function writeLock(data: Int32Array, index: number = 0) {\n\t// Write lock needs to be exclusive - wait until we were in UNLOCKED to proceed\n\tlet oldValue = Atomics.compareExchange(data, index, UNLOCKED, WRITE_LOCKED);\n\twhile(oldValue !== UNLOCKED) {\n\t\tAtomics.wait(data, index, oldValue);\n\t\toldValue = Atomics.compareExchange(data, index, UNLOCKED, WRITE_LOCKED);\n\t}\n}\n\nexport function readUnlock(data: Int32Array, index: number = 0) {\n\tlet readCount = Atomics.sub(data, index + 1, 1) - 1;\n\n\tif(readCount <= 0) {\n\t\tif(Atomics.compareExchange(data, index, READ_LOCKED, UNLOCKED) !== READ_LOCKED) {\n\t\t\tconsole.warn('We are unlocking when it was not read locked!');\n\t\t}\n\n\t\tAtomics.notify(data, index);\n\t}\n}\nexport function writeUnlock(data: Int32Array, index: number = 0) {\n\tif(Atomics.compareExchange(data, index, WRITE_LOCKED, UNLOCKED) !== WRITE_LOCKED) {\n\t\tconsole.warn('We are unlocking when it was not write locked!');\n\t}\n\n\tAtomics.notify(data, index);\n}\n\nexport const READ_WRITE_LOCK_ALLOCATE_COUNT = 2;"],"names":["readLock","data","index","writeLock","oldValue","readUnlock","writeUnlock","READ_WRITE_LOCK_ALLOCATE_COUNT"],"mappings":"AAIO,SAASA,EAASC,GAAkBC,IAAgB,GAAG;AAE7D,SAAM,QAAQ,gBAAgBD,GAAMC,GAAO,GAAU,CAAW,MAAM;AACrE,YAAQ,KAAKD,GAAMC,GAAO,CAAY;AAGvC,UAAQ,IAAID,GAAMC,IAAQ,GAAG,CAAC;AAC/B;AACO,SAASC,EAAUF,GAAkBC,IAAgB,GAAG;AAE9D,MAAIE,IAAW,QAAQ,gBAAgBH,GAAMC,GAAO,GAAU,CAAY;AAC1E,SAAME,MAAa;AAClB,YAAQ,KAAKH,GAAMC,GAAOE,CAAQ,GAClCA,IAAW,QAAQ,gBAAgBH,GAAMC,GAAO,GAAU,CAAY;AAExE;AAEO,SAASG,EAAWJ,GAAkBC,IAAgB,GAAG;AAG/D,EAFgB,QAAQ,IAAID,GAAMC,IAAQ,GAAG,CAAC,IAAI,KAElC,MACZ,QAAQ,gBAAgBD,GAAMC,GAAO,GAAa,CAAQ,MAAM,KAClE,QAAQ,KAAK,+CAA+C,GAG7D,QAAQ,OAAOD,GAAMC,CAAK;AAE5B;AACO,SAASI,EAAYL,GAAkBC,IAAgB,GAAG;AAChE,EAAG,QAAQ,gBAAgBD,GAAMC,GAAO,GAAc,CAAQ,MAAM,KACnE,QAAQ,KAAK,gDAAgD,GAG9D,QAAQ,OAAOD,GAAMC,CAAK;AAC3B;AAEO,MAAMK,IAAiC;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
function n(o, c = 0) {
|
|
2
|
+
for (; Atomics.compareExchange(o, c, 0, 1) !== 0; )
|
|
3
|
+
"WorkerGlobalScope" in self && Atomics.wait(o, c, 1);
|
|
4
|
+
}
|
|
5
|
+
function E(o, c = 0) {
|
|
6
|
+
Atomics.compareExchange(o, c, 1, 0) !== 1 && console.warn("We are unlocking when it was not locked!"), Atomics.notify(o, c);
|
|
7
|
+
}
|
|
8
|
+
const L = 1;
|
|
9
|
+
export {
|
|
10
|
+
L as SIMPLE_LOCK_ALLOCATE_COUNT,
|
|
11
|
+
n as lock,
|
|
12
|
+
E as unlock
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=simple-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-lock.js","sources":["../../src/lock/simple-lock.ts"],"sourcesContent":["const UNLOCKED = 0;\nconst LOCKED = 1;\nexport function lock(data: Int32Array, index: number = 0) {\n\t// Wait over and over again until we are one who set this from UNLOCKED to LOCKED\n\twhile(Atomics.compareExchange(data, index, UNLOCKED, LOCKED) !== UNLOCKED) {\n\t\tif('WorkerGlobalScope' in self) {\n\t\t\tAtomics.wait(data, index, LOCKED);\n\t\t} else {\n\t\t\t// TODO: Spin-locks suck....\n\t\t}\n\t}\n}\nexport function unlock(data: Int32Array, index: number = 0) {\n\tif(Atomics.compareExchange(data, index, LOCKED, UNLOCKED) !== LOCKED) {\n\t\tconsole.warn('We are unlocking when it was not locked!');\n\t}\n\n\tAtomics.notify(data, index);\n}\n\nexport const SIMPLE_LOCK_ALLOCATE_COUNT = 1;"],"names":["lock","data","index","unlock","SIMPLE_LOCK_ALLOCATE_COUNT"],"mappings":"AAEO,SAASA,EAAKC,GAAkBC,IAAgB,GAAG;AAEzD,SAAM,QAAQ,gBAAgBD,GAAMC,GAAO,GAAU,CAAM,MAAM;AAChE,IAAG,uBAAuB,QACzB,QAAQ,KAAKD,GAAMC,GAAO,CAAM;AAKnC;AACO,SAASC,EAAOF,GAAkBC,IAAgB,GAAG;AAC3D,EAAG,QAAQ,gBAAgBD,GAAMC,GAAO,GAAQ,CAAQ,MAAM,KAC7D,QAAQ,KAAK,0CAA0C,GAGxD,QAAQ,OAAOD,GAAMC,CAAK;AAC3B;AAEO,MAAME,IAA6B;"}
|