@e280/quay 0.0.0-11 → 0.0.0-13

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.
Files changed (58) hide show
  1. package/README.md +59 -0
  2. package/package.json +2 -1
  3. package/s/cellar/cask.ts +13 -7
  4. package/s/cellar/cellar.test.ts +20 -18
  5. package/s/cellar/cellar.ts +3 -3
  6. package/s/cellar/forklift.ts +2 -2
  7. package/s/cellar/memory-forklift.ts +4 -3
  8. package/s/cellar/opfs-forklift.ts +4 -6
  9. package/s/dom/components/browser/style.css.ts +30 -30
  10. package/s/dom/components/dropzone/style.css.ts +11 -12
  11. package/s/dom/components/filter/component.ts +2 -2
  12. package/s/dom/components/searchbar/component.ts +5 -2
  13. package/s/dom/components/sort/component.ts +3 -3
  14. package/s/dom/theme.css.ts +28 -0
  15. package/s/dom/views/tree/style.css.ts +9 -9
  16. package/s/logic/aspects/codex/parts/hierarchy.ts +1 -0
  17. package/s/logic/group.ts +5 -3
  18. package/s/logic/presets/media/library.test.ts +41 -14
  19. package/s/logic/presets/media/library.ts +25 -17
  20. package/x/cellar/cask.d.ts +4 -4
  21. package/x/cellar/cask.js +13 -9
  22. package/x/cellar/cask.js.map +1 -1
  23. package/x/cellar/cellar.d.ts +1 -1
  24. package/x/cellar/cellar.js +3 -3
  25. package/x/cellar/cellar.js.map +1 -1
  26. package/x/cellar/cellar.test.js +19 -18
  27. package/x/cellar/cellar.test.js.map +1 -1
  28. package/x/cellar/forklift.d.ts +2 -2
  29. package/x/cellar/memory-forklift.d.ts +2 -2
  30. package/x/cellar/memory-forklift.js +3 -2
  31. package/x/cellar/memory-forklift.js.map +1 -1
  32. package/x/cellar/opfs-forklift.d.ts +2 -2
  33. package/x/cellar/opfs-forklift.js +3 -5
  34. package/x/cellar/opfs-forklift.js.map +1 -1
  35. package/x/demo/main.bundle.min.js +104 -71
  36. package/x/demo/main.bundle.min.js.map +2 -2
  37. package/x/dom/components/browser/style.css.js +30 -29
  38. package/x/dom/components/browser/style.css.js.map +1 -1
  39. package/x/dom/components/dropzone/style.css.js +11 -11
  40. package/x/dom/components/filter/component.js +2 -2
  41. package/x/dom/components/searchbar/component.js +5 -1
  42. package/x/dom/components/searchbar/component.js.map +1 -1
  43. package/x/dom/components/sort/component.js +3 -3
  44. package/x/dom/theme.css.js +28 -0
  45. package/x/dom/theme.css.js.map +1 -1
  46. package/x/dom/views/tree/style.css.js +9 -9
  47. package/x/index.html +2 -2
  48. package/x/logic/aspects/codex/parts/hierarchy.js +1 -0
  49. package/x/logic/aspects/codex/parts/hierarchy.js.map +1 -1
  50. package/x/logic/group.d.ts +3 -3
  51. package/x/logic/group.js +3 -2
  52. package/x/logic/group.js.map +1 -1
  53. package/x/logic/presets/media/library.d.ts +4 -40
  54. package/x/logic/presets/media/library.js +21 -16
  55. package/x/logic/presets/media/library.js.map +1 -1
  56. package/x/logic/presets/media/library.test.d.ts +3 -2
  57. package/x/logic/presets/media/library.test.js +34 -14
  58. package/x/logic/presets/media/library.test.js.map +1 -1
@@ -3,40 +3,67 @@ import {Txt} from "@e280/stz"
3
3
  import {expect, Science, test} from "@e280/science"
4
4
 
5
5
  import {MediaLibrary} from "./library.js"
6
+ import {Permissions} from "../../permissions.js"
6
7
 
7
8
  delete (globalThis as any).localStorage
8
9
 
9
10
  export default Science.suite({
10
- "imports files into cellar and index": test(async() => {
11
+ "uploads files into cellar and index": test(async() => {
11
12
  const group = new MediaLibrary()
12
- const file = new File([Txt.toBytes("hello")], "hello.txt", {type: "text/plain"})
13
+ await group.upload([file("hello.txt", "hello")], group.config.root)
13
14
 
14
- const [record] = await group.importFiles([file])
15
+ const record = await recordByLabel(group, "hello.txt")
16
+ const item = group.findByHash(record.hash)!
15
17
 
18
+ expect(item.specimen.label).is("hello.txt")
16
19
  expect(await group.cellar.has(record.hash)).is(true)
17
- expect(group.findByHash(record.hash)?.specimen.label).is("hello.txt")
20
+ }),
21
+
22
+ "upload respects upload permission": test(async() => {
23
+ const group = new MediaLibrary()
24
+ const file = new File([Txt.toBytes("hello")], "hello.txt", {type: "text/plain"})
25
+ group.config.permissions = () => Permissions.readOnly
26
+
27
+ expect(() => group.upload([file], group.config.root)).throws()
18
28
  }),
19
29
 
20
30
  "lists media records": test(async() => {
21
31
  const store = new MediaLibrary()
22
- const file = new File([Txt.toBytes("image")], "image.png", {type: "image/png"})
23
- const record = await store.importFile(file)
24
- const records = []
25
- for await (const record of store.records())
26
- records.push(record)
32
+ await store.upload([file("image.png", "image", "image/png")], store.config.root)
27
33
 
28
- expect(records.some(r => r.hash === record.hash)).is(true)
34
+ expect(await recordByLabel(store, "image.png")).ok()
29
35
  }),
30
36
 
31
- "removes media records and bytes": test(async() => {
37
+ "deletes media records and bytes": test(async() => {
32
38
  const store = new MediaLibrary()
33
- const file = new File([Txt.toBytes("image")], "image.png", {type: "image/png"})
34
- const record = await store.importFile(file)
39
+ await store.upload([file("delete.png", "delete-image", "image/png")], store.config.root)
35
40
 
36
- await store.remove(record.hash)
41
+ const record = await recordByLabel(store, "delete.png")
42
+ const item = store.findByHash(record.hash)!
43
+
44
+ await store.delete(item)
37
45
 
38
46
  expect(await store.cellar.has(record.hash)).is(false)
39
47
  expect(store.findByHash(record.hash)).is(undefined)
40
48
  }),
49
+
41
50
  })
42
51
 
52
+ function file(name: string, text: string, type = "text/plain") {
53
+ return new File([Txt.toBytes(text)], name, {type})
54
+ }
55
+
56
+ async function records(store: MediaLibrary) {
57
+ const records = []
58
+ for await (const record of store.records())
59
+ records.push(record)
60
+ return records
61
+ }
62
+
63
+ async function recordByLabel(store: MediaLibrary, label: string) {
64
+ const record = (await records(store)).find(r => r.label === label)
65
+ if (!record)
66
+ throw new Error(`expected record "${label}"`)
67
+ return record
68
+ }
69
+
@@ -1,9 +1,10 @@
1
1
 
2
2
  import {Kv, StorageDriver} from "@e280/kv"
3
3
 
4
- import {Cellar} from "../../../cellar/cellar.js"
5
- import {MediaFormat} from "./schema.js"
6
4
  import {MediaGroup} from "./group.js"
5
+ import {Cellar} from "../../../cellar/cellar.js"
6
+ import {MediaFormat, MediaSchema} from "./schema.js"
7
+ import {CodexItem} from "../../aspects/codex/parts/codex-item.js"
7
8
 
8
9
  export type MediaRecord = {
9
10
  hash: string
@@ -33,7 +34,11 @@ export class MediaLibrary extends MediaGroup {
33
34
  super()
34
35
  this.#index = mediaIndex("default")
35
36
  this.on.upload.sub(({files, target}) => {
36
- void this.importFiles(files, target)
37
+ return this.#upload(files, target)
38
+ })
39
+ this.on.delete.sub(({items}) => {
40
+ const hashes = this.#hashes(items)
41
+ return this.#delete(hashes)
37
42
  })
38
43
  }
39
44
 
@@ -50,13 +55,12 @@ export class MediaLibrary extends MediaGroup {
50
55
  }
51
56
  }
52
57
 
53
- async importFiles(files: File[], parent = this.config.root) {
54
- return Promise.all(files.map(f => this.importFile(f, parent)))
58
+ async #upload(files: File[], parent: CodexItem<MediaSchema>) {
59
+ await Promise.all(files.map(file => this.#storeFile(file, parent)))
55
60
  }
56
61
 
57
- async importFile(file: File, parent = this.config.root) {
58
- const bytes = new Uint8Array(await file.arrayBuffer())
59
- const cask = await this.cellar.save(bytes)
62
+ async #storeFile(file: File, parent: CodexItem<MediaSchema>) {
63
+ const cask = await this.cellar.save(file)
60
64
  const existing = await this.#index.get(cask.hash)
61
65
  const now = Date.now()
62
66
  const record: MediaRecord = {
@@ -75,15 +79,18 @@ export class MediaLibrary extends MediaGroup {
75
79
  return record
76
80
  }
77
81
 
78
- async remove(hash: string) {
79
- await this.#index.del(hash)
80
- await this.cellar.delete(hash)
81
- const item = this.findByHash(hash)
82
- if (item) {
83
- item.detach()
84
- item.destroy()
82
+ #hashes(items: CodexItem<MediaSchema>[]) {
83
+ return items
84
+ .map(item => item.isKind("file") ? item.specimen.hash : undefined)
85
+ .filter((hash): hash is string => !!hash)
86
+ }
87
+
88
+ async #delete(hashes: string[]) {
89
+ for (const hash of hashes) {
90
+ await this.#index.del(hash)
91
+ await this.cellar.delete(hash)
92
+ this.#revokePreview(hash)
85
93
  }
86
- this.#revokePreview(hash)
87
94
  }
88
95
 
89
96
  findByHash(hash: string) {
@@ -118,7 +125,7 @@ export class MediaLibrary extends MediaGroup {
118
125
 
119
126
  async #loadPreview(record: MediaRecord) {
120
127
  const cask = await this.cellar.load(record.hash)
121
- const blob = new Blob([cask.bytes], {type: record.mime || "image/*"})
128
+ const blob = new Blob([cask.file], {type: record.mime || "image/*"})
122
129
  return this.#setPreview(record.hash, URL.createObjectURL(blob))
123
130
  }
124
131
 
@@ -160,3 +167,4 @@ function mediaIndex(scope: string) {
160
167
  memoryIndexes.set(scope, index)
161
168
  return index
162
169
  }
170
+
@@ -1,8 +1,8 @@
1
1
  /** File with a hash label */
2
2
  export declare class Cask {
3
3
  hash: string;
4
- bytes: Uint8Array;
5
- static hash(bytes: Uint8Array): Promise<string>;
6
- static make(bytes: Uint8Array): Promise<Cask>;
7
- constructor(hash: string, bytes: Uint8Array);
4
+ file: Blob;
5
+ static hash(file: Blob): Promise<string>;
6
+ static make(file: Blob): Promise<Cask>;
7
+ constructor(hash: string, file: Blob);
8
8
  }
package/x/cellar/cask.js CHANGED
@@ -1,19 +1,23 @@
1
1
  import { Hex } from "@e280/stz";
2
+ import { blake3 } from "@noble/hashes/blake3.js";
2
3
  /** File with a hash label */
3
4
  export class Cask {
4
5
  hash;
5
- bytes;
6
- static async hash(bytes) {
7
- const hashBuffer = await crypto.subtle.digest("SHA-256", bytes);
8
- return Hex.fromBytes(new Uint8Array(hashBuffer));
6
+ file;
7
+ static async hash(file) {
8
+ const hasher = blake3.create();
9
+ for await (const chunk of file.stream())
10
+ hasher.update(chunk);
11
+ const digest = hasher.digest();
12
+ return Hex.fromBytes(digest);
9
13
  }
10
- static async make(bytes) {
11
- const hash = await this.hash(bytes);
12
- return new this(hash, bytes);
14
+ static async make(file) {
15
+ const hash = await this.hash(file);
16
+ return new this(hash, file);
13
17
  }
14
- constructor(hash, bytes) {
18
+ constructor(hash, file) {
15
19
  this.hash = hash;
16
- this.bytes = bytes;
20
+ this.file = file;
17
21
  }
18
22
  }
19
23
  //# sourceMappingURL=cask.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cask.js","sourceRoot":"","sources":["../../s/cellar/cask.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAC,MAAM,WAAW,CAAA;AAE7B,6BAA6B;AAC7B,MAAM,OAAO,IAAI;IAWG;IAAqB;IAVxC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAiB;QAClC,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;QAC/D,OAAO,GAAG,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAiB;QAClC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACnC,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IAC7B,CAAC;IAED,YAAmB,IAAY,EAAS,KAAiB;QAAtC,SAAI,GAAJ,IAAI,CAAQ;QAAS,UAAK,GAAL,KAAK,CAAY;IAAG,CAAC;CAC7D"}
1
+ {"version":3,"file":"cask.js","sourceRoot":"","sources":["../../s/cellar/cask.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAC,MAAM,WAAW,CAAA;AAC7B,OAAO,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAA;AAE9C,6BAA6B;AAC7B,MAAM,OAAO,IAAI;IAgBG;IAAqB;IAfxC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAU;QAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAA;QAE9B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE;YACtC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAErB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAA;QAC9B,OAAO,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAU;QAC3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClC,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IAC5B,CAAC;IAED,YAAmB,IAAY,EAAS,IAAU;QAA/B,SAAI,GAAJ,IAAI,CAAQ;QAAS,SAAI,GAAJ,IAAI,CAAM;IAAG,CAAC;CACtD"}
@@ -15,7 +15,7 @@ export declare class Cellar {
15
15
  constructor(forklift?: Forklift);
16
16
  list(): AsyncIterable<string>;
17
17
  has(hash: string): Promise<boolean>;
18
- save(bytes: Uint8Array): Promise<Cask>;
18
+ save(file: Blob): Promise<Cask>;
19
19
  load(hash: string): Promise<Cask>;
20
20
  delete(hash: string): Promise<void>;
21
21
  clear(): Promise<void>;
@@ -24,10 +24,10 @@ export class Cellar {
24
24
  async has(hash) {
25
25
  return this.forklift.has(hash);
26
26
  }
27
- async save(bytes) {
28
- const cask = await Cask.make(bytes);
27
+ async save(file) {
28
+ const cask = await Cask.make(file);
29
29
  if (!await this.forklift.has(cask.hash))
30
- await this.forklift.save(cask.hash, cask.bytes);
30
+ await this.forklift.save(cask.hash, cask.file);
31
31
  return cask;
32
32
  }
33
33
  async load(hash) {
@@ -1 +1 @@
1
- {"version":3,"file":"cellar.js","sourceRoot":"","sources":["../../s/cellar/cellar.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAE9B,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAA;AAEnD;;;;;;;;GAQG;AACH,MAAM,OAAO,MAAM;IAKE;IAJpB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,QAAQ;QACnC,OAAO,IAAI,IAAI,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;IACnD,CAAC;IAED,YAAoB,WAAqB,IAAI,cAAc,EAAE;QAAzC,aAAQ,GAAR,QAAQ,CAAiC;IAAG,CAAC;IAEjE,KAAK,CAAC,CAAC,IAAI;QACV,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAiB;QAC3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACnC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YACtC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;QAChD,OAAO,IAAI,CAAA;IACZ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY;QACtB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACnC,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,IAAI,UAAU,IAAI,CAAC,IAAI,GAAG,CAAC,CAAA;QACjH,OAAO,IAAI,CAAA;IACZ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC;IAED,KAAK,CAAC,KAAK;QACV,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE;YACnC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;CACD"}
1
+ {"version":3,"file":"cellar.js","sourceRoot":"","sources":["../../s/cellar/cellar.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAE9B,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAA;AAEnD;;;;;;;;GAQG;AACH,MAAM,OAAO,MAAM;IAKE;IAJpB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,QAAQ;QACnC,OAAO,IAAI,IAAI,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;IACnD,CAAC;IAED,YAAoB,WAAqB,IAAI,cAAc,EAAE;QAAzC,aAAQ,GAAR,QAAQ,CAAiC;IAAG,CAAC;IAEjE,KAAK,CAAC,CAAC,IAAI;QACV,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAU;QACpB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YACtC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/C,OAAO,IAAI,CAAA;IACZ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY;QACtB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACnC,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,IAAI,UAAU,IAAI,CAAC,IAAI,GAAG,CAAC,CAAA;QACjH,OAAO,IAAI,CAAA;IACZ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC;IAED,KAAK,CAAC,KAAK;QACV,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE;YACnC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;CACD"}
@@ -3,40 +3,41 @@ import { expect, Science, test } from "@e280/science";
3
3
  import { Cask } from "./cask.js";
4
4
  import { Cellar } from "./cellar.js";
5
5
  import { MemoryForklift } from "./memory-forklift.js";
6
+ const blob = (text) => new Blob([Txt.toBytes(text)]);
6
7
  export default Science.suite({
7
8
  "save + load roundtrip": test(async () => {
8
9
  const cellar = new Cellar();
9
10
  const text = "hello world";
10
- const bytes = Txt.toBytes(text);
11
- await cellar.save(bytes);
12
- const hash = await Cask.hash(bytes);
11
+ const file = blob(text);
12
+ await cellar.save(file);
13
+ const hash = await Cask.hash(file);
13
14
  expect(await cellar.has(hash)).is(true);
14
15
  const loaded = await cellar.load(hash);
15
16
  expect(loaded.hash).is(hash);
16
- expect(Txt.fromBytes(loaded.bytes)).is(text);
17
+ expect(await loaded.file.text()).is(text);
17
18
  }),
18
19
  "save is idempotent": test(async () => {
19
20
  const cellar = new Cellar();
20
- const bytes = new TextEncoder().encode("foo bar");
21
- await cellar.save(bytes);
22
- await cellar.save(bytes); // again
23
- const hash = await Cask.hash(bytes);
21
+ const file = blob("foo bar");
22
+ await cellar.save(file);
23
+ await cellar.save(file); // again
24
+ const hash = await Cask.hash(file);
24
25
  expect(await cellar.has(hash)).is(true);
25
26
  }),
26
27
  "throws on corruption": test(async () => {
27
28
  const forklift = new MemoryForklift();
28
29
  const cellar = new Cellar(forklift);
29
- const good = new TextEncoder().encode("valid data");
30
- const bad = new TextEncoder().encode("corrupt data");
30
+ const good = blob("valid data");
31
+ const bad = blob("corrupt data");
31
32
  const hash = await Cask.hash(good);
32
33
  await forklift.save(hash, bad);
33
34
  await expect(async () => cellar.load(hash)).throwsAsync();
34
35
  }),
35
36
  "delete removes file": test(async () => {
36
37
  const cellar = new Cellar();
37
- const bytes = new TextEncoder().encode("temporary data");
38
- await cellar.save(bytes);
39
- const hash = await Cask.hash(bytes);
38
+ const file = blob("temporary data");
39
+ await cellar.save(file);
40
+ const hash = await Cask.hash(file);
40
41
  expect(await cellar.has(hash)).is(true);
41
42
  await cellar.delete(hash);
42
43
  expect(await cellar.has(hash)).is(false);
@@ -50,21 +51,21 @@ export default Science.suite({
50
51
  const cellar = new Cellar();
51
52
  const texts = ["a", "b", "c"];
52
53
  for (const t of texts)
53
- await cellar.save(Txt.toBytes(t));
54
+ await cellar.save(blob(t));
54
55
  const hashes = [];
55
56
  for await (const hash of cellar.list())
56
57
  hashes.push(hash);
57
58
  expect(hashes.length).is(3);
58
59
  for (const t of texts) {
59
- const h = await Cask.hash(Txt.toBytes(t));
60
+ const h = await Cask.hash(blob(t));
60
61
  expect(hashes.includes(h)).is(true);
61
62
  }
62
63
  }),
63
64
  "clear removes all entries": test(async () => {
64
65
  const cellar = new Cellar();
65
- await cellar.save(Txt.toBytes("one"));
66
- await cellar.save(Txt.toBytes("two"));
67
- await cellar.save(Txt.toBytes("three"));
66
+ await cellar.save(blob("one"));
67
+ await cellar.save(blob("two"));
68
+ await cellar.save(blob("three"));
68
69
  let count = 0;
69
70
  for await (const _ of cellar.list())
70
71
  count++;
@@ -1 +1 @@
1
- {"version":3,"file":"cellar.test.js","sourceRoot":"","sources":["../../s/cellar/cellar.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cellar.test.js","sourceRoot":"","sources":["../../s/cellar/cellar.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAC,MAAM,WAAW,CAAA;AAC7B,OAAO,EAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAC,MAAM,eAAe,CAAA;AAEnD,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAClC,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAA;AAEnD,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAE5D,eAAe,OAAO,CAAC,KAAK,CAAC;IAC5B,uBAAuB,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;QACvC,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;QAC3B,MAAM,IAAI,GAAG,aAAa,CAAA;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAA;QACvB,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEvB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClC,MAAM,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;QAEvC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACtC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;QAC5B,MAAM,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;IAC1C,CAAC,CAAC;IAEF,oBAAoB,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;QACpC,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAA;QAC5B,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACvB,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAC,QAAQ;QAEhC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClC,MAAM,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;IACxC,CAAC,CAAC;IAEF,sBAAsB,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;QACtC,MAAM,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAA;QACrC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAA;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,CAAA;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,CAAA;QAEhC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAE9B,MAAM,MAAM,CAAC,KAAK,IAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;IACzD,CAAC,CAAC;IAEF,qBAAqB,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAA;QACnC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEvB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClC,MAAM,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;QAEvC,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACzB,MAAM,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;IACzC,CAAC,CAAC;IAEF,qBAAqB,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;QAC3B,MAAM,QAAQ,GAAG,oBAAoB,CAAA;QAErC,MAAM,MAAM,CAAC,KAAK,IAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;IAC7D,CAAC,CAAC;IAEF,2BAA2B,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;QAC3C,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;QAC3B,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;QAE7B,KAAK,MAAM,CAAC,IAAI,KAAK;YACpB,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;QAE3B,MAAM,MAAM,GAAG,EAAE,CAAA;QACjB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE;YACrC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAElB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAC3B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YAClC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;QACpC,CAAC;IACF,CAAC,CAAC;IAEF,2BAA2B,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;QAC3C,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;QAC3B,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAC9B,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAC9B,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;QAEhC,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE;YAAE,KAAK,EAAE,CAAA;QAC5C,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAEnB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;QAEpB,IAAI,cAAc,GAAG,CAAC,CAAA;QACtB,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE;YAAE,cAAc,EAAE,CAAA;QACrD,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAC7B,CAAC,CAAC;CACF,CAAC,CAAA"}
@@ -1,7 +1,7 @@
1
1
  export type Forklift = {
2
2
  list(): AsyncIterable<string>;
3
3
  has(label: string): Promise<boolean>;
4
- save(label: string, bytes: Uint8Array): Promise<void>;
5
- load(label: string): Promise<Uint8Array>;
4
+ save(label: string, file: Blob): Promise<void>;
5
+ load(label: string): Promise<Blob>;
6
6
  delete(label: string): Promise<void>;
7
7
  };
@@ -3,7 +3,7 @@ export declare class MemoryForklift implements Forklift {
3
3
  #private;
4
4
  list(): AsyncIterable<string>;
5
5
  has(label: string): Promise<boolean>;
6
- save(label: string, bytes: Uint8Array): Promise<void>;
7
- load(label: string): Promise<Uint8Array>;
6
+ save(label: string, file: Blob): Promise<void>;
7
+ load(label: string): Promise<Blob>;
8
8
  delete(label: string): Promise<void>;
9
9
  }
@@ -8,11 +8,12 @@ export class MemoryForklift {
8
8
  async has(label) {
9
9
  return this.#map.has(label);
10
10
  }
11
- async save(label, bytes) {
11
+ async save(label, file) {
12
+ const bytes = new Uint8Array(await file.arrayBuffer());
12
13
  this.#map.set(label, bytes);
13
14
  }
14
15
  async load(label) {
15
- return this.#map.require(label);
16
+ return new Blob([this.#map.require(label)]);
16
17
  }
17
18
  async delete(label) {
18
19
  this.#map.delete(label);
@@ -1 +1 @@
1
- {"version":3,"file":"memory-forklift.js","sourceRoot":"","sources":["../../s/cellar/memory-forklift.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAG9B,MAAM,OAAO,cAAc;IAC1B,IAAI,GAAG,IAAI,IAAI,EAAsB,CAAA;IAErC,KAAK,CAAC,CAAC,IAAI;QACV,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACnC,MAAM,KAAK,CAAA;IACb,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAa;QACtB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,KAAiB;QAC1C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa;QACvB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAChC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa;QACzB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACxB,CAAC;CACD"}
1
+ {"version":3,"file":"memory-forklift.js","sourceRoot":"","sources":["../../s/cellar/memory-forklift.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAG9B,MAAM,OAAO,cAAc;IAC1B,IAAI,GAAG,IAAI,IAAI,EAAsB,CAAA;IAErC,KAAK,CAAC,CAAC,IAAI;QACV,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACnC,MAAM,KAAK,CAAA;IACb,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAa;QACtB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,IAAU;QACnC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAA;QACtD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa;QACvB,OAAO,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa;QACzB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACxB,CAAC;CACD"}
@@ -5,7 +5,7 @@ export declare class OpfsForklift implements Forklift {
5
5
  constructor(directory: FileSystemDirectoryHandle);
6
6
  list(): AsyncIterable<string>;
7
7
  has(label: string): Promise<boolean>;
8
- save(label: string, bytes: Uint8Array): Promise<void>;
9
- load(label: string): Promise<Uint8Array>;
8
+ save(label: string, file: Blob): Promise<void>;
9
+ load(label: string): Promise<Blob>;
10
10
  delete(label: string): Promise<void>;
11
11
  }
@@ -25,17 +25,15 @@ export class OpfsForklift {
25
25
  throw err;
26
26
  }
27
27
  }
28
- async save(label, bytes) {
28
+ async save(label, file) {
29
29
  const fileHandle = await this.directory.getFileHandle(label, { create: true });
30
30
  const writable = await fileHandle.createWritable();
31
- await writable.write(bytes);
31
+ await writable.write(file);
32
32
  await writable.close();
33
33
  }
34
34
  async load(label) {
35
35
  const fileHandle = await this.directory.getFileHandle(label);
36
- const file = await fileHandle.getFile();
37
- const buffer = await file.arrayBuffer();
38
- return new Uint8Array(buffer);
36
+ return await fileHandle.getFile();
39
37
  }
40
38
  async delete(label) {
41
39
  await this.directory.removeEntry(label);
@@ -1 +1 @@
1
- {"version":3,"file":"opfs-forklift.js","sourceRoot":"","sources":["../../s/cellar/opfs-forklift.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,YAAY;IAOJ;IANpB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAe;QACjC,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,CAAA;QACnD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAA;QACxE,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,CAAA;IAC3B,CAAC;IAED,YAAoB,SAAoC;QAApC,cAAS,GAAT,SAAS,CAA2B;IAAG,CAAC;IAE5D,KAAK,CAAC,CAAC,IAAI;QACV,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;YAC7D,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;gBACzB,MAAM,IAAI,CAAA;QACZ,CAAC;IACF,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAa;QACtB,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;YACzC,OAAO,IAAI,CAAA;QACZ,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACZ,IAAK,GAAoB,CAAC,IAAI,KAAK,eAAe;gBAAE,OAAO,KAAK,CAAA;YAChE,MAAM,GAAG,CAAA;QACV,CAAC;IACF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,KAAiB;QAC1C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAA;QAC5E,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,cAAc,EAAE,CAAA;QAClD,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAC3B,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa;QACvB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QAC5D,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,CAAA;QACvC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAA;QACvC,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa;QACzB,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IACxC,CAAC;CACD"}
1
+ {"version":3,"file":"opfs-forklift.js","sourceRoot":"","sources":["../../s/cellar/opfs-forklift.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,YAAY;IAOJ;IANpB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAe;QACjC,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,CAAA;QACnD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAA;QACxE,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,CAAA;IAC3B,CAAC;IAED,YAAoB,SAAoC;QAApC,cAAS,GAAT,SAAS,CAA2B;IAAG,CAAC;IAE5D,KAAK,CAAC,CAAC,IAAI;QACV,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;YAC7D,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;gBACzB,MAAM,IAAI,CAAA;QACZ,CAAC;IACF,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAa;QACtB,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;YACzC,OAAO,IAAI,CAAA;QACZ,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACZ,IAAK,GAAoB,CAAC,IAAI,KAAK,eAAe;gBAAE,OAAO,KAAK,CAAA;YAChE,MAAM,GAAG,CAAA;QACV,CAAC;IACF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,IAAU;QACnC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAA;QAC5E,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,cAAc,EAAE,CAAA;QAClD,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC1B,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa;QACvB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QAC5D,OAAO,MAAM,UAAU,CAAC,OAAO,EAAE,CAAA;IAClC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa;QACzB,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IACxC,CAAC;CACD"}