@intelligentelectron/universal-netlist 0.0.12

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 (105) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/LICENSE +190 -0
  3. package/NOTICE +4 -0
  4. package/README.md +246 -0
  5. package/dist/circuit-traversal.d.ts +73 -0
  6. package/dist/circuit-traversal.d.ts.map +1 -0
  7. package/dist/circuit-traversal.js +299 -0
  8. package/dist/circuit-traversal.js.map +1 -0
  9. package/dist/cli/commands.d.ts +23 -0
  10. package/dist/cli/commands.d.ts.map +1 -0
  11. package/dist/cli/commands.js +140 -0
  12. package/dist/cli/commands.js.map +1 -0
  13. package/dist/cli/prompts.d.ts +10 -0
  14. package/dist/cli/prompts.d.ts.map +1 -0
  15. package/dist/cli/prompts.js +22 -0
  16. package/dist/cli/prompts.js.map +1 -0
  17. package/dist/cli/shell.d.ts +15 -0
  18. package/dist/cli/shell.d.ts.map +1 -0
  19. package/dist/cli/shell.js +66 -0
  20. package/dist/cli/shell.js.map +1 -0
  21. package/dist/cli/updater.d.ts +46 -0
  22. package/dist/cli/updater.d.ts.map +1 -0
  23. package/dist/cli/updater.js +319 -0
  24. package/dist/cli/updater.js.map +1 -0
  25. package/dist/index.d.ts +16 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +63 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/parsers/altium/connectivity.d.ts +32 -0
  30. package/dist/parsers/altium/connectivity.d.ts.map +1 -0
  31. package/dist/parsers/altium/connectivity.js +308 -0
  32. package/dist/parsers/altium/connectivity.js.map +1 -0
  33. package/dist/parsers/altium/discovery.d.ts +30 -0
  34. package/dist/parsers/altium/discovery.d.ts.map +1 -0
  35. package/dist/parsers/altium/discovery.js +174 -0
  36. package/dist/parsers/altium/discovery.js.map +1 -0
  37. package/dist/parsers/altium/hierarchy.d.ts +29 -0
  38. package/dist/parsers/altium/hierarchy.d.ts.map +1 -0
  39. package/dist/parsers/altium/hierarchy.js +94 -0
  40. package/dist/parsers/altium/hierarchy.js.map +1 -0
  41. package/dist/parsers/altium/index.d.ts +53 -0
  42. package/dist/parsers/altium/index.d.ts.map +1 -0
  43. package/dist/parsers/altium/index.js +404 -0
  44. package/dist/parsers/altium/index.js.map +1 -0
  45. package/dist/parsers/altium/net-extractor.d.ts +24 -0
  46. package/dist/parsers/altium/net-extractor.d.ts.map +1 -0
  47. package/dist/parsers/altium/net-extractor.js +295 -0
  48. package/dist/parsers/altium/net-extractor.js.map +1 -0
  49. package/dist/parsers/altium/ole-reader.d.ts +91 -0
  50. package/dist/parsers/altium/ole-reader.d.ts.map +1 -0
  51. package/dist/parsers/altium/ole-reader.js +304 -0
  52. package/dist/parsers/altium/ole-reader.js.map +1 -0
  53. package/dist/parsers/altium/record-parser.d.ts +21 -0
  54. package/dist/parsers/altium/record-parser.d.ts.map +1 -0
  55. package/dist/parsers/altium/record-parser.js +117 -0
  56. package/dist/parsers/altium/record-parser.js.map +1 -0
  57. package/dist/parsers/altium/schemas.d.ts +277 -0
  58. package/dist/parsers/altium/schemas.d.ts.map +1 -0
  59. package/dist/parsers/altium/schemas.js +246 -0
  60. package/dist/parsers/altium/schemas.js.map +1 -0
  61. package/dist/parsers/altium/types.d.ts +213 -0
  62. package/dist/parsers/altium/types.d.ts.map +1 -0
  63. package/dist/parsers/altium/types.js +180 -0
  64. package/dist/parsers/altium/types.js.map +1 -0
  65. package/dist/parsers/cadence/discovery.d.ts +45 -0
  66. package/dist/parsers/cadence/discovery.d.ts.map +1 -0
  67. package/dist/parsers/cadence/discovery.js +277 -0
  68. package/dist/parsers/cadence/discovery.js.map +1 -0
  69. package/dist/parsers/cadence/index.d.ts +41 -0
  70. package/dist/parsers/cadence/index.d.ts.map +1 -0
  71. package/dist/parsers/cadence/index.js +139 -0
  72. package/dist/parsers/cadence/index.js.map +1 -0
  73. package/dist/parsers/cadence/pstchip-parser.d.ts +23 -0
  74. package/dist/parsers/cadence/pstchip-parser.d.ts.map +1 -0
  75. package/dist/parsers/cadence/pstchip-parser.js +82 -0
  76. package/dist/parsers/cadence/pstchip-parser.js.map +1 -0
  77. package/dist/parsers/cadence/pstxnet-parser.d.ts +15 -0
  78. package/dist/parsers/cadence/pstxnet-parser.d.ts.map +1 -0
  79. package/dist/parsers/cadence/pstxnet-parser.js +55 -0
  80. package/dist/parsers/cadence/pstxnet-parser.js.map +1 -0
  81. package/dist/parsers/cadence/pstxprt-parser.d.ts +24 -0
  82. package/dist/parsers/cadence/pstxprt-parser.d.ts.map +1 -0
  83. package/dist/parsers/cadence/pstxprt-parser.js +75 -0
  84. package/dist/parsers/cadence/pstxprt-parser.js.map +1 -0
  85. package/dist/parsers/index.d.ts +33 -0
  86. package/dist/parsers/index.d.ts.map +1 -0
  87. package/dist/parsers/index.js +49 -0
  88. package/dist/parsers/index.js.map +1 -0
  89. package/dist/server.d.ts +16 -0
  90. package/dist/server.d.ts.map +1 -0
  91. package/dist/server.js +277 -0
  92. package/dist/server.js.map +1 -0
  93. package/dist/service.d.ts +129 -0
  94. package/dist/service.d.ts.map +1 -0
  95. package/dist/service.js +759 -0
  96. package/dist/service.js.map +1 -0
  97. package/dist/types.d.ts +242 -0
  98. package/dist/types.d.ts.map +1 -0
  99. package/dist/types.js +27 -0
  100. package/dist/types.js.map +1 -0
  101. package/dist/version.d.ts +10 -0
  102. package/dist/version.d.ts.map +1 -0
  103. package/dist/version.js +25 -0
  104. package/dist/version.js.map +1 -0
  105. package/package.json +74 -0
@@ -0,0 +1,295 @@
1
+ /**
2
+ * Altium Net Extractor
3
+ *
4
+ * Extracts net information from Altium schematics by analyzing
5
+ * wires, pins, power ports, and net labels.
6
+ */
7
+ import { RECORD_TYPES } from './types.js';
8
+ import { findAllConnectedComponents } from './connectivity.js';
9
+ import { findRecordByIndex } from './hierarchy.js';
10
+ const COORDINATE_SCALE = 10000;
11
+ const toNumber = (value) => {
12
+ if (value === undefined || value === null || value === '') {
13
+ return 0;
14
+ }
15
+ const parsed = Number(value);
16
+ return Number.isNaN(parsed) ? 0 : parsed;
17
+ };
18
+ const scaledCoordinate = (base, frac) => {
19
+ return Math.round(toNumber(base) * COORDINATE_SCALE + toNumber(frac));
20
+ };
21
+ const pinMatchesCurrentPart = (pin, schematic) => {
22
+ const ownerIndexValue = pin.OwnerIndex ?? pin.OWNERINDEX;
23
+ if (ownerIndexValue === undefined || ownerIndexValue === null || ownerIndexValue === '') {
24
+ return true;
25
+ }
26
+ const ownerIndex = parseInt(String(ownerIndexValue), 10);
27
+ const parent = findRecordByIndex(schematic, ownerIndex);
28
+ if (!parent) {
29
+ return true;
30
+ }
31
+ const parentPartId = parent.CURRENTPARTID ?? parent.CurrentPartId ?? parent.CurrentPartID;
32
+ const pinPartId = pin.OwnerPartId ?? pin.OWNERPARTID;
33
+ if (parentPartId === undefined ||
34
+ parentPartId === null ||
35
+ parentPartId === '' ||
36
+ pinPartId === undefined ||
37
+ pinPartId === null ||
38
+ pinPartId === '') {
39
+ return true;
40
+ }
41
+ return String(parentPartId) === String(pinPartId);
42
+ };
43
+ /**
44
+ * Find all devices that can be part of a net.
45
+ *
46
+ * These are: wires (27), pins (2), net labels (25), power ports (17)
47
+ */
48
+ const findConnectableDevices = (schematic) => {
49
+ const devices = [];
50
+ const connectableTypes = new Set([
51
+ RECORD_TYPES.WIRE,
52
+ RECORD_TYPES.PIN,
53
+ RECORD_TYPES.NET_LABEL,
54
+ RECORD_TYPES.POWER_PORT,
55
+ ]);
56
+ const collectDevices = (records) => {
57
+ for (const record of records) {
58
+ if (record.RECORD === RECORD_TYPES.PIN && !pinMatchesCurrentPart(record, schematic)) {
59
+ continue;
60
+ }
61
+ if (record.RECORD && connectableTypes.has(record.RECORD)) {
62
+ devices.push(record);
63
+ }
64
+ if (record.children) {
65
+ collectDevices(record.children);
66
+ }
67
+ }
68
+ };
69
+ collectDevices(schematic.records);
70
+ return devices;
71
+ };
72
+ /**
73
+ * Calculate pin coordinates.
74
+ *
75
+ * Pin rotation is encoded in PINCONGLOMERATE (lower 2 bits * 90 degrees).
76
+ * The endpoint is calculated using: location + rotation * pin_length.
77
+ * We keep both the pin origin and endpoint so connectivity works at either end.
78
+ */
79
+ const calculatePinCoordinates = (device) => {
80
+ const locationX = scaledCoordinate(device['Location.X'] ?? device['LOCATION.X'], device['Location.X_Frac'] ?? device['LOCATION.X_FRAC']);
81
+ const locationY = scaledCoordinate(device['Location.Y'] ?? device['LOCATION.Y'], device['Location.Y_Frac'] ?? device['LOCATION.Y_FRAC']);
82
+ const pinLength = scaledCoordinate(device['PinLength'] ?? device['PINLENGTH'], device['PinLength_Frac'] ?? device['PINLENGTH_FRAC']);
83
+ const pinConglomerate = parseInt(String(device['PinConglomerate'] || device['PINCONGLOMERATE'] || '0'), 10);
84
+ // Extract rotation from lower 2 bits (0-3 -> 0, 90, 180, 270 degrees)
85
+ const rotationIndex = pinConglomerate & 0x03;
86
+ const rotationDegrees = rotationIndex * 90;
87
+ const rotationRadians = (rotationDegrees / 180) * Math.PI;
88
+ // Calculate pin endpoint
89
+ const endX = Math.round(locationX + Math.cos(rotationRadians) * pinLength);
90
+ const endY = Math.round(locationY + Math.sin(rotationRadians) * pinLength);
91
+ device.coords = [
92
+ [locationX, locationY],
93
+ [endX, endY],
94
+ ];
95
+ };
96
+ /**
97
+ * Calculate wire coordinates.
98
+ *
99
+ * Wires have coordinates stored as X1,Y1,X2,Y2,... pairs.
100
+ */
101
+ const calculateWireCoordinates = (device) => {
102
+ const coords = [];
103
+ // Pattern: X1, Y1, X2, Y2, etc.
104
+ const coordPattern = /^X(\d+)$/;
105
+ // Find all X coordinate keys and extract their indices
106
+ const indices = [];
107
+ for (const key of Object.keys(device)) {
108
+ const match = key.match(coordPattern);
109
+ if (match) {
110
+ indices.push(parseInt(match[1], 10));
111
+ }
112
+ }
113
+ // Sort indices and build coordinate array
114
+ indices.sort((a, b) => a - b);
115
+ for (const idx of indices) {
116
+ const x = scaledCoordinate(device[`X${idx}`], device[`X${idx}_Frac`] ?? device[`X${idx}_FRAC`]);
117
+ const y = scaledCoordinate(device[`Y${idx}`], device[`Y${idx}_Frac`] ?? device[`Y${idx}_FRAC`]);
118
+ coords.push([x, y]);
119
+ }
120
+ device.coords = coords;
121
+ };
122
+ /**
123
+ * Calculate simple location coordinates.
124
+ *
125
+ * Used for power ports, net labels, etc.
126
+ */
127
+ const calculateSimpleCoordinates = (device) => {
128
+ const x = scaledCoordinate(device['Location.X'] ?? device['LOCATION.X'], device['Location.X_Frac'] ?? device['LOCATION.X_FRAC']);
129
+ const y = scaledCoordinate(device['Location.Y'] ?? device['LOCATION.Y'], device['Location.Y_Frac'] ?? device['LOCATION.Y_FRAC']);
130
+ device.coords = [[x, y]];
131
+ };
132
+ /**
133
+ * Calculate coordinates for a device.
134
+ *
135
+ * Different device types have coordinates stored differently:
136
+ * - Pins: calculated from location + rotation + pin length
137
+ * - Wires: multiple X/Y coordinate pairs (X1,Y1,X2,Y2,...)
138
+ * - Others: simple LOCATION.X and LOCATION.Y
139
+ */
140
+ const calculateDeviceCoordinates = (device) => {
141
+ if (device.RECORD === RECORD_TYPES.PIN) {
142
+ calculatePinCoordinates(device);
143
+ }
144
+ else if (device.RECORD === RECORD_TYPES.WIRE) {
145
+ calculateWireCoordinates(device);
146
+ }
147
+ else {
148
+ calculateSimpleCoordinates(device);
149
+ }
150
+ };
151
+ const getPinNumber = (device) => {
152
+ const designator = device.Designator ?? device.DESIGNATOR;
153
+ if (designator !== undefined && designator !== null && designator !== '') {
154
+ return String(designator);
155
+ }
156
+ const name = device.Name ?? device.NAME;
157
+ if (name !== undefined && name !== null && name !== '') {
158
+ return String(name);
159
+ }
160
+ return null;
161
+ };
162
+ const getRefdesForPin = (device, schematic) => {
163
+ const ownerIndexValue = device.OwnerIndex ?? device.OWNERINDEX;
164
+ if (ownerIndexValue === undefined || ownerIndexValue === null || ownerIndexValue === '') {
165
+ return null;
166
+ }
167
+ const ownerIndex = parseInt(String(ownerIndexValue), 10);
168
+ const parent = findRecordByIndex(schematic, ownerIndex);
169
+ if (!parent?.children) {
170
+ return null;
171
+ }
172
+ for (const child of parent.children) {
173
+ if (child.RECORD !== RECORD_TYPES.DESIGNATOR) {
174
+ continue;
175
+ }
176
+ const textValue = child.Text ?? child.TEXT ?? child.Name ?? child.NAME;
177
+ if (textValue !== undefined && textValue !== null && textValue !== '') {
178
+ return String(textValue);
179
+ }
180
+ }
181
+ return null;
182
+ };
183
+ const comparePinNumbers = (a, b) => {
184
+ const aNum = Number.parseInt(a, 10);
185
+ const bNum = Number.parseInt(b, 10);
186
+ if (!Number.isNaN(aNum) && !Number.isNaN(bNum)) {
187
+ return aNum - bNum;
188
+ }
189
+ if (!Number.isNaN(aNum))
190
+ return -1;
191
+ if (!Number.isNaN(bNum))
192
+ return 1;
193
+ return a.localeCompare(b);
194
+ };
195
+ const collectPinCandidates = (net, schematic) => {
196
+ const refdesPins = new Map();
197
+ for (const device of net.devices) {
198
+ if (device.RECORD !== RECORD_TYPES.PIN) {
199
+ continue;
200
+ }
201
+ const refdes = getRefdesForPin(device, schematic);
202
+ const pinNumber = getPinNumber(device);
203
+ if (!refdes || !pinNumber) {
204
+ continue;
205
+ }
206
+ if (!refdesPins.has(refdes)) {
207
+ refdesPins.set(refdes, []);
208
+ }
209
+ const pins = refdesPins.get(refdes);
210
+ if (!pins.includes(pinNumber)) {
211
+ pins.push(pinNumber);
212
+ }
213
+ }
214
+ return refdesPins;
215
+ };
216
+ /**
217
+ * Assign a name to a net.
218
+ *
219
+ * Priority:
220
+ * 1. Power port TEXT value
221
+ * 2. Net label TEXT value
222
+ * 3. Pin-derived name (Net<Refdes>_<Pin>) using the lowest refdes/pin in the net
223
+ */
224
+ const assignNetName = (net, schematic) => {
225
+ // Try power ports and net labels first
226
+ for (const device of net.devices) {
227
+ if ((device.RECORD === RECORD_TYPES.POWER_PORT || device.RECORD === RECORD_TYPES.NET_LABEL) &&
228
+ (device.Text !== undefined || device.TEXT !== undefined)) {
229
+ const textValue = device.Text ?? device.TEXT;
230
+ if (textValue !== undefined && textValue !== null && textValue !== '') {
231
+ net.name = String(textValue);
232
+ return;
233
+ }
234
+ }
235
+ }
236
+ const refdesPins = collectPinCandidates(net, schematic);
237
+ if (refdesPins.size === 0) {
238
+ return;
239
+ }
240
+ const sortedRefdes = Array.from(refdesPins.keys()).sort((a, b) => a.localeCompare(b));
241
+ const selectedRefdes = sortedRefdes[0];
242
+ const pinNumbers = refdesPins.get(selectedRefdes);
243
+ if (!pinNumbers || pinNumbers.length === 0) {
244
+ return;
245
+ }
246
+ pinNumbers.sort(comparePinNumbers);
247
+ const selectedPin = pinNumbers[0];
248
+ net.name = `Net${selectedRefdes}_${selectedPin}`;
249
+ };
250
+ /**
251
+ * Extract all nets from the schematic.
252
+ *
253
+ * This function:
254
+ * 1. Finds all connectable devices (wires, pins, labels, power ports)
255
+ * 2. Calculates coordinates for each device
256
+ * 3. Groups connected devices into nets
257
+ * 4. Assigns names to nets based on power ports, labels, or pin names
258
+ */
259
+ export const extractNets = (schematic) => {
260
+ // Find all connectable devices
261
+ const devices = findConnectableDevices(schematic);
262
+ // Calculate coordinates for each device
263
+ for (const device of devices) {
264
+ calculateDeviceCoordinates(device);
265
+ }
266
+ // Group connected devices into nets using optimized algorithm
267
+ const components = findAllConnectedComponents(devices);
268
+ // Convert to AltiumNet objects
269
+ const nets = [];
270
+ for (const connectedDevices of components) {
271
+ // Sort by index for consistency
272
+ connectedDevices.sort((a, b) => a.index - b.index);
273
+ const net = {
274
+ name: null,
275
+ devices: connectedDevices,
276
+ };
277
+ nets.push(net);
278
+ }
279
+ // Assign names to nets
280
+ for (const net of nets) {
281
+ assignNetName(net, schematic);
282
+ }
283
+ return nets;
284
+ };
285
+ /**
286
+ * Get net list with schematic (for compatibility with Python API).
287
+ */
288
+ export const determineNetList = (schematic) => {
289
+ const nets = extractNets(schematic);
290
+ return {
291
+ ...schematic,
292
+ nets,
293
+ };
294
+ };
295
+ //# sourceMappingURL=net-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"net-extractor.js","sourceRoot":"","sources":["../../../src/parsers/altium/net-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * OLE/CFB File Reader
3
+ *
4
+ * Custom implementation of Microsoft Compound File Binary (CFB) format parser.
5
+ * Based on MS-CFB specification:
6
+ * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cfb/
7
+ *
8
+ * Only implements the subset needed to read streams from Altium .SchDoc files.
9
+ */
10
+ /**
11
+ * OLE/CFB file reader class
12
+ *
13
+ * Reads Microsoft Compound File Binary format files.
14
+ */
15
+ export declare class OleReader {
16
+ private buffer;
17
+ private header;
18
+ private fat;
19
+ private miniFat;
20
+ private directories;
21
+ private miniStream;
22
+ /**
23
+ * Create a new OleReader instance for reading OLE compound files.
24
+ */
25
+ constructor(filePath: string);
26
+ /**
27
+ * Read a named stream from the OLE file.
28
+ */
29
+ readStream(name: string): Buffer;
30
+ /**
31
+ * List all stream names in the file.
32
+ */
33
+ listStreams(): string[];
34
+ /**
35
+ * Validate the OLE magic signature.
36
+ */
37
+ private validateMagic;
38
+ /**
39
+ * Parse the 512-byte header.
40
+ */
41
+ private parseHeader;
42
+ /**
43
+ * Build the complete FAT by reading all FAT sectors.
44
+ */
45
+ private buildFat;
46
+ /**
47
+ * Build the mini FAT.
48
+ */
49
+ private buildMiniFat;
50
+ /**
51
+ * Read the mini stream from the root entry.
52
+ */
53
+ private readMiniStream;
54
+ /**
55
+ * Read all directory entries.
56
+ */
57
+ private readDirectories;
58
+ /**
59
+ * Parse a single 128-byte directory entry.
60
+ */
61
+ private parseDirectoryEntry;
62
+ /**
63
+ * Find a directory entry by name.
64
+ */
65
+ private findDirectoryEntry;
66
+ /**
67
+ * Read stream data from a directory entry.
68
+ */
69
+ private readStreamData;
70
+ /**
71
+ * Read a regular stream (>= 4096 bytes).
72
+ */
73
+ private readRegularStream;
74
+ /**
75
+ * Read from mini stream (< 4096 bytes).
76
+ */
77
+ private readMiniStreamData;
78
+ /**
79
+ * Read a sector by its index.
80
+ */
81
+ private readSector;
82
+ /**
83
+ * Get the chain of sectors for a stream.
84
+ */
85
+ private getSectorChain;
86
+ }
87
+ /**
88
+ * Read a stream from an OLE file.
89
+ */
90
+ export declare const readOleStream: (filePath: string, streamName?: string) => Buffer;
91
+ //# sourceMappingURL=ole-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ole-reader.d.ts","sourceRoot":"","sources":["../../../src/parsers/altium/ole-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoBH;;;;GAIG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,GAAG,CAAW;IACtB,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,UAAU,CAAS;IAE3B;;OAEG;gBACS,QAAQ,EAAE,MAAM;IAU5B;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAQhC;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE;IAIvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,WAAW;IA4DnB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAoChB;;OAEG;IACH,OAAO,CAAC,YAAY;IAoBpB;;OAEG;IACH,OAAO,CAAC,cAAc;IAUtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAgB1B;;OAEG;IACH,OAAO,CAAC,UAAU;IAMlB;;OAEG;IACH,OAAO,CAAC,cAAc;CAqBvB;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,UAAU,MAAM,EAAE,mBAAyB,KAAG,MAG3E,CAAC"}