@tscircuit/core 0.0.994 → 0.0.995
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/index.d.ts +1162 -4
- package/dist/index.js +181 -60
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -78,6 +78,7 @@ __export(components_exports, {
|
|
|
78
78
|
SmtPad: () => SmtPad,
|
|
79
79
|
SolderJumper: () => SolderJumper,
|
|
80
80
|
Subcircuit: () => Subcircuit,
|
|
81
|
+
Subpanel: () => Subpanel,
|
|
81
82
|
Switch: () => Switch,
|
|
82
83
|
Symbol: () => SymbolComponent,
|
|
83
84
|
TestPoint: () => TestPoint,
|
|
@@ -16682,6 +16683,10 @@ var Board = class extends Group6 {
|
|
|
16682
16683
|
|
|
16683
16684
|
// lib/components/normal-components/Panel.ts
|
|
16684
16685
|
import { panelProps } from "@tscircuit/props";
|
|
16686
|
+
import { distance as distance12 } from "circuit-json";
|
|
16687
|
+
|
|
16688
|
+
// lib/components/normal-components/Subpanel.ts
|
|
16689
|
+
import { subpanelProps } from "@tscircuit/props";
|
|
16685
16690
|
import { distance as distance11 } from "circuit-json";
|
|
16686
16691
|
|
|
16687
16692
|
// lib/utils/panels/generate-panel-tabs-and-mouse-bites.ts
|
|
@@ -17017,16 +17022,19 @@ var packBoardsIntoGrid = ({
|
|
|
17017
17022
|
return { positions, gridWidth: totalGridWidth, gridHeight: totalGridHeight };
|
|
17018
17023
|
};
|
|
17019
17024
|
|
|
17020
|
-
// lib/components/normal-components/
|
|
17021
|
-
var
|
|
17025
|
+
// lib/components/normal-components/Subpanel.ts
|
|
17026
|
+
var Subpanel = class _Subpanel extends Group6 {
|
|
17022
17027
|
pcb_panel_id = null;
|
|
17023
17028
|
_tabsAndMouseBitesGenerated = false;
|
|
17024
17029
|
get config() {
|
|
17025
17030
|
return {
|
|
17026
|
-
componentName: "
|
|
17027
|
-
zodProps:
|
|
17031
|
+
componentName: "Subpanel",
|
|
17032
|
+
zodProps: subpanelProps
|
|
17028
17033
|
};
|
|
17029
17034
|
}
|
|
17035
|
+
get _errorComponentName() {
|
|
17036
|
+
return this.componentName.toLowerCase();
|
|
17037
|
+
}
|
|
17030
17038
|
get isGroup() {
|
|
17031
17039
|
return true;
|
|
17032
17040
|
}
|
|
@@ -17034,19 +17042,55 @@ var Panel = class extends Group6 {
|
|
|
17034
17042
|
return true;
|
|
17035
17043
|
}
|
|
17036
17044
|
add(component) {
|
|
17037
|
-
if (component.lowercaseComponentName !== "board") {
|
|
17038
|
-
throw new Error(
|
|
17045
|
+
if (component.lowercaseComponentName !== "board" && component.lowercaseComponentName !== "subpanel") {
|
|
17046
|
+
throw new Error(
|
|
17047
|
+
`<${this._errorComponentName}> can only contain <board> or <subpanel> elements`
|
|
17048
|
+
);
|
|
17039
17049
|
}
|
|
17040
17050
|
super.add(component);
|
|
17041
17051
|
}
|
|
17042
17052
|
_cachedGridWidth = 0;
|
|
17043
17053
|
_cachedGridHeight = 0;
|
|
17054
|
+
/**
|
|
17055
|
+
* Get all board instances from this subpanel and nested subpanels
|
|
17056
|
+
*/
|
|
17057
|
+
_getAllBoardInstances() {
|
|
17058
|
+
const boards = [];
|
|
17059
|
+
for (const child of this.children) {
|
|
17060
|
+
if (child instanceof Board) {
|
|
17061
|
+
boards.push(child);
|
|
17062
|
+
} else if (child instanceof _Subpanel) {
|
|
17063
|
+
boards.push(...child._getAllBoardInstances());
|
|
17064
|
+
}
|
|
17065
|
+
}
|
|
17066
|
+
return boards;
|
|
17067
|
+
}
|
|
17068
|
+
/**
|
|
17069
|
+
* Check if this subpanel contains at least one board (directly or through nested subpanels)
|
|
17070
|
+
*/
|
|
17071
|
+
_containsBoards() {
|
|
17072
|
+
for (const child of this.children) {
|
|
17073
|
+
if (child.componentName === "Board") {
|
|
17074
|
+
return true;
|
|
17075
|
+
}
|
|
17076
|
+
if (child.componentName === "Subpanel" && "_containsBoards" in child) {
|
|
17077
|
+
if (child._containsBoards()) {
|
|
17078
|
+
return true;
|
|
17079
|
+
}
|
|
17080
|
+
}
|
|
17081
|
+
}
|
|
17082
|
+
return false;
|
|
17083
|
+
}
|
|
17084
|
+
/**
|
|
17085
|
+
* Get direct board children only (not from nested subpanels)
|
|
17086
|
+
*/
|
|
17087
|
+
_getDirectBoardChildren() {
|
|
17088
|
+
return this.children.filter((c) => c instanceof Board);
|
|
17089
|
+
}
|
|
17044
17090
|
doInitialPanelBoardLayout() {
|
|
17045
17091
|
if (this.root?.pcbDisabled) return;
|
|
17046
17092
|
const layoutMode = this._parsedProps.layoutMode ?? "none";
|
|
17047
|
-
const childBoardInstances = this.
|
|
17048
|
-
(c) => c instanceof Board
|
|
17049
|
-
);
|
|
17093
|
+
const childBoardInstances = this._getDirectBoardChildren();
|
|
17050
17094
|
if (layoutMode !== "none") {
|
|
17051
17095
|
for (const board of childBoardInstances) {
|
|
17052
17096
|
const hasPcbX = board._parsedProps.pcbX !== void 0;
|
|
@@ -17059,7 +17103,7 @@ var Panel = class extends Group6 {
|
|
|
17059
17103
|
this.root.db.source_property_ignored_warning.insert({
|
|
17060
17104
|
source_component_id: board.source_component_id,
|
|
17061
17105
|
property_name: propertyNames,
|
|
17062
|
-
message: `Board has manual positioning (${propertyNames}) but
|
|
17106
|
+
message: `Board has manual positioning (${propertyNames}) but ${this._errorComponentName} layout mode is "${layoutMode}". Manual positioning will be ignored.`,
|
|
17063
17107
|
error_type: "source_property_ignored_warning"
|
|
17064
17108
|
});
|
|
17065
17109
|
}
|
|
@@ -17074,7 +17118,7 @@ var Panel = class extends Group6 {
|
|
|
17074
17118
|
if (boardsWithoutPosition.length > 1) {
|
|
17075
17119
|
this.root.db.pcb_placement_error.insert({
|
|
17076
17120
|
error_type: "pcb_placement_error",
|
|
17077
|
-
message: `Multiple boards in
|
|
17121
|
+
message: `Multiple boards in ${this._errorComponentName} without pcbX/pcbY positions. When layoutMode="none", each board must have explicit pcbX and pcbY coordinates to avoid overlapping. Either set pcbX/pcbY on each board, or use layoutMode="grid" for automatic positioning.`
|
|
17078
17122
|
});
|
|
17079
17123
|
}
|
|
17080
17124
|
}
|
|
@@ -17098,9 +17142,7 @@ var Panel = class extends Group6 {
|
|
|
17098
17142
|
doInitialPanelLayout() {
|
|
17099
17143
|
if (this.root?.pcbDisabled) return;
|
|
17100
17144
|
const { db } = this.root;
|
|
17101
|
-
const childBoardInstances = this.
|
|
17102
|
-
(c) => c instanceof Board
|
|
17103
|
-
);
|
|
17145
|
+
const childBoardInstances = this._getDirectBoardChildren();
|
|
17104
17146
|
const layoutMode = this._parsedProps.layoutMode ?? "none";
|
|
17105
17147
|
if (layoutMode === "grid") {
|
|
17106
17148
|
for (const board of childBoardInstances) {
|
|
@@ -17111,39 +17153,7 @@ var Panel = class extends Group6 {
|
|
|
17111
17153
|
display_offset_y: `${board._panelPositionOffset.y}mm`
|
|
17112
17154
|
});
|
|
17113
17155
|
}
|
|
17114
|
-
|
|
17115
|
-
const hasExplicitHeight = this._parsedProps.height !== void 0;
|
|
17116
|
-
const gridWidth = this._cachedGridWidth;
|
|
17117
|
-
const gridHeight = this._cachedGridHeight;
|
|
17118
|
-
if (hasExplicitWidth && hasExplicitHeight) {
|
|
17119
|
-
db.pcb_panel.update(this.pcb_panel_id, {
|
|
17120
|
-
width: distance11.parse(this._parsedProps.width),
|
|
17121
|
-
height: distance11.parse(this._parsedProps.height)
|
|
17122
|
-
});
|
|
17123
|
-
} else if (gridWidth > 0 || gridHeight > 0) {
|
|
17124
|
-
const {
|
|
17125
|
-
edgePadding: edgePaddingProp,
|
|
17126
|
-
edgePaddingLeft: edgePaddingLeftProp,
|
|
17127
|
-
edgePaddingRight: edgePaddingRightProp,
|
|
17128
|
-
edgePaddingTop: edgePaddingTopProp,
|
|
17129
|
-
edgePaddingBottom: edgePaddingBottomProp
|
|
17130
|
-
} = this._parsedProps;
|
|
17131
|
-
const edgePadding = distance11.parse(edgePaddingProp ?? 5);
|
|
17132
|
-
const edgePaddingLeft = distance11.parse(
|
|
17133
|
-
edgePaddingLeftProp ?? edgePadding
|
|
17134
|
-
);
|
|
17135
|
-
const edgePaddingRight = distance11.parse(
|
|
17136
|
-
edgePaddingRightProp ?? edgePadding
|
|
17137
|
-
);
|
|
17138
|
-
const edgePaddingTop = distance11.parse(edgePaddingTopProp ?? edgePadding);
|
|
17139
|
-
const edgePaddingBottom = distance11.parse(
|
|
17140
|
-
edgePaddingBottomProp ?? edgePadding
|
|
17141
|
-
);
|
|
17142
|
-
db.pcb_panel.update(this.pcb_panel_id, {
|
|
17143
|
-
width: hasExplicitWidth ? distance11.parse(this._parsedProps.width) : gridWidth + edgePaddingLeft + edgePaddingRight,
|
|
17144
|
-
height: hasExplicitHeight ? distance11.parse(this._parsedProps.height) : gridHeight + edgePaddingTop + edgePaddingBottom
|
|
17145
|
-
});
|
|
17146
|
-
}
|
|
17156
|
+
this._updatePanelDimensions();
|
|
17147
17157
|
} else {
|
|
17148
17158
|
const panelGlobalPos = this._getGlobalPcbPositionBeforeLayout();
|
|
17149
17159
|
for (const board of childBoardInstances) {
|
|
@@ -17158,9 +17168,55 @@ var Panel = class extends Group6 {
|
|
|
17158
17168
|
});
|
|
17159
17169
|
}
|
|
17160
17170
|
}
|
|
17171
|
+
this._generateTabsAndMouseBites();
|
|
17172
|
+
}
|
|
17173
|
+
/**
|
|
17174
|
+
* Update dimensions for the subpanel. Subpanel updates pcb_group,
|
|
17175
|
+
*/
|
|
17176
|
+
_updatePanelDimensions() {
|
|
17177
|
+
const { db } = this.root;
|
|
17178
|
+
const hasExplicitWidth = this._parsedProps.width !== void 0;
|
|
17179
|
+
const hasExplicitHeight = this._parsedProps.height !== void 0;
|
|
17180
|
+
const gridWidth = this._cachedGridWidth;
|
|
17181
|
+
const gridHeight = this._cachedGridHeight;
|
|
17182
|
+
if (!this.pcb_group_id) return;
|
|
17183
|
+
if (hasExplicitWidth && hasExplicitHeight) {
|
|
17184
|
+
db.pcb_group.update(this.pcb_group_id, {
|
|
17185
|
+
width: distance11.parse(this._parsedProps.width),
|
|
17186
|
+
height: distance11.parse(this._parsedProps.height)
|
|
17187
|
+
});
|
|
17188
|
+
} else if (gridWidth > 0 || gridHeight > 0) {
|
|
17189
|
+
const {
|
|
17190
|
+
edgePadding: edgePaddingProp,
|
|
17191
|
+
edgePaddingLeft: edgePaddingLeftProp,
|
|
17192
|
+
edgePaddingRight: edgePaddingRightProp,
|
|
17193
|
+
edgePaddingTop: edgePaddingTopProp,
|
|
17194
|
+
edgePaddingBottom: edgePaddingBottomProp
|
|
17195
|
+
} = this._parsedProps;
|
|
17196
|
+
const edgePadding = distance11.parse(edgePaddingProp ?? 5);
|
|
17197
|
+
const edgePaddingLeft = distance11.parse(edgePaddingLeftProp ?? edgePadding);
|
|
17198
|
+
const edgePaddingRight = distance11.parse(
|
|
17199
|
+
edgePaddingRightProp ?? edgePadding
|
|
17200
|
+
);
|
|
17201
|
+
const edgePaddingTop = distance11.parse(edgePaddingTopProp ?? edgePadding);
|
|
17202
|
+
const edgePaddingBottom = distance11.parse(
|
|
17203
|
+
edgePaddingBottomProp ?? edgePadding
|
|
17204
|
+
);
|
|
17205
|
+
db.pcb_group.update(this.pcb_group_id, {
|
|
17206
|
+
width: hasExplicitWidth ? distance11.parse(this._parsedProps.width) : gridWidth + edgePaddingLeft + edgePaddingRight,
|
|
17207
|
+
height: hasExplicitHeight ? distance11.parse(this._parsedProps.height) : gridHeight + edgePaddingTop + edgePaddingBottom
|
|
17208
|
+
});
|
|
17209
|
+
}
|
|
17210
|
+
}
|
|
17211
|
+
/**
|
|
17212
|
+
* Generate tabs and mouse bites for panelization
|
|
17213
|
+
*/
|
|
17214
|
+
_generateTabsAndMouseBites() {
|
|
17161
17215
|
if (this._tabsAndMouseBitesGenerated) return;
|
|
17216
|
+
const { db } = this.root;
|
|
17162
17217
|
const props = this._parsedProps;
|
|
17163
17218
|
const panelizationMethod = props.panelizationMethod ?? "none";
|
|
17219
|
+
const childBoardInstances = this._getDirectBoardChildren();
|
|
17164
17220
|
if (panelizationMethod !== "none") {
|
|
17165
17221
|
const childBoardIds = childBoardInstances.map((c) => c.pcb_board_id).filter((id) => !!id);
|
|
17166
17222
|
const boardsInPanel = db.pcb_board.list().filter((b) => childBoardIds.includes(b.pcb_board_id));
|
|
@@ -17185,24 +17241,88 @@ var Panel = class extends Group6 {
|
|
|
17185
17241
|
}
|
|
17186
17242
|
this._tabsAndMouseBitesGenerated = true;
|
|
17187
17243
|
}
|
|
17188
|
-
|
|
17189
|
-
|
|
17190
|
-
|
|
17244
|
+
/**
|
|
17245
|
+
* Override to validate board containment before rendering.
|
|
17246
|
+
* Subpanel uses parent Group's pcb_group rendering.
|
|
17247
|
+
*/
|
|
17248
|
+
doInitialPcbComponentRender() {
|
|
17249
|
+
if (this.root?.pcbDisabled) return;
|
|
17250
|
+
if (!this._containsBoards()) {
|
|
17251
|
+
throw new Error(
|
|
17252
|
+
`<${this._errorComponentName}> must contain at least one <board>`
|
|
17253
|
+
);
|
|
17191
17254
|
}
|
|
17192
|
-
super.
|
|
17255
|
+
super.doInitialPcbComponentRender();
|
|
17193
17256
|
}
|
|
17257
|
+
};
|
|
17258
|
+
|
|
17259
|
+
// lib/components/normal-components/Panel.ts
|
|
17260
|
+
var Panel = class extends Subpanel {
|
|
17261
|
+
get config() {
|
|
17262
|
+
return {
|
|
17263
|
+
componentName: "Panel",
|
|
17264
|
+
zodProps: panelProps
|
|
17265
|
+
};
|
|
17266
|
+
}
|
|
17267
|
+
/**
|
|
17268
|
+
* Panel creates a pcb_panel record for the physical manufacturing panel.
|
|
17269
|
+
* This overrides the Subpanel behavior which uses pcb_group.
|
|
17270
|
+
*/
|
|
17194
17271
|
doInitialPcbComponentRender() {
|
|
17195
17272
|
if (this.root?.pcbDisabled) return;
|
|
17273
|
+
if (!this._containsBoards()) {
|
|
17274
|
+
throw new Error(
|
|
17275
|
+
`<${this._errorComponentName}> must contain at least one <board>`
|
|
17276
|
+
);
|
|
17277
|
+
}
|
|
17196
17278
|
const { db } = this.root;
|
|
17197
17279
|
const props = this._parsedProps;
|
|
17198
17280
|
const inserted = db.pcb_panel.insert({
|
|
17199
|
-
width: props.width !== void 0 ?
|
|
17200
|
-
height: props.height !== void 0 ?
|
|
17281
|
+
width: props.width !== void 0 ? distance12.parse(props.width) : 0,
|
|
17282
|
+
height: props.height !== void 0 ? distance12.parse(props.height) : 0,
|
|
17201
17283
|
center: this._getGlobalPcbPositionBeforeLayout(),
|
|
17202
17284
|
covered_with_solder_mask: !(props.noSolderMask ?? false)
|
|
17203
17285
|
});
|
|
17204
17286
|
this.pcb_panel_id = inserted.pcb_panel_id;
|
|
17205
17287
|
}
|
|
17288
|
+
/**
|
|
17289
|
+
* Panel updates pcb_panel dimensions instead of pcb_group
|
|
17290
|
+
*/
|
|
17291
|
+
_updatePanelDimensions() {
|
|
17292
|
+
const { db } = this.root;
|
|
17293
|
+
const hasExplicitWidth = this._parsedProps.width !== void 0;
|
|
17294
|
+
const hasExplicitHeight = this._parsedProps.height !== void 0;
|
|
17295
|
+
const gridWidth = this._cachedGridWidth;
|
|
17296
|
+
const gridHeight = this._cachedGridHeight;
|
|
17297
|
+
if (!this.pcb_panel_id) return;
|
|
17298
|
+
if (hasExplicitWidth && hasExplicitHeight) {
|
|
17299
|
+
db.pcb_panel.update(this.pcb_panel_id, {
|
|
17300
|
+
width: distance12.parse(this._parsedProps.width),
|
|
17301
|
+
height: distance12.parse(this._parsedProps.height)
|
|
17302
|
+
});
|
|
17303
|
+
} else if (gridWidth > 0 || gridHeight > 0) {
|
|
17304
|
+
const {
|
|
17305
|
+
edgePadding: edgePaddingProp,
|
|
17306
|
+
edgePaddingLeft: edgePaddingLeftProp,
|
|
17307
|
+
edgePaddingRight: edgePaddingRightProp,
|
|
17308
|
+
edgePaddingTop: edgePaddingTopProp,
|
|
17309
|
+
edgePaddingBottom: edgePaddingBottomProp
|
|
17310
|
+
} = this._parsedProps;
|
|
17311
|
+
const edgePadding = distance12.parse(edgePaddingProp ?? 5);
|
|
17312
|
+
const edgePaddingLeft = distance12.parse(edgePaddingLeftProp ?? edgePadding);
|
|
17313
|
+
const edgePaddingRight = distance12.parse(
|
|
17314
|
+
edgePaddingRightProp ?? edgePadding
|
|
17315
|
+
);
|
|
17316
|
+
const edgePaddingTop = distance12.parse(edgePaddingTopProp ?? edgePadding);
|
|
17317
|
+
const edgePaddingBottom = distance12.parse(
|
|
17318
|
+
edgePaddingBottomProp ?? edgePadding
|
|
17319
|
+
);
|
|
17320
|
+
db.pcb_panel.update(this.pcb_panel_id, {
|
|
17321
|
+
width: hasExplicitWidth ? distance12.parse(this._parsedProps.width) : gridWidth + edgePaddingLeft + edgePaddingRight,
|
|
17322
|
+
height: hasExplicitHeight ? distance12.parse(this._parsedProps.height) : gridHeight + edgePaddingTop + edgePaddingBottom
|
|
17323
|
+
});
|
|
17324
|
+
}
|
|
17325
|
+
}
|
|
17206
17326
|
updatePcbComponentRender() {
|
|
17207
17327
|
if (this.root?.pcbDisabled) return;
|
|
17208
17328
|
if (!this.pcb_panel_id) return;
|
|
@@ -17210,8 +17330,8 @@ var Panel = class extends Group6 {
|
|
|
17210
17330
|
const props = this._parsedProps;
|
|
17211
17331
|
const currentPanel = db.pcb_panel.get(this.pcb_panel_id);
|
|
17212
17332
|
db.pcb_panel.update(this.pcb_panel_id, {
|
|
17213
|
-
width: props.width !== void 0 ?
|
|
17214
|
-
height: props.height !== void 0 ?
|
|
17333
|
+
width: props.width !== void 0 ? distance12.parse(props.width) : currentPanel?.width,
|
|
17334
|
+
height: props.height !== void 0 ? distance12.parse(props.height) : currentPanel?.height,
|
|
17215
17335
|
center: this._getGlobalPcbPositionBeforeLayout(),
|
|
17216
17336
|
covered_with_solder_mask: !(props.noSolderMask ?? false)
|
|
17217
17337
|
});
|
|
@@ -19223,7 +19343,7 @@ var SilkscreenLine = class extends PrimitiveComponent2 {
|
|
|
19223
19343
|
|
|
19224
19344
|
// lib/components/primitive-components/Fiducial.ts
|
|
19225
19345
|
import "zod";
|
|
19226
|
-
import { distance as
|
|
19346
|
+
import { distance as distance13 } from "circuit-json";
|
|
19227
19347
|
import { fiducialProps } from "@tscircuit/props";
|
|
19228
19348
|
var Fiducial = class extends PrimitiveComponent2 {
|
|
19229
19349
|
pcb_smtpad_id = null;
|
|
@@ -19248,15 +19368,15 @@ var Fiducial = class extends PrimitiveComponent2 {
|
|
|
19248
19368
|
shape: "circle",
|
|
19249
19369
|
x: position.x,
|
|
19250
19370
|
y: position.y,
|
|
19251
|
-
radius:
|
|
19252
|
-
soldermask_margin: props.soldermaskPullback ?
|
|
19371
|
+
radius: distance13.parse(props.padDiameter) / 2,
|
|
19372
|
+
soldermask_margin: props.soldermaskPullback ? distance13.parse(props.soldermaskPullback) : distance13.parse(props.padDiameter) / 2,
|
|
19253
19373
|
is_covered_with_solder_mask: true
|
|
19254
19374
|
});
|
|
19255
19375
|
this.pcb_smtpad_id = pcb_smtpad.pcb_smtpad_id;
|
|
19256
19376
|
}
|
|
19257
19377
|
getPcbSize() {
|
|
19258
19378
|
const { _parsedProps: props } = this;
|
|
19259
|
-
const d =
|
|
19379
|
+
const d = distance13.parse(props.padDiameter);
|
|
19260
19380
|
return { width: d, height: d };
|
|
19261
19381
|
}
|
|
19262
19382
|
_setPositionFromLayout(newCenter) {
|
|
@@ -21197,7 +21317,7 @@ import { identity as identity5 } from "transformation-matrix";
|
|
|
21197
21317
|
var package_default = {
|
|
21198
21318
|
name: "@tscircuit/core",
|
|
21199
21319
|
type: "module",
|
|
21200
|
-
version: "0.0.
|
|
21320
|
+
version: "0.0.994",
|
|
21201
21321
|
types: "dist/index.d.ts",
|
|
21202
21322
|
main: "dist/index.js",
|
|
21203
21323
|
module: "dist/index.js",
|
|
@@ -21847,6 +21967,7 @@ export {
|
|
|
21847
21967
|
SmtPad,
|
|
21848
21968
|
SolderJumper,
|
|
21849
21969
|
Subcircuit,
|
|
21970
|
+
Subpanel,
|
|
21850
21971
|
Switch,
|
|
21851
21972
|
SymbolComponent as Symbol,
|
|
21852
21973
|
TestPoint,
|