@timeax/digital-service-engine 0.2.5 → 0.2.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/dist/core/index.cjs +1 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +146 -96
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +146 -96
- package/dist/react/index.js.map +1 -1
- package/dist/workspace/index.cjs +146 -96
- package/dist/workspace/index.cjs.map +1 -1
- package/dist/workspace/index.js +146 -96
- package/dist/workspace/index.js.map +1 -1
- package/package.json +7 -7
package/dist/workspace/index.cjs
CHANGED
|
@@ -6654,7 +6654,7 @@ function createNodeIndex(builder) {
|
|
|
6654
6654
|
for (const fieldId of visible) {
|
|
6655
6655
|
const node = getField(fieldId);
|
|
6656
6656
|
if (!node) continue;
|
|
6657
|
-
const explicit = includes.has(fieldId)
|
|
6657
|
+
const explicit = includes.has(fieldId);
|
|
6658
6658
|
results.push(explicit ? node : { ...node, isInherited: true });
|
|
6659
6659
|
}
|
|
6660
6660
|
return Object.freeze(results);
|
|
@@ -8408,7 +8408,9 @@ function include(ctx, receiverId, idOrIds) {
|
|
|
8408
8408
|
const ids = Array.isArray(idOrIds) ? idOrIds : [idOrIds];
|
|
8409
8409
|
if (receiver.kind === "tag" || receiver.kind === "field" && isActualButtonField(receiver.data) || receiver.kind === "option") {
|
|
8410
8410
|
if (receiver.kind === "tag") {
|
|
8411
|
-
const t = ((_a = p.filters) != null ? _a : []).find(
|
|
8411
|
+
const t = ((_a = p.filters) != null ? _a : []).find(
|
|
8412
|
+
(x) => x.id === receiverId
|
|
8413
|
+
);
|
|
8412
8414
|
if (t) {
|
|
8413
8415
|
const accepted = [];
|
|
8414
8416
|
const next = new Set((_b = t.includes) != null ? _b : []);
|
|
@@ -8450,7 +8452,12 @@ function include(ctx, receiverId, idOrIds) {
|
|
|
8450
8452
|
const current = (_f = (_e = p.includes_for_buttons) == null ? void 0 : _e[receiverId]) != null ? _f : [];
|
|
8451
8453
|
const next = new Set(current);
|
|
8452
8454
|
for (const id of ids) {
|
|
8453
|
-
if (wouldCreateIncludeExcludeCycle(
|
|
8455
|
+
if (wouldCreateIncludeExcludeCycle(
|
|
8456
|
+
ctx,
|
|
8457
|
+
p,
|
|
8458
|
+
receiverId,
|
|
8459
|
+
id
|
|
8460
|
+
)) {
|
|
8454
8461
|
ctx.emit("editor:error", {
|
|
8455
8462
|
message: `Cycle detected: ${receiverId} including ${id} would create a cycle.`,
|
|
8456
8463
|
code: "cycle_detected",
|
|
@@ -8466,7 +8473,8 @@ function include(ctx, receiverId, idOrIds) {
|
|
|
8466
8473
|
accepted.push(id);
|
|
8467
8474
|
}
|
|
8468
8475
|
if (accepted.length > 0 || current.length > 0) {
|
|
8469
|
-
if (!p.includes_for_buttons)
|
|
8476
|
+
if (!p.includes_for_buttons)
|
|
8477
|
+
p.includes_for_buttons = {};
|
|
8470
8478
|
p.includes_for_buttons[receiverId] = Array.from(next);
|
|
8471
8479
|
}
|
|
8472
8480
|
if ((_g = p.excludes_for_buttons) == null ? void 0 : _g[receiverId]) {
|
|
@@ -8481,7 +8489,9 @@ function include(ctx, receiverId, idOrIds) {
|
|
|
8481
8489
|
if (!p.fields) p.fields = [];
|
|
8482
8490
|
if (!p.filters) p.filters = [];
|
|
8483
8491
|
} else {
|
|
8484
|
-
throw new Error(
|
|
8492
|
+
throw new Error(
|
|
8493
|
+
"Receiver must be a tag, button field, or option"
|
|
8494
|
+
);
|
|
8485
8495
|
}
|
|
8486
8496
|
}),
|
|
8487
8497
|
undo: () => ctx.undo()
|
|
@@ -8496,7 +8506,9 @@ function exclude(ctx, receiverId, idOrIds) {
|
|
|
8496
8506
|
const ids = Array.isArray(idOrIds) ? idOrIds : [idOrIds];
|
|
8497
8507
|
if (receiver.kind === "tag" || receiver.kind === "field" && isActualButtonField(receiver.data) || receiver.kind === "option") {
|
|
8498
8508
|
if (receiver.kind === "tag") {
|
|
8499
|
-
const t = ((_a = p.filters) != null ? _a : []).find(
|
|
8509
|
+
const t = ((_a = p.filters) != null ? _a : []).find(
|
|
8510
|
+
(x) => x.id === receiverId
|
|
8511
|
+
);
|
|
8500
8512
|
if (t) {
|
|
8501
8513
|
const accepted = [];
|
|
8502
8514
|
const next = new Set((_b = t.excludes) != null ? _b : []);
|
|
@@ -8538,7 +8550,12 @@ function exclude(ctx, receiverId, idOrIds) {
|
|
|
8538
8550
|
const current = (_f = (_e = p.excludes_for_buttons) == null ? void 0 : _e[receiverId]) != null ? _f : [];
|
|
8539
8551
|
const next = new Set(current);
|
|
8540
8552
|
for (const id of ids) {
|
|
8541
|
-
if (wouldCreateIncludeExcludeCycle(
|
|
8553
|
+
if (wouldCreateIncludeExcludeCycle(
|
|
8554
|
+
ctx,
|
|
8555
|
+
p,
|
|
8556
|
+
receiverId,
|
|
8557
|
+
id
|
|
8558
|
+
)) {
|
|
8542
8559
|
ctx.emit("editor:error", {
|
|
8543
8560
|
message: `Cycle detected: ${receiverId} excluding ${id} would create a cycle.`,
|
|
8544
8561
|
code: "cycle_detected",
|
|
@@ -8554,7 +8571,8 @@ function exclude(ctx, receiverId, idOrIds) {
|
|
|
8554
8571
|
accepted.push(id);
|
|
8555
8572
|
}
|
|
8556
8573
|
if (accepted.length > 0 || current.length > 0) {
|
|
8557
|
-
if (!p.excludes_for_buttons)
|
|
8574
|
+
if (!p.excludes_for_buttons)
|
|
8575
|
+
p.excludes_for_buttons = {};
|
|
8558
8576
|
p.excludes_for_buttons[receiverId] = Array.from(next);
|
|
8559
8577
|
}
|
|
8560
8578
|
if ((_g = p.includes_for_buttons) == null ? void 0 : _g[receiverId]) {
|
|
@@ -8569,7 +8587,9 @@ function exclude(ctx, receiverId, idOrIds) {
|
|
|
8569
8587
|
if (!p.fields) p.fields = [];
|
|
8570
8588
|
if (!p.filters) p.filters = [];
|
|
8571
8589
|
} else {
|
|
8572
|
-
throw new Error(
|
|
8590
|
+
throw new Error(
|
|
8591
|
+
"Receiver must be a tag, button field, or option"
|
|
8592
|
+
);
|
|
8573
8593
|
}
|
|
8574
8594
|
}),
|
|
8575
8595
|
undo: () => ctx.undo()
|
|
@@ -8579,87 +8599,98 @@ function connect(ctx, kind, fromId, toId2) {
|
|
|
8579
8599
|
ctx.exec({
|
|
8580
8600
|
name: `connect:${kind}`,
|
|
8581
8601
|
do: () => ctx.patchProps((p) => {
|
|
8582
|
-
var _a, _b, _c, _d, _e;
|
|
8602
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
8583
8603
|
if (kind === "bind") {
|
|
8584
8604
|
if (ctx.isTagId(fromId) && ctx.isTagId(toId2)) {
|
|
8585
8605
|
if (wouldCreateTagCycle(ctx, p, fromId, toId2)) {
|
|
8586
|
-
throw new Error(
|
|
8606
|
+
throw new Error(
|
|
8607
|
+
`bind would create a cycle: ${fromId} ? ${toId2}`
|
|
8608
|
+
);
|
|
8587
8609
|
}
|
|
8588
|
-
const child = ((_a = p.filters) != null ? _a : []).find(
|
|
8610
|
+
const child = ((_a = p.filters) != null ? _a : []).find(
|
|
8611
|
+
(t) => t.id === toId2
|
|
8612
|
+
);
|
|
8589
8613
|
if (child) child.bind_id = fromId;
|
|
8590
8614
|
return;
|
|
8591
8615
|
}
|
|
8592
8616
|
if (ctx.isTagId(fromId) && ctx.isFieldId(toId2) || ctx.isFieldId(fromId) && ctx.isTagId(toId2)) {
|
|
8593
8617
|
const fieldId = ctx.isFieldId(toId2) ? toId2 : fromId;
|
|
8594
8618
|
const tagId = ctx.isTagId(fromId) ? fromId : toId2;
|
|
8595
|
-
const f = ((_b = p.fields) != null ? _b : []).find(
|
|
8619
|
+
const f = ((_b = p.fields) != null ? _b : []).find(
|
|
8620
|
+
(x) => x.id === fieldId
|
|
8621
|
+
);
|
|
8596
8622
|
if (!f) return;
|
|
8597
8623
|
if (!f.bind_id) {
|
|
8598
8624
|
f.bind_id = tagId;
|
|
8599
8625
|
return;
|
|
8600
8626
|
}
|
|
8601
8627
|
if (typeof f.bind_id === "string") {
|
|
8602
|
-
if (f.bind_id !== tagId)
|
|
8628
|
+
if (f.bind_id !== tagId) {
|
|
8629
|
+
f.bind_id = [f.bind_id, tagId];
|
|
8630
|
+
}
|
|
8603
8631
|
return;
|
|
8604
8632
|
}
|
|
8605
|
-
if (!f.bind_id.includes(tagId))
|
|
8633
|
+
if (!f.bind_id.includes(tagId)) {
|
|
8634
|
+
f.bind_id.push(tagId);
|
|
8635
|
+
}
|
|
8606
8636
|
return;
|
|
8607
8637
|
}
|
|
8608
|
-
throw new Error(
|
|
8638
|
+
throw new Error(
|
|
8639
|
+
`bind: unsupported route ${fromId} ? ${toId2}`
|
|
8640
|
+
);
|
|
8609
8641
|
}
|
|
8610
8642
|
if (kind === "include" || kind === "exclude") {
|
|
8611
|
-
const
|
|
8643
|
+
const tagKey = kind === "include" ? "includes" : "excludes";
|
|
8644
|
+
const mapKey = kind === "include" ? "includes_for_buttons" : "excludes_for_buttons";
|
|
8612
8645
|
if (ctx.isTagId(fromId) && ctx.isFieldId(toId2)) {
|
|
8613
|
-
const t = ((_c = p.filters) != null ? _c : []).find(
|
|
8646
|
+
const t = ((_c = p.filters) != null ? _c : []).find(
|
|
8647
|
+
(x) => x.id === fromId
|
|
8648
|
+
);
|
|
8614
8649
|
if (!t) return;
|
|
8615
|
-
const arr = (_d = t[
|
|
8650
|
+
const arr = (_d = t[tagKey]) != null ? _d : t[tagKey] = [];
|
|
8616
8651
|
if (!arr.includes(toId2)) arr.push(toId2);
|
|
8617
8652
|
return;
|
|
8618
8653
|
}
|
|
8654
|
+
if (ctx.isFieldId(fromId) && ctx.isFieldId(toId2)) {
|
|
8655
|
+
const source = ((_e = p.fields) != null ? _e : []).find(
|
|
8656
|
+
(x) => x.id === fromId
|
|
8657
|
+
);
|
|
8658
|
+
if (!(source == null ? void 0 : source.button)) {
|
|
8659
|
+
throw new Error(
|
|
8660
|
+
`${kind}: source field must be button=true: ${fromId} ? ${toId2}`
|
|
8661
|
+
);
|
|
8662
|
+
}
|
|
8663
|
+
addMappedField(p, mapKey, fromId, toId2);
|
|
8664
|
+
return;
|
|
8665
|
+
}
|
|
8619
8666
|
if (ctx.isOptionId(fromId) && ctx.isFieldId(toId2)) {
|
|
8620
|
-
|
|
8621
|
-
const maps = p[mapKey];
|
|
8622
|
-
const next = { ...maps != null ? maps : {} };
|
|
8623
|
-
const arr = (_e = next[fromId]) != null ? _e : [];
|
|
8624
|
-
if (!arr.includes(toId2)) arr.push(toId2);
|
|
8625
|
-
next[fromId] = arr;
|
|
8626
|
-
p[mapKey] = next;
|
|
8667
|
+
addMappedField(p, mapKey, fromId, toId2);
|
|
8627
8668
|
return;
|
|
8628
8669
|
}
|
|
8629
|
-
throw new Error(
|
|
8670
|
+
throw new Error(
|
|
8671
|
+
`${kind}: unsupported route ${fromId} ? ${toId2}`
|
|
8672
|
+
);
|
|
8630
8673
|
}
|
|
8631
8674
|
if (kind === "service") {
|
|
8632
8675
|
ensureServiceExists(ctx.opts, fromId);
|
|
8633
8676
|
if (toId2.startsWith("t:")) {
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
do: () => ctx.patchProps((next) => {
|
|
8637
|
-
var _a2;
|
|
8638
|
-
const t = ((_a2 = next.filters) != null ? _a2 : []).find((x) => x.id === toId2);
|
|
8639
|
-
if (t) t.service_id = fromId;
|
|
8640
|
-
}),
|
|
8641
|
-
undo: () => ctx.undo()
|
|
8642
|
-
});
|
|
8677
|
+
const t = ((_f = p.filters) != null ? _f : []).find((x) => x.id === toId2);
|
|
8678
|
+
if (t) t.service_id = fromId;
|
|
8643
8679
|
return;
|
|
8644
8680
|
}
|
|
8645
8681
|
if (toId2.startsWith("o:")) {
|
|
8646
|
-
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
|
|
8650
|
-
|
|
8651
|
-
|
|
8652
|
-
|
|
8653
|
-
o.service_id = fromId;
|
|
8654
|
-
return;
|
|
8655
|
-
}
|
|
8656
|
-
}
|
|
8657
|
-
}),
|
|
8658
|
-
undo: () => ctx.undo()
|
|
8659
|
-
});
|
|
8682
|
+
for (const f of (_g = p.fields) != null ? _g : []) {
|
|
8683
|
+
const o = (_h = f.options) == null ? void 0 : _h.find((x) => x.id === toId2);
|
|
8684
|
+
if (o) {
|
|
8685
|
+
o.service_id = fromId;
|
|
8686
|
+
return;
|
|
8687
|
+
}
|
|
8688
|
+
}
|
|
8660
8689
|
return;
|
|
8661
8690
|
}
|
|
8662
|
-
throw new Error(
|
|
8691
|
+
throw new Error(
|
|
8692
|
+
'service: to must be a tag ("t:*") or option ("o:*")'
|
|
8693
|
+
);
|
|
8663
8694
|
}
|
|
8664
8695
|
throw new Error(`Unknown connect kind: ${kind}`);
|
|
8665
8696
|
}),
|
|
@@ -8670,90 +8701,109 @@ function disconnect(ctx, kind, fromId, toId2) {
|
|
|
8670
8701
|
ctx.exec({
|
|
8671
8702
|
name: `disconnect:${kind}`,
|
|
8672
8703
|
do: () => ctx.patchProps((p) => {
|
|
8673
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
8704
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
8674
8705
|
if (kind === "bind") {
|
|
8675
8706
|
if (ctx.isTagId(fromId) && ctx.isTagId(toId2)) {
|
|
8676
|
-
const child = ((_a = p.filters) != null ? _a : []).find(
|
|
8677
|
-
|
|
8707
|
+
const child = ((_a = p.filters) != null ? _a : []).find(
|
|
8708
|
+
(t) => t.id === toId2
|
|
8709
|
+
);
|
|
8710
|
+
if ((child == null ? void 0 : child.bind_id) === fromId) {
|
|
8711
|
+
delete child.bind_id;
|
|
8712
|
+
}
|
|
8678
8713
|
return;
|
|
8679
8714
|
}
|
|
8680
8715
|
if (ctx.isTagId(fromId) && ctx.isFieldId(toId2) || ctx.isFieldId(fromId) && ctx.isTagId(toId2)) {
|
|
8681
8716
|
const fieldId = ctx.isFieldId(toId2) ? toId2 : fromId;
|
|
8682
8717
|
const tagId = ctx.isTagId(fromId) ? fromId : toId2;
|
|
8683
|
-
const f = ((_b = p.fields) != null ? _b : []).find(
|
|
8718
|
+
const f = ((_b = p.fields) != null ? _b : []).find(
|
|
8719
|
+
(x) => x.id === fieldId
|
|
8720
|
+
);
|
|
8684
8721
|
if (!(f == null ? void 0 : f.bind_id)) return;
|
|
8685
8722
|
if (typeof f.bind_id === "string") {
|
|
8686
|
-
if (f.bind_id === tagId)
|
|
8723
|
+
if (f.bind_id === tagId) {
|
|
8724
|
+
delete f.bind_id;
|
|
8725
|
+
}
|
|
8687
8726
|
return;
|
|
8688
8727
|
}
|
|
8689
8728
|
f.bind_id = f.bind_id.filter((x) => x !== tagId);
|
|
8690
|
-
if (((_c = f.bind_id) == null ? void 0 : _c.length) === 0)
|
|
8729
|
+
if (((_c = f.bind_id) == null ? void 0 : _c.length) === 0) {
|
|
8730
|
+
delete f.bind_id;
|
|
8731
|
+
}
|
|
8691
8732
|
return;
|
|
8692
8733
|
}
|
|
8693
|
-
throw new Error(
|
|
8734
|
+
throw new Error(
|
|
8735
|
+
`unbind: unsupported route ${fromId} ? ${toId2}`
|
|
8736
|
+
);
|
|
8694
8737
|
}
|
|
8695
8738
|
if (kind === "include" || kind === "exclude") {
|
|
8696
|
-
const
|
|
8739
|
+
const tagKey = kind === "include" ? "includes" : "excludes";
|
|
8740
|
+
const mapKey = kind === "include" ? "includes_for_buttons" : "excludes_for_buttons";
|
|
8697
8741
|
if (ctx.isTagId(fromId) && ctx.isFieldId(toId2)) {
|
|
8698
|
-
const t = ((_d = p.filters) != null ? _d : []).find(
|
|
8742
|
+
const t = ((_d = p.filters) != null ? _d : []).find(
|
|
8743
|
+
(x) => x.id === fromId
|
|
8744
|
+
);
|
|
8699
8745
|
if (!t) return;
|
|
8700
|
-
t[
|
|
8701
|
-
if (!((_f = t[
|
|
8746
|
+
t[tagKey] = ((_e = t[tagKey]) != null ? _e : []).filter((x) => x !== toId2);
|
|
8747
|
+
if (!((_f = t[tagKey]) == null ? void 0 : _f.length)) {
|
|
8748
|
+
delete t[tagKey];
|
|
8749
|
+
}
|
|
8702
8750
|
return;
|
|
8703
8751
|
}
|
|
8704
|
-
if (ctx.isOptionId(fromId) && ctx.isFieldId(toId2)) {
|
|
8705
|
-
const mapKey = kind === "include" ? "includes_for_options" : "excludes_for_options";
|
|
8752
|
+
if ((ctx.isFieldId(fromId) || ctx.isOptionId(fromId)) && ctx.isFieldId(toId2)) {
|
|
8706
8753
|
const maps = p[mapKey];
|
|
8707
|
-
if (!maps) return;
|
|
8708
|
-
|
|
8709
|
-
|
|
8710
|
-
|
|
8711
|
-
|
|
8712
|
-
|
|
8754
|
+
if (!(maps == null ? void 0 : maps[fromId])) return;
|
|
8755
|
+
maps[fromId] = maps[fromId].filter(
|
|
8756
|
+
(fid) => fid !== toId2
|
|
8757
|
+
);
|
|
8758
|
+
if (!((_g = maps[fromId]) == null ? void 0 : _g.length)) {
|
|
8759
|
+
delete maps[fromId];
|
|
8760
|
+
}
|
|
8761
|
+
if (!Object.keys(maps).length) {
|
|
8762
|
+
delete p[mapKey];
|
|
8713
8763
|
}
|
|
8714
|
-
if (!Object.keys(maps).length) delete p[mapKey];
|
|
8715
8764
|
return;
|
|
8716
8765
|
}
|
|
8717
|
-
throw new Error(
|
|
8766
|
+
throw new Error(
|
|
8767
|
+
`${kind}: unsupported route ${fromId} ? ${toId2}`
|
|
8768
|
+
);
|
|
8718
8769
|
}
|
|
8719
8770
|
if (kind === "service") {
|
|
8720
8771
|
ensureServiceExists(ctx.opts, fromId);
|
|
8721
8772
|
if (toId2.startsWith("t:")) {
|
|
8722
|
-
|
|
8723
|
-
|
|
8724
|
-
|
|
8725
|
-
|
|
8726
|
-
const t = ((_a2 = next.filters) != null ? _a2 : []).find((x) => x.id === toId2);
|
|
8727
|
-
if (t) delete t.service_id;
|
|
8728
|
-
}),
|
|
8729
|
-
undo: () => ctx.undo()
|
|
8730
|
-
});
|
|
8773
|
+
const t = ((_h = p.filters) != null ? _h : []).find((x) => x.id === toId2);
|
|
8774
|
+
if (t) {
|
|
8775
|
+
delete t.service_id;
|
|
8776
|
+
}
|
|
8731
8777
|
return;
|
|
8732
8778
|
}
|
|
8733
8779
|
if (toId2.startsWith("o:")) {
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
8740
|
-
|
|
8741
|
-
delete o.service_id;
|
|
8742
|
-
return;
|
|
8743
|
-
}
|
|
8744
|
-
}
|
|
8745
|
-
}),
|
|
8746
|
-
undo: () => ctx.undo()
|
|
8747
|
-
});
|
|
8780
|
+
for (const f of (_i = p.fields) != null ? _i : []) {
|
|
8781
|
+
const o = (_j = f.options) == null ? void 0 : _j.find((x) => x.id === toId2);
|
|
8782
|
+
if (o) {
|
|
8783
|
+
delete o.service_id;
|
|
8784
|
+
return;
|
|
8785
|
+
}
|
|
8786
|
+
}
|
|
8748
8787
|
return;
|
|
8749
8788
|
}
|
|
8750
|
-
throw new Error(
|
|
8789
|
+
throw new Error(
|
|
8790
|
+
'service: to must be a tag ("t:*") or option ("o:*")'
|
|
8791
|
+
);
|
|
8751
8792
|
}
|
|
8752
8793
|
throw new Error(`Unknown disconnect kind: ${kind}`);
|
|
8753
8794
|
}),
|
|
8754
8795
|
undo: () => ctx.undo()
|
|
8755
8796
|
});
|
|
8756
8797
|
}
|
|
8798
|
+
function addMappedField(p, mapKey, fromId, toId2) {
|
|
8799
|
+
var _a, _b;
|
|
8800
|
+
const maps = (_a = p[mapKey]) != null ? _a : {};
|
|
8801
|
+
const arr = (_b = maps[fromId]) != null ? _b : [];
|
|
8802
|
+
if (!arr.includes(toId2)) {
|
|
8803
|
+
maps[fromId] = [...arr, toId2];
|
|
8804
|
+
}
|
|
8805
|
+
p[mapKey] = maps;
|
|
8806
|
+
}
|
|
8757
8807
|
|
|
8758
8808
|
// src/react/canvas/editor/editor-service-filter.ts
|
|
8759
8809
|
function filterServicesForVisibleGroup2(ctx, candidates, input) {
|