@fireproof/core 0.17.3 → 0.17.5
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/README.md +2 -2
- package/dist/browser/fireproof.cjs +9 -3
- package/dist/browser/fireproof.cjs.map +1 -1
- package/dist/browser/fireproof.d.cts +15 -12
- package/dist/browser/fireproof.d.ts +15 -12
- package/dist/browser/fireproof.global.js +81 -112
- package/dist/browser/fireproof.global.js.map +1 -1
- package/dist/browser/fireproof.js +13 -3
- package/dist/browser/fireproof.js.map +1 -1
- package/dist/browser/metafile-cjs.json +1 -1
- package/dist/browser/metafile-esm.json +1 -1
- package/dist/browser/metafile-iife.json +1 -1
- package/dist/memory/fireproof.cjs +9 -3
- package/dist/memory/fireproof.cjs.map +1 -1
- package/dist/memory/fireproof.d.cts +15 -12
- package/dist/memory/fireproof.d.ts +15 -12
- package/dist/memory/fireproof.global.js +81 -112
- package/dist/memory/fireproof.global.js.map +1 -1
- package/dist/memory/fireproof.js +13 -3
- package/dist/memory/fireproof.js.map +1 -1
- package/dist/memory/metafile-cjs.json +1 -1
- package/dist/memory/metafile-esm.json +1 -1
- package/dist/memory/metafile-iife.json +1 -1
- package/dist/node/fireproof.cjs +3 -2
- package/dist/node/fireproof.cjs.map +1 -1
- package/dist/node/fireproof.d.cts +15 -12
- package/dist/node/fireproof.d.ts +15 -12
- package/dist/node/fireproof.global.js +76 -103
- package/dist/node/fireproof.global.js.map +1 -1
- package/dist/node/fireproof.js +3 -2
- package/dist/node/fireproof.js.map +1 -1
- package/dist/node/metafile-cjs.json +1 -1
- package/dist/node/metafile-esm.json +1 -1
- package/dist/node/metafile-iife.json +1 -1
- package/package.json +8 -5
@@ -4082,7 +4082,7 @@ var Fireproof = (() => {
|
|
4082
4082
|
};
|
4083
4083
|
var parse = (source, base4) => CID.parse(source, base4);
|
4084
4084
|
|
4085
|
-
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.
|
4085
|
+
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.2/node_modules/@web3-storage/pail/src/block.js
|
4086
4086
|
var MemoryBlockstore = class {
|
4087
4087
|
/** @type {Map<string, Uint8Array>} */
|
4088
4088
|
#blocks = /* @__PURE__ */ new Map();
|
@@ -4129,6 +4129,22 @@ var Fireproof = (() => {
|
|
4129
4129
|
}
|
4130
4130
|
}
|
4131
4131
|
};
|
4132
|
+
var MultiBlockFetcher = class {
|
4133
|
+
/** @type {API.BlockFetcher[]} */
|
4134
|
+
#fetchers;
|
4135
|
+
/** @param {API.BlockFetcher[]} fetchers */
|
4136
|
+
constructor(...fetchers) {
|
4137
|
+
this.#fetchers = fetchers;
|
4138
|
+
}
|
4139
|
+
/** @type {API.BlockFetcher['get']} */
|
4140
|
+
async get(link2) {
|
4141
|
+
for (const f of this.#fetchers) {
|
4142
|
+
const v = await f.get(link2);
|
4143
|
+
if (v)
|
4144
|
+
return v;
|
4145
|
+
}
|
4146
|
+
}
|
4147
|
+
};
|
4132
4148
|
|
4133
4149
|
// ../../node_modules/.pnpm/yocto-queue@1.0.0/node_modules/yocto-queue/index.js
|
4134
4150
|
var Node = class {
|
@@ -9875,8 +9891,7 @@ You can use close({ resize: true }) to resize header`);
|
|
9875
9891
|
return uint8Array;
|
9876
9892
|
}
|
9877
9893
|
async function encryptedEncodeCarFile(crypto2, key, rootCid, t) {
|
9878
|
-
const
|
9879
|
-
const encryptionKey = encryptionKeyUint8.buffer.slice(0, encryptionKeyUint8.byteLength);
|
9894
|
+
const encryptionKey = hexStringToUint8Array(key);
|
9880
9895
|
const encryptedBlocks = new MemoryBlockstore();
|
9881
9896
|
const cidsToEncrypt = [];
|
9882
9897
|
for (const { cid } of t.entries()) {
|
@@ -9953,7 +9968,7 @@ You can use close({ resize: true }) to resize header`);
|
|
9953
9968
|
}
|
9954
9969
|
return bytes;
|
9955
9970
|
}
|
9956
|
-
var PACKAGE_VERSION = "0.
|
9971
|
+
var PACKAGE_VERSION = "0.17.4";
|
9957
9972
|
var match = PACKAGE_VERSION.match(/^([^.]*\.[^.]*)/);
|
9958
9973
|
if (!match)
|
9959
9974
|
throw new Error("invalid version: " + PACKAGE_VERSION);
|
@@ -10029,11 +10044,11 @@ You can use close({ resize: true }) to resize header`);
|
|
10029
10044
|
constructor(name7, ebOpts) {
|
10030
10045
|
this.name = name7;
|
10031
10046
|
this.ebOpts = ebOpts;
|
10032
|
-
this.
|
10033
|
-
this.
|
10034
|
-
this.
|
10035
|
-
this.remoteWAL = new ebOpts.store.RemoteWAL(this);
|
10047
|
+
this.carStore = ebOpts.store.makeDataStore(this.name);
|
10048
|
+
this.fileStore = ebOpts.store.makeDataStore(this.name);
|
10049
|
+
this.remoteWAL = ebOpts.store.makeRemoteWAL(this);
|
10036
10050
|
this.ready = Promise.resolve().then(async () => {
|
10051
|
+
this.metaStore = ebOpts.store.makeMetaStore(this);
|
10037
10052
|
if (!this.metaStore || !this.carStore || !this.remoteWAL)
|
10038
10053
|
throw new Error("stores not initialized");
|
10039
10054
|
const metas = this.ebOpts.meta ? [this.ebOpts.meta] : await this.metaStore.load("main");
|
@@ -10207,19 +10222,30 @@ You can use close({ resize: true }) to resize header`);
|
|
10207
10222
|
const sCid = cid.toString();
|
10208
10223
|
if (this.getBlockCache.has(sCid))
|
10209
10224
|
return this.getBlockCache.get(sCid);
|
10210
|
-
const
|
10211
|
-
|
10212
|
-
|
10213
|
-
|
10214
|
-
|
10215
|
-
|
10216
|
-
|
10217
|
-
|
10218
|
-
|
10219
|
-
|
10220
|
-
|
10221
|
-
|
10222
|
-
|
10225
|
+
const getCarCid = async (carCid) => {
|
10226
|
+
const reader = await this.loadCar(carCid);
|
10227
|
+
if (!reader) {
|
10228
|
+
throw new Error(`missing car reader ${carCid.toString()}`);
|
10229
|
+
}
|
10230
|
+
await this.cacheCarReader(reader);
|
10231
|
+
if (this.getBlockCache.has(sCid))
|
10232
|
+
return this.getBlockCache.get(sCid);
|
10233
|
+
throw new Error(`block not in reader: ${cid.toString()}`);
|
10234
|
+
};
|
10235
|
+
let got;
|
10236
|
+
const batchSize = 5;
|
10237
|
+
for (let i = 0; i < this.carLog.length; i += batchSize) {
|
10238
|
+
const promises = [];
|
10239
|
+
for (let j = i; j < Math.min(i + batchSize, this.carLog.length); j++) {
|
10240
|
+
promises.push(getCarCid(this.carLog[j]));
|
10241
|
+
}
|
10242
|
+
try {
|
10243
|
+
got = await Promise.any(promises);
|
10244
|
+
} catch {
|
10245
|
+
}
|
10246
|
+
if (got)
|
10247
|
+
break;
|
10248
|
+
}
|
10223
10249
|
if (got) {
|
10224
10250
|
this.getBlockCache.set(sCid, got);
|
10225
10251
|
}
|
@@ -10460,14 +10486,6 @@ You can use close({ resize: true }) to resize header`);
|
|
10460
10486
|
return bytes;
|
10461
10487
|
}
|
10462
10488
|
|
10463
|
-
// ../encrypted-blockstore/dist/lib/store-web.js
|
10464
|
-
var store_web_exports = {};
|
10465
|
-
__export(store_web_exports, {
|
10466
|
-
DataStore: () => DataStore2,
|
10467
|
-
MetaStore: () => MetaStore2,
|
10468
|
-
RemoteWAL: () => RemoteWAL2
|
10469
|
-
});
|
10470
|
-
|
10471
10489
|
// ../../node_modules/.pnpm/idb@7.1.1/node_modules/idb/build/wrap-idb-value.js
|
10472
10490
|
var instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);
|
10473
10491
|
var idbProxyableTypes;
|
@@ -10676,7 +10694,7 @@ You can use close({ resize: true }) to resize header`);
|
|
10676
10694
|
}));
|
10677
10695
|
|
10678
10696
|
// ../encrypted-blockstore/dist/lib/store-web.js
|
10679
|
-
var PACKAGE_VERSION2 = "0.
|
10697
|
+
var PACKAGE_VERSION2 = "0.17.4";
|
10680
10698
|
var match2 = PACKAGE_VERSION2.match(/^([^.]*\.[^.]*)/);
|
10681
10699
|
if (!match2)
|
10682
10700
|
throw new Error("invalid version: " + PACKAGE_VERSION2);
|
@@ -10764,14 +10782,14 @@ You can use close({ resize: true }) to resize header`);
|
|
10764
10782
|
processQueue = new CommitQueue2();
|
10765
10783
|
constructor(loader) {
|
10766
10784
|
this.loader = loader;
|
10767
|
-
this.ready = (async () => {
|
10785
|
+
this.ready = Promise.resolve().then(async () => {
|
10768
10786
|
const walState = await this.load().catch((e) => {
|
10769
10787
|
console.error("error loading wal", e);
|
10770
10788
|
return null;
|
10771
10789
|
});
|
10772
10790
|
this.walState.operations = walState?.operations || [];
|
10773
10791
|
this.walState.fileOperations = walState?.fileOperations || [];
|
10774
|
-
})
|
10792
|
+
});
|
10775
10793
|
}
|
10776
10794
|
async enqueue(dbMeta, opts) {
|
10777
10795
|
await this.ready;
|
@@ -10870,6 +10888,9 @@ You can use close({ resize: true }) to resize header`);
|
|
10870
10888
|
await rmlp;
|
10871
10889
|
}
|
10872
10890
|
};
|
10891
|
+
var makeDataStore = (name7) => new DataStore2(name7);
|
10892
|
+
var makeMetaStore = (loader) => new MetaStore2(loader.name);
|
10893
|
+
var makeRemoteWAL = (loader) => new RemoteWAL2(loader);
|
10873
10894
|
var DataStore2 = class extends DataStore {
|
10874
10895
|
tag = "car-web-idb";
|
10875
10896
|
idb = null;
|
@@ -10964,7 +10985,14 @@ You can use close({ resize: true }) to resize header`);
|
|
10964
10985
|
}
|
10965
10986
|
};
|
10966
10987
|
|
10967
|
-
//
|
10988
|
+
// src/eb-web.ts
|
10989
|
+
var store = {
|
10990
|
+
makeDataStore,
|
10991
|
+
makeMetaStore,
|
10992
|
+
makeRemoteWAL
|
10993
|
+
};
|
10994
|
+
|
10995
|
+
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.2/node_modules/@web3-storage/pail/src/clock/index.js
|
10968
10996
|
var advance = async (blocks, head, event) => {
|
10969
10997
|
const events = new EventFetcher(blocks);
|
10970
10998
|
const headmap = new Map(head.map((cid) => [cid.toString(), cid]));
|
@@ -11038,6 +11066,7 @@ You can use close({ resize: true }) to resize header`);
|
|
11038
11066
|
return true;
|
11039
11067
|
const [{ value: aevent }, { value: bevent }] = await Promise.all([events.get(a), events.get(b)]);
|
11040
11068
|
const links3 = [...aevent.parents];
|
11069
|
+
const seen = /* @__PURE__ */ new Set();
|
11041
11070
|
while (links3.length) {
|
11042
11071
|
const link2 = links3.shift();
|
11043
11072
|
if (!link2)
|
@@ -11046,6 +11075,9 @@ You can use close({ resize: true }) to resize header`);
|
|
11046
11075
|
return true;
|
11047
11076
|
if (bevent.parents.some((p) => link2.toString() === p.toString()))
|
11048
11077
|
continue;
|
11078
|
+
if (seen.has(link2.toString()))
|
11079
|
+
continue;
|
11080
|
+
seen.add(link2.toString());
|
11049
11081
|
const { value: event } = await events.get(link2);
|
11050
11082
|
links3.push(...event.parents);
|
11051
11083
|
}
|
@@ -11086,7 +11118,7 @@ You can use close({ resize: true }) to resize header`);
|
|
11086
11118
|
};
|
11087
11119
|
var shortLink = (l) => `${String(l).slice(0, 4)}..${String(l).slice(-4)}`;
|
11088
11120
|
|
11089
|
-
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.
|
11121
|
+
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.2/node_modules/@web3-storage/pail/src/shard.js
|
11090
11122
|
var MaxKeyLength = 64;
|
11091
11123
|
var MaxShardSize = 512 * 1024;
|
11092
11124
|
var CID_TAG2 = new Token(Type.tag, 42);
|
@@ -11218,7 +11250,7 @@ You can use close({ resize: true }) to resize header`);
|
|
11218
11250
|
}
|
11219
11251
|
};
|
11220
11252
|
|
11221
|
-
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.
|
11253
|
+
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.2/node_modules/@web3-storage/pail/src/index.js
|
11222
11254
|
var put = async (blocks, root2, key, value) => {
|
11223
11255
|
const shards = new ShardFetcher(blocks);
|
11224
11256
|
const rshard = await shards.get(root2);
|
@@ -11421,71 +11453,7 @@ You can use close({ resize: true }) to resize header`);
|
|
11421
11453
|
return [shard];
|
11422
11454
|
};
|
11423
11455
|
|
11424
|
-
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.
|
11425
|
-
var MemoryBlockstore2 = class {
|
11426
|
-
/** @type {Map<string, Uint8Array>} */
|
11427
|
-
#blocks = /* @__PURE__ */ new Map();
|
11428
|
-
/**
|
11429
|
-
* @param {Array<import('multiformats').Block>} [blocks]
|
11430
|
-
*/
|
11431
|
-
constructor(blocks) {
|
11432
|
-
if (blocks) {
|
11433
|
-
this.#blocks = new Map(blocks.map((b) => [b.cid.toString(), b.bytes]));
|
11434
|
-
}
|
11435
|
-
}
|
11436
|
-
/** @type {API.BlockFetcher['get']} */
|
11437
|
-
async get(cid) {
|
11438
|
-
const bytes = this.#blocks.get(cid.toString());
|
11439
|
-
if (!bytes)
|
11440
|
-
return;
|
11441
|
-
return { cid, bytes };
|
11442
|
-
}
|
11443
|
-
/**
|
11444
|
-
* @param {API.UnknownLink} cid
|
11445
|
-
* @param {Uint8Array} bytes
|
11446
|
-
*/
|
11447
|
-
async put(cid, bytes) {
|
11448
|
-
this.#blocks.set(cid.toString(), bytes);
|
11449
|
-
}
|
11450
|
-
/**
|
11451
|
-
* @param {API.UnknownLink} cid
|
11452
|
-
* @param {Uint8Array} bytes
|
11453
|
-
*/
|
11454
|
-
putSync(cid, bytes) {
|
11455
|
-
this.#blocks.set(cid.toString(), bytes);
|
11456
|
-
}
|
11457
|
-
/** @param {API.UnknownLink} cid */
|
11458
|
-
async delete(cid) {
|
11459
|
-
this.#blocks.delete(cid.toString());
|
11460
|
-
}
|
11461
|
-
/** @param {API.UnknownLink} cid */
|
11462
|
-
deleteSync(cid) {
|
11463
|
-
this.#blocks.delete(cid.toString());
|
11464
|
-
}
|
11465
|
-
*entries() {
|
11466
|
-
for (const [str, bytes] of this.#blocks) {
|
11467
|
-
yield { cid: parse(str), bytes };
|
11468
|
-
}
|
11469
|
-
}
|
11470
|
-
};
|
11471
|
-
var MultiBlockFetcher = class {
|
11472
|
-
/** @type {API.BlockFetcher[]} */
|
11473
|
-
#fetchers;
|
11474
|
-
/** @param {API.BlockFetcher[]} fetchers */
|
11475
|
-
constructor(...fetchers) {
|
11476
|
-
this.#fetchers = fetchers;
|
11477
|
-
}
|
11478
|
-
/** @type {API.BlockFetcher['get']} */
|
11479
|
-
async get(link2) {
|
11480
|
-
for (const f of this.#fetchers) {
|
11481
|
-
const v = await f.get(link2);
|
11482
|
-
if (v)
|
11483
|
-
return v;
|
11484
|
-
}
|
11485
|
-
}
|
11486
|
-
};
|
11487
|
-
|
11488
|
-
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.1/node_modules/@web3-storage/pail/src/batch/shard.js
|
11456
|
+
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.2/node_modules/@web3-storage/pail/src/batch/shard.js
|
11489
11457
|
var ShardLinkByteLength = 36;
|
11490
11458
|
var CID_TAG3 = new Token(Type.tag, 42);
|
11491
11459
|
var create8 = (init2) => ({
|
@@ -11532,7 +11500,7 @@ You can use close({ resize: true }) to resize header`);
|
|
11532
11500
|
return tokensToLength(tokens);
|
11533
11501
|
};
|
11534
11502
|
|
11535
|
-
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.
|
11503
|
+
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.2/node_modules/@web3-storage/pail/src/batch/index.js
|
11536
11504
|
var Batcher = class _Batcher {
|
11537
11505
|
#committed = false;
|
11538
11506
|
/**
|
@@ -11714,9 +11682,9 @@ You can use close({ resize: true }) to resize header`);
|
|
11714
11682
|
static code = "ERR_BATCH_COMMITTED";
|
11715
11683
|
};
|
11716
11684
|
|
11717
|
-
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.
|
11685
|
+
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.2/node_modules/@web3-storage/pail/src/crdt/index.js
|
11718
11686
|
var put3 = async (blocks, head, key, value) => {
|
11719
|
-
const mblocks = new
|
11687
|
+
const mblocks = new MemoryBlockstore();
|
11720
11688
|
blocks = new MultiBlockFetcher(mblocks, blocks);
|
11721
11689
|
if (!head.length) {
|
11722
11690
|
const shard = await ShardBlock.create();
|
@@ -11800,7 +11768,7 @@ You can use close({ resize: true }) to resize header`);
|
|
11800
11768
|
var root = async (blocks, head) => {
|
11801
11769
|
if (!head.length)
|
11802
11770
|
throw new Error("cannot determine root of headless clock");
|
11803
|
-
const mblocks = new
|
11771
|
+
const mblocks = new MemoryBlockstore();
|
11804
11772
|
blocks = new MultiBlockFetcher(mblocks, blocks);
|
11805
11773
|
const events = new EventFetcher(blocks);
|
11806
11774
|
if (head.length === 1) {
|
@@ -11859,7 +11827,7 @@ You can use close({ resize: true }) to resize header`);
|
|
11859
11827
|
return;
|
11860
11828
|
const result = await root(blocks, head);
|
11861
11829
|
if (result.additions.length) {
|
11862
|
-
blocks = new MultiBlockFetcher(new
|
11830
|
+
blocks = new MultiBlockFetcher(new MemoryBlockstore(result.additions), blocks);
|
11863
11831
|
}
|
11864
11832
|
return get2(blocks, result.root, key);
|
11865
11833
|
};
|
@@ -11868,7 +11836,7 @@ You can use close({ resize: true }) to resize header`);
|
|
11868
11836
|
return;
|
11869
11837
|
const result = await root(blocks, head);
|
11870
11838
|
if (result.additions.length) {
|
11871
|
-
blocks = new MultiBlockFetcher(new
|
11839
|
+
blocks = new MultiBlockFetcher(new MemoryBlockstore(result.additions), blocks);
|
11872
11840
|
}
|
11873
11841
|
yield* entries(blocks, result.root, options);
|
11874
11842
|
};
|
@@ -11952,7 +11920,7 @@ You can use close({ resize: true }) to resize header`);
|
|
11952
11920
|
return acc.concat(...rest);
|
11953
11921
|
};
|
11954
11922
|
|
11955
|
-
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.
|
11923
|
+
// ../../node_modules/.pnpm/@web3-storage+pail@0.4.2/node_modules/@web3-storage/pail/src/crdt/batch/index.js
|
11956
11924
|
var Batcher2 = class _Batcher {
|
11957
11925
|
#committed = false;
|
11958
11926
|
/**
|
@@ -11997,7 +11965,7 @@ You can use close({ resize: true }) to resize header`);
|
|
11997
11965
|
const res = await commit(this);
|
11998
11966
|
const data = { type: "batch", ops: this.ops, root: res.root };
|
11999
11967
|
const event = await EventBlock.create(data, this.head);
|
12000
|
-
const mblocks = new
|
11968
|
+
const mblocks = new MemoryBlockstore();
|
12001
11969
|
const blocks = new MultiBlockFetcher(mblocks, this.blocks);
|
12002
11970
|
mblocks.putSync(event.cid, event.bytes);
|
12003
11971
|
const head = await advance(blocks, this.head, event.cid);
|
@@ -12037,7 +12005,7 @@ You can use close({ resize: true }) to resize header`);
|
|
12037
12005
|
* @param {string} init.prefix
|
12038
12006
|
*/
|
12039
12007
|
static async create({ blocks, head, prefix }) {
|
12040
|
-
const mblocks = new
|
12008
|
+
const mblocks = new MemoryBlockstore();
|
12041
12009
|
blocks = new MultiBlockFetcher(mblocks, blocks);
|
12042
12010
|
if (!head.length) {
|
12043
12011
|
const base5 = await ShardBlock.create();
|
@@ -20611,6 +20579,7 @@ You can use close({ resize: true }) to resize header`);
|
|
20611
20579
|
if (!block)
|
20612
20580
|
throw new Error(`Missing linked block ${link2.toString()}`);
|
20613
20581
|
const { value } = await decode11({ bytes: block.bytes, hasher: sha256, codec: src_exports });
|
20582
|
+
value.cid = link2;
|
20614
20583
|
readFiles(blocks, value);
|
20615
20584
|
return value;
|
20616
20585
|
}
|
@@ -21562,8 +21531,8 @@ You can use close({ resize: true }) to resize header`);
|
|
21562
21531
|
return { head: this.clock.head };
|
21563
21532
|
},
|
21564
21533
|
autoCompact: this.opts.autoCompact || 100,
|
21565
|
-
crypto: crypto_web_exports,
|
21566
|
-
store:
|
21534
|
+
crypto: this.opts.crypto || crypto_web_exports,
|
21535
|
+
store: this.opts.store || store,
|
21567
21536
|
public: this.opts.public,
|
21568
21537
|
meta: this.opts.meta
|
21569
21538
|
});
|
@@ -21578,7 +21547,7 @@ You can use close({ resize: true }) to resize header`);
|
|
21578
21547
|
},
|
21579
21548
|
crypto: crypto_web_exports,
|
21580
21549
|
public: this.opts.public,
|
21581
|
-
store
|
21550
|
+
store
|
21582
21551
|
});
|
21583
21552
|
this.ready = Promise.all([this.blockstore.ready, this.indexBlockstore.ready]).then(() => {
|
21584
21553
|
});
|