circuitscript 0.1.0 → 0.1.2

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 (61) hide show
  1. package/dist/cjs/BaseVisitor.js +13 -8
  2. package/dist/cjs/antlr/CircuitScriptLexer.js +80 -80
  3. package/dist/cjs/antlr/CircuitScriptParser.js +599 -657
  4. package/dist/cjs/builtinMethods.js +27 -8
  5. package/dist/cjs/draw_symbols.js +314 -190
  6. package/dist/cjs/execute.js +113 -115
  7. package/dist/cjs/export.js +2 -4
  8. package/dist/cjs/geometry.js +52 -19
  9. package/dist/cjs/globals.js +12 -8
  10. package/dist/cjs/helpers.js +16 -3
  11. package/dist/cjs/layout.js +129 -125
  12. package/dist/cjs/logger.js +8 -1
  13. package/dist/cjs/objects/ClassComponent.js +22 -22
  14. package/dist/cjs/objects/ExecutionScope.js +10 -4
  15. package/dist/cjs/objects/Frame.js +2 -1
  16. package/dist/cjs/objects/ParamDefinition.js +120 -4
  17. package/dist/cjs/objects/PinDefinition.js +1 -4
  18. package/dist/cjs/render.js +40 -110
  19. package/dist/cjs/sizing.js +33 -7
  20. package/dist/cjs/utils.js +68 -2
  21. package/dist/cjs/visitor.js +214 -254
  22. package/dist/esm/BaseVisitor.mjs +15 -10
  23. package/dist/esm/antlr/CircuitScriptLexer.mjs +80 -80
  24. package/dist/esm/antlr/CircuitScriptParser.mjs +599 -657
  25. package/dist/esm/builtinMethods.mjs +24 -8
  26. package/dist/esm/draw_symbols.mjs +316 -193
  27. package/dist/esm/execute.mjs +115 -117
  28. package/dist/esm/export.mjs +2 -4
  29. package/dist/esm/geometry.mjs +52 -19
  30. package/dist/esm/globals.mjs +12 -8
  31. package/dist/esm/helpers.mjs +17 -4
  32. package/dist/esm/layout.mjs +131 -127
  33. package/dist/esm/logger.mjs +8 -1
  34. package/dist/esm/objects/ClassComponent.mjs +21 -26
  35. package/dist/esm/objects/ExecutionScope.mjs +10 -4
  36. package/dist/esm/objects/Frame.mjs +2 -1
  37. package/dist/esm/objects/ParamDefinition.mjs +119 -3
  38. package/dist/esm/objects/PinDefinition.mjs +0 -2
  39. package/dist/esm/render.mjs +42 -112
  40. package/dist/esm/sizing.mjs +34 -8
  41. package/dist/esm/utils.mjs +64 -1
  42. package/dist/esm/visitor.mjs +216 -256
  43. package/dist/types/BaseVisitor.d.ts +1 -1
  44. package/dist/types/antlr/CircuitScriptParser.d.ts +2 -3
  45. package/dist/types/draw_symbols.d.ts +71 -45
  46. package/dist/types/execute.d.ts +15 -10
  47. package/dist/types/geometry.d.ts +31 -19
  48. package/dist/types/globals.d.ts +14 -10
  49. package/dist/types/helpers.d.ts +2 -1
  50. package/dist/types/layout.d.ts +21 -21
  51. package/dist/types/logger.d.ts +1 -1
  52. package/dist/types/objects/ClassComponent.d.ts +19 -16
  53. package/dist/types/objects/ExecutionScope.d.ts +2 -1
  54. package/dist/types/objects/Frame.d.ts +2 -2
  55. package/dist/types/objects/ParamDefinition.d.ts +31 -2
  56. package/dist/types/objects/PinDefinition.d.ts +0 -2
  57. package/dist/types/render.d.ts +2 -1
  58. package/dist/types/utils.d.ts +6 -1
  59. package/dist/types/visitor.d.ts +4 -5
  60. package/libs/lib.cst +15 -3
  61. package/package.json +7 -3
@@ -6,7 +6,7 @@ import { LayoutEngine } from "./layout.mjs";
6
6
  import { SequenceAction } from "./objects/ExecutionScope.mjs";
7
7
  import { parseFileWithVisitor } from "./parser.mjs";
8
8
  import { generatePdfOutput, generateSvgOutput, renderSheetsToSVG } from "./render.mjs";
9
- import { SimpleStopwatch } from "./utils.mjs";
9
+ import { resolveToNumericValue, SimpleStopwatch } from "./utils.mjs";
10
10
  import { ParserVisitor, VisitorExecutionException } from "./visitor.mjs";
11
11
  import { createContext } from "this-file";
12
12
  import { SymbolValidatorResolveVisitor, SymbolValidatorVisitor } from "./SymbolValidatorVisitor.mjs";
@@ -16,6 +16,8 @@ import { CircuitScriptParser } from "./antlr/CircuitScriptParser.mjs";
16
16
  import { prepareTokens, SemanticTokensVisitor } from "./SemanticTokenVisitor.mjs";
17
17
  import { defaultPageMarginMM, defaultZoomScale, LengthUnit, MilsToMM, PxToMM } from "./globals.mjs";
18
18
  import { FrameParamKeys } from "./objects/Frame.mjs";
19
+ import Big from "big.js";
20
+ import { Logger } from "./logger.mjs";
19
21
  export var JSModuleType;
20
22
  (function (JSModuleType) {
21
23
  JSModuleType["CommonJs"] = "cjs";
@@ -189,7 +191,13 @@ export function renderScript(scriptData, outputPath, options) {
189
191
  const action = tmp[0];
190
192
  if (action === SequenceAction.Wire) {
191
193
  tmp[2] = tmp[2].map(item2 => {
192
- return [item2.direction, item2.value].join(",");
194
+ const lengthValue = item2.value;
195
+ const useValue = [item2.direction];
196
+ if (lengthValue !== null) {
197
+ useValue.push(lengthValue.value);
198
+ useValue.push(lengthValue.type);
199
+ }
200
+ return useValue.join(",");
193
201
  }).join(" ");
194
202
  }
195
203
  else if (action === SequenceAction.Frame) {
@@ -227,8 +235,10 @@ export function renderScript(scriptData, outputPath, options) {
227
235
  showStats && console.log('Layout took:', layoutTimer.lap());
228
236
  dumpData && writeFileSync('dump/raw-layout.txt', layoutEngine.logger.dump());
229
237
  const generateSvgTimer = new SimpleStopwatch();
230
- const svgCanvas = renderSheetsToSVG(sheetFrames);
238
+ const renderLogger = new Logger();
239
+ const svgCanvas = renderSheetsToSVG(sheetFrames, renderLogger);
231
240
  showStats && console.log('Render took:', generateSvgTimer.lap());
241
+ dumpData && writeFileSync('dump/raw-render.txt', renderLogger.dump());
232
242
  svgOutput = generateSvgOutput(svgCanvas, outputDefaultZoom);
233
243
  if (outputPath) {
234
244
  if (fileExtension === 'svg') {
@@ -320,7 +330,10 @@ export class UnitDimension {
320
330
  }
321
331
  }
322
332
  export function milsToMM(value) {
323
- return value * MilsToMM;
333
+ if (typeof value === 'number') {
334
+ value = resolveToNumericValue(new Big(value));
335
+ }
336
+ return resolveToNumericValue(value.toBigNumber().mul(new Big(MilsToMM)));
324
337
  }
325
338
  export function pxToMM(value) {
326
339
  return value * PxToMM;
@@ -1,13 +1,14 @@
1
1
  import { Graph, alg } from '@dagrejs/graphlib';
2
- import { SymbolCustom, SymbolDrawing, SymbolFactory, SymbolCustomModule, SymbolPlaceholder, SymbolText, PlaceHolderCommands } from "./draw_symbols.mjs";
2
+ import { SymbolCustom, SymbolDrawing, SymbolCustomModule, SymbolPlaceholder, SymbolText, PlaceHolderCommands } from "./draw_symbols.mjs";
3
3
  import { FrameAction, SequenceAction } from "./objects/ExecutionScope.mjs";
4
- import { defaultFrameTitleTextSize, defaultGridSizeUnits, FrameType, GlobalNames, ParamKeys, WireAutoDirection } from './globals.mjs';
4
+ import { ComponentTypes, defaultFrameTitleTextSize, defaultGridSizeUnits, FrameType, ParamKeys, SymbolPinSide, WireAutoDirection } from './globals.mjs';
5
5
  import { Geometry } from './geometry.mjs';
6
6
  import { Logger } from './logger.mjs';
7
7
  import { Frame, FrameParamKeys, FramePlotDirection } from './objects/Frame.mjs';
8
8
  import { combineMaps, getBoundsSize, printBounds, resizeBounds, resizeToNearestGrid, roundValue, toNearestGrid } from './utils.mjs';
9
9
  import { Direction } from './objects/types.mjs';
10
10
  import { milsToMM, UnitDimension } from './helpers.mjs';
11
+ import { numeric, NumericValue } from './objects/ParamDefinition.mjs';
11
12
  export class LayoutEngine {
12
13
  logger;
13
14
  placeSubgraphVersion = 2;
@@ -113,8 +114,8 @@ export class LayoutEngine {
113
114
  const allLines = wires.map(wire => {
114
115
  return wire.points.map(pt => {
115
116
  return {
116
- x: wire.x + pt.x,
117
- y: wire.y + pt.y,
117
+ x: wire.x.add(pt.x),
118
+ y: wire.y.add(pt.y),
118
119
  };
119
120
  });
120
121
  });
@@ -125,7 +126,7 @@ export class LayoutEngine {
125
126
  intersectPoints,
126
127
  });
127
128
  intersectPoints.forEach(([x, y]) => {
128
- junctions.push(new RenderJunction(x, y));
129
+ junctions.push(new RenderJunction(numeric(x), numeric(y)));
129
130
  });
130
131
  }
131
132
  return {
@@ -135,15 +136,15 @@ export class LayoutEngine {
135
136
  }
136
137
  placeFrames(graph, subgraphInfo, frameObjects) {
137
138
  const baseFrame = frameObjects[0];
138
- baseFrame.padding = 0;
139
- baseFrame.borderWidth = 0;
139
+ baseFrame.padding = numeric(0);
140
+ baseFrame.borderWidth = numeric(0);
140
141
  if (this.showBaseFrame) {
141
- baseFrame.borderWidth = 5;
142
+ baseFrame.borderWidth = numeric(5);
142
143
  baseFrame.width = 11692 - 400 * 2;
143
144
  baseFrame.height = 8267 - 400 * 2;
144
145
  }
145
- baseFrame.x = 0;
146
- baseFrame.y = 0;
146
+ baseFrame.x = numeric(0);
147
+ baseFrame.y = numeric(0);
147
148
  let textObjects = [];
148
149
  let elementFrames = [];
149
150
  baseFrame.bounds = {
@@ -189,18 +190,18 @@ export class LayoutEngine {
189
190
  const innerItems = frame.innerItems;
190
191
  innerItems.forEach(innerFrame => {
191
192
  if (innerFrame.frame.frameType === FrameType.Sheet) {
192
- innerFrame.x = 0;
193
- innerFrame.y = 0;
193
+ innerFrame.x = numeric(0);
194
+ innerFrame.y = numeric(0);
194
195
  }
195
196
  else {
196
- innerFrame.x += frame.x;
197
- innerFrame.y += frame.y;
197
+ innerFrame.x = innerFrame.x.add(frame.x);
198
+ innerFrame.y = innerFrame.y.add(frame.y);
198
199
  }
199
200
  if (innerFrame.type === RenderFrameType.Elements) {
200
201
  this.print(level, "".padStart(level * 4), 'element frame', innerFrame.x, innerFrame.y);
201
202
  innerFrame.innerItems.forEach(item2 => {
202
- item2.x += innerFrame.x - innerFrame.translateX;
203
- item2.y += innerFrame.y - innerFrame.translateY;
203
+ item2.x = item2.x.add(innerFrame.x).sub(innerFrame.translateX);
204
+ item2.y = item2.y.add(innerFrame.y).sub(innerFrame.translateY);
204
205
  });
205
206
  }
206
207
  else {
@@ -212,8 +213,8 @@ export class LayoutEngine {
212
213
  placeAndSizeFrame(frame, level = 0) {
213
214
  const innerFrames = frame.innerItems;
214
215
  const gridSize = defaultGridSizeUnits;
215
- let accumX = 0;
216
- let accumY = 0;
216
+ let accumX = numeric(0);
217
+ let accumY = numeric(0);
217
218
  const boundPoints = [];
218
219
  const frameSizes = innerFrames.map(innerFrame => {
219
220
  if (innerFrame.type === RenderFrameType.Elements) {
@@ -241,7 +242,7 @@ export class LayoutEngine {
241
242
  return accum;
242
243
  }
243
244
  return accum + width +
244
- ((index + 1 < frameSizes.length) ? frame.gap : 0);
245
+ ((index + 1 < frameSizes.length) ? frame.gap.toNumber() : 0);
245
246
  }, 0);
246
247
  }
247
248
  else {
@@ -265,49 +266,55 @@ export class LayoutEngine {
265
266
  innerFrames.forEach(innerFrame => {
266
267
  const { width: frameWidth, height: frameHeight } = getBoundsSize(innerFrame.bounds);
267
268
  if (innerFrame.containsTitle) {
268
- innerFrame.x = offsetX + accumX + toNearestGrid(widthForTitle / 2 - frameWidth / 2, gridSize);
269
- innerFrame.y = offsetY + accumY;
270
- accumY += (frameHeight + frame.gap);
269
+ innerFrame.x = offsetX.add(accumX).add(toNearestGrid(widthForTitle / 2 - frameWidth / 2, gridSize));
270
+ innerFrame.y = offsetY.add(accumY);
271
+ accumY = accumY.add(frameHeight).add(frame.gap);
271
272
  }
272
273
  else {
273
274
  if (frame.direction === FramePlotDirection.Column) {
274
- innerFrame.x = offsetX + accumX + toNearestGrid(maxWidth / 2 - frameWidth / 2, gridSize);
275
- innerFrame.y = offsetY + accumY;
276
- accumY += (frameHeight + frame.gap);
275
+ innerFrame.x = offsetX.add(accumX).add(toNearestGrid(maxWidth / 2 - frameWidth / 2, gridSize));
276
+ innerFrame.y = offsetY.add(accumY);
277
+ accumY = accumY.add(frameHeight).add(frame.gap);
277
278
  }
278
279
  else if (frame.direction === FramePlotDirection.Row) {
279
- innerFrame.x = offsetX + centeredOffsetX + accumX;
280
- innerFrame.y = offsetY + accumY;
281
- accumX += (frameWidth + frame.gap);
280
+ innerFrame.x = offsetX.add(centeredOffsetX).add(accumX);
281
+ innerFrame.y = offsetY.add(accumY);
282
+ accumX = accumX.add(frameWidth).add(frame.gap);
282
283
  }
283
284
  }
284
- boundPoints.push([innerFrame.x, innerFrame.y], [innerFrame.x + frameWidth, innerFrame.y + frameHeight]);
285
+ boundPoints.push([innerFrame.x, innerFrame.y], [innerFrame.x.add(frameWidth), innerFrame.y.add(frameHeight)]);
285
286
  });
286
- const contentsBounds = resizeBounds(getBoundsFromPoints(boundPoints), frame.padding);
287
+ const tmpBoundPoints = boundPoints.map(item => {
288
+ return [
289
+ item[0].toNumber(),
290
+ item[1].toNumber(),
291
+ ];
292
+ });
293
+ const contentsBounds = resizeBounds(getBoundsFromPoints(tmpBoundPoints), frame.padding.toNumber());
287
294
  if (frame.frame.parameters.has(FrameParamKeys.SheetType)) {
288
295
  const frameComponent = frame.frame.parameters.get(FrameParamKeys.SheetType);
289
296
  const frameDrawing = frameComponent.displayProp;
290
297
  frameDrawing.variables = combineMaps(frameComponent.parameters, frame.frame.parameters);
291
298
  const rects = ExtractDrawingRects(frameDrawing);
292
- let frameWidth = 0;
293
- let frameHeight = 0;
299
+ let frameWidth = numeric(0);
300
+ let frameHeight = numeric(0);
294
301
  if (rects[1]) {
295
302
  frameWidth = milsToMM(rects[1].width);
296
303
  frameHeight = milsToMM(rects[1].height);
297
304
  }
298
305
  const contentsWidth = contentsBounds.xmax - contentsBounds.xmin;
299
306
  const contentsHeight = contentsBounds.ymax - contentsBounds.ymin;
300
- const frameOffsetX = toNearestGrid((frameWidth - contentsWidth) / 2, gridSize);
301
- const frameOffsetY = toNearestGrid((frameHeight - contentsHeight) / 2, gridSize);
307
+ const frameOffsetX = toNearestGrid((frameWidth.toNumber() - contentsWidth) / 2, gridSize);
308
+ const frameOffsetY = toNearestGrid((frameHeight.toNumber() - contentsHeight) / 2, gridSize);
302
309
  innerFrames.forEach(innerFrame => {
303
- innerFrame.x += frameOffsetX;
304
- innerFrame.y += frameOffsetY;
310
+ innerFrame.x = innerFrame.x.add(frameOffsetX);
311
+ innerFrame.y = innerFrame.y.add(frameOffsetY);
305
312
  });
306
313
  frame.bounds = {
307
314
  xmin: 0,
308
315
  ymin: 0,
309
- xmax: frameWidth,
310
- ymax: frameHeight
316
+ xmax: frameWidth.toNumber(),
317
+ ymax: frameHeight.toNumber(),
311
318
  };
312
319
  }
313
320
  else {
@@ -381,7 +388,7 @@ export class LayoutEngine {
381
388
  tmpFrame.containsTitle = true;
382
389
  tmpFrame.subgraphId = title.replace(/\s/g, "_");
383
390
  const textObject = new RenderText(title);
384
- textObject.fontSize = defaultFrameTitleTextSize;
391
+ textObject.fontSize = numeric(defaultFrameTitleTextSize);
385
392
  textObject.fontWeight = 'bold';
386
393
  textObject.symbol.refreshDrawing();
387
394
  tmpFrame.innerItems.push(textObject);
@@ -392,8 +399,8 @@ export class LayoutEngine {
392
399
  xmax: tmpBox.start[0] + tmpBox.width,
393
400
  ymax: tmpBox.start[1] + tmpBox.height
394
401
  };
395
- textObject.x = 0;
396
- textObject.y = 0;
402
+ textObject.x = numeric(0);
403
+ textObject.y = numeric(0);
397
404
  frame.innerItems.splice(0, 0, tmpFrame);
398
405
  this.printLevel(level, frame, 'added text', tmpFrame);
399
406
  textObjects.push(textObject);
@@ -426,46 +433,43 @@ export class LayoutEngine {
426
433
  const tmpInstanceName = component.instanceName;
427
434
  if (!graph.hasNode(tmpInstanceName)) {
428
435
  this.print('create instance', tmpInstanceName);
429
- let { displayProp = null, widthProp = null, typeProp = null } = component;
436
+ const { displayProp = null, widthProp = null, heightProp = null } = component;
430
437
  let tmpSymbol;
431
- if (displayProp === null &&
432
- component.parameters.get(ParamKeys.net_name) === GlobalNames.gnd) {
433
- displayProp = 'gnd';
434
- }
435
- if (displayProp !== null) {
436
- if (displayProp instanceof SymbolDrawing) {
437
- tmpSymbol = new SymbolPlaceholder(displayProp);
438
- tmpSymbol.drawing.logger = this.logger;
439
- }
440
- else if (typeof displayProp === "string") {
441
- tmpSymbol = SymbolFactory(displayProp);
442
- }
438
+ if (displayProp instanceof SymbolDrawing) {
439
+ tmpSymbol = new SymbolPlaceholder(displayProp);
440
+ tmpSymbol.drawing.logger = this.logger;
443
441
  }
444
442
  else {
445
443
  const symbolPinDefinitions = generateLayoutPinDefinition(component);
446
- if (component.typeProp === 'module') {
447
- tmpSymbol = new SymbolCustomModule(symbolPinDefinitions);
444
+ if (component.typeProp === ComponentTypes.module) {
445
+ tmpSymbol = new SymbolCustomModule(symbolPinDefinitions, component.pinsMaxPositions);
448
446
  }
449
447
  else {
450
- tmpSymbol = new SymbolCustom(symbolPinDefinitions);
448
+ tmpSymbol = new SymbolCustom(symbolPinDefinitions, component.pinsMaxPositions);
451
449
  }
452
450
  }
453
451
  applyComponentParamsToSymbol(component, tmpSymbol);
454
452
  let didSetAngle = false;
455
- if (component.parameters.has('angle')) {
453
+ if (component.parameters.has(ParamKeys.angle)) {
456
454
  didSetAngle = true;
457
- tmpSymbol.angle = component.parameters.get('angle');
455
+ const value = component.parameters.get(ParamKeys.angle).toNumber();
456
+ tmpSymbol.angle = value;
458
457
  }
459
- if (component.parameters.has('flipX')) {
458
+ if (component.parameters.has(ParamKeys.flipX)) {
460
459
  tmpSymbol.flipX =
461
- component.parameters.get('flipX');
460
+ component.parameters.get(ParamKeys.flipX);
462
461
  }
463
- if (component.parameters.has('flipY')) {
462
+ if (component.parameters.has(ParamKeys.flipY)) {
464
463
  tmpSymbol.flipY =
465
- component.parameters.get('flipY');
464
+ component.parameters.get(ParamKeys.flipY);
466
465
  }
467
- if (tmpSymbol instanceof SymbolCustom && widthProp) {
468
- tmpSymbol.bodyWidth = milsToMM(widthProp);
466
+ if (tmpSymbol instanceof SymbolCustom) {
467
+ if (widthProp) {
468
+ tmpSymbol.bodyWidth = milsToMM(widthProp);
469
+ }
470
+ if (heightProp) {
471
+ tmpSymbol.bodyHeight = milsToMM(heightProp);
472
+ }
469
473
  }
470
474
  if (!didSetAngle && component.parameters.has('_addDirection')) {
471
475
  tmpSymbol.refreshDrawing(false);
@@ -487,7 +491,7 @@ export class LayoutEngine {
487
491
  }
488
492
  else if (action === SequenceAction.Wire) {
489
493
  const [, wireId, wireSegments] = sequence[i];
490
- const wire = new RenderWire(0, 0, wireSegments);
494
+ const wire = new RenderWire(numeric(0), numeric(0), wireSegments);
491
495
  wire.id = wireId;
492
496
  let useNetName = null;
493
497
  if (previousNode !== null) {
@@ -651,7 +655,7 @@ export class LayoutEngine {
651
655
  }
652
656
  if (subgraphEdges.length === 0) {
653
657
  const [, node1] = graph.node(firstNodeId);
654
- this.placeNodeAtPosition(0, 0, node1, 1);
658
+ this.placeNodeAtPosition(numeric(0), numeric(0), node1, 1);
655
659
  return;
656
660
  }
657
661
  let fixedNode;
@@ -664,7 +668,7 @@ export class LayoutEngine {
664
668
  const [, node2] = graph.node(nodeId2);
665
669
  if (nodeId1 === firstNodeId && !firstNodePlaced) {
666
670
  this.print('first node placed at origin');
667
- this.placeNodeAtPosition(0, 0, node1, pin1);
671
+ this.placeNodeAtPosition(numeric(0), numeric(0), node1, pin1);
668
672
  firstNodePlaced = true;
669
673
  node1.isFloating = false;
670
674
  originNodes.push(node1);
@@ -687,7 +691,7 @@ export class LayoutEngine {
687
691
  originNodes.push(node1);
688
692
  originNodeGroups.set(node1.toString(), [node1]);
689
693
  this.print('creating new origin node at', node1);
690
- this.placeNodeAtPosition(0, 0, node1, pin1);
694
+ this.placeNodeAtPosition(numeric(0), numeric(0), node1, pin1);
691
695
  node1.isFloating = false;
692
696
  fixedNode = node1;
693
697
  fixedNodePin = pin1;
@@ -704,7 +708,7 @@ export class LayoutEngine {
704
708
  else {
705
709
  const [x1, y1] = getNodePositionAtPin(node1, pin1);
706
710
  const [x2, y2] = getNodePositionAtPin(node2, pin2);
707
- if (x1 !== x2 && y1 !== y2) {
711
+ if (!x1.eq(x2) && !y1.eq(y2)) {
708
712
  if (node1 instanceof RenderWire &&
709
713
  node2 instanceof RenderComponent) {
710
714
  const refdes = node2.component.assignedRefDes;
@@ -781,8 +785,8 @@ export class LayoutEngine {
781
785
  this.print('merging origin node groups, fixed:', keepOriginNode, ', other:', otherOriginNode);
782
786
  const [x, y] = getNodePositionAtPin(fixedNode, fixedNodePin);
783
787
  const [otherNodeOriginX, otherNodeOriginY] = getNodePositionAtPin(mergedNode, mergedNodePin);
784
- const offsetX = x - otherNodeOriginX;
785
- const offsetY = y - otherNodeOriginY;
788
+ const offsetX = x.sub(otherNodeOriginX);
789
+ const offsetY = y.sub(otherNodeOriginY);
786
790
  this.print('offset of other origin:', offsetX, offsetY);
787
791
  const otherItemsLinkedToOriginNode = originNodeGroups.get(otherOriginNode);
788
792
  this.print('nodes in other origin:', otherItemsLinkedToOriginNode);
@@ -804,7 +808,7 @@ export class LayoutEngine {
804
808
  const [, node2] = graph.node(nodeId2);
805
809
  if (nodeId1 === firstNodeId && !firstNodePlaced) {
806
810
  this.print('first node placed at origin');
807
- this.placeNodeAtPosition(0, 0, node1, pin1);
811
+ this.placeNodeAtPosition(numeric(0), numeric(0), node1, pin1);
808
812
  firstNodePlaced = true;
809
813
  node1.isFloating = false;
810
814
  }
@@ -850,14 +854,14 @@ export class LayoutEngine {
850
854
  });
851
855
  }
852
856
  translateNodeBy(offsetX, offsetY, item) {
853
- item.x += offsetX;
854
- item.y += offsetY;
857
+ item.x = item.x.add(offsetX);
858
+ item.y = item.y.add(offsetY);
855
859
  }
856
860
  placeNodeAtPosition(fromX, fromY, item, pin, depth = 0) {
857
861
  if (item instanceof RenderComponent) {
858
862
  const pinPosition = item.symbol.pinPosition(pin);
859
- item.x = fromX - pinPosition.x;
860
- item.y = fromY - pinPosition.y;
863
+ item.x = fromX.sub(pinPosition.x);
864
+ item.y = fromY.sub(pinPosition.y);
861
865
  }
862
866
  else if (item instanceof RenderWire) {
863
867
  if (pin === 0) {
@@ -866,8 +870,8 @@ export class LayoutEngine {
866
870
  }
867
871
  else {
868
872
  const wireEnd = item.getWireEnd();
869
- item.x = fromX - wireEnd.x;
870
- item.y = fromY - wireEnd.y;
873
+ item.x = fromX.sub(wireEnd.x);
874
+ item.y = fromY.sub(wireEnd.y);
871
875
  }
872
876
  }
873
877
  this.print(this.padLevel(depth), 'place', item, 'pin', pin, 'at', item.x, item.y);
@@ -906,12 +910,12 @@ export class LayoutEngine {
906
910
  }
907
911
  }
908
912
  function getNodePositionAtPin(item, pin) {
909
- let x = 0;
910
- let y = 0;
913
+ let x = numeric(0);
914
+ let y = numeric(0);
911
915
  if (item instanceof RenderComponent) {
912
916
  const pinPosition = item.symbol.pinPosition(pin);
913
- x = item.x + pinPosition.x;
914
- y = item.y + pinPosition.y;
917
+ x = item.x.add(pinPosition.x);
918
+ y = item.y.add(pinPosition.y);
915
919
  }
916
920
  else if (item instanceof RenderWire) {
917
921
  if (pin === 0) {
@@ -920,8 +924,8 @@ function getNodePositionAtPin(item, pin) {
920
924
  }
921
925
  else {
922
926
  const wireEnd = item.getWireEnd();
923
- x = item.x + wireEnd.x;
924
- y = item.y + wireEnd.y;
927
+ x = item.x.add(wireEnd.x);
928
+ y = item.y.add(wireEnd.y);
925
929
  }
926
930
  }
927
931
  return [
@@ -954,7 +958,7 @@ function generateLayoutPinDefinition(component) {
954
958
  const pinPosition = Math.floor(i / 2);
955
959
  const pin = pins.get(existingPinIds[i]);
956
960
  symbolPinDefinitions.push({
957
- side: (i % 2 === 0) ? "left" : "right",
961
+ side: (i % 2 === 0) ? SymbolPinSide.Left : SymbolPinSide.Right,
958
962
  pinId: existingPinIds[i],
959
963
  text: pin.name,
960
964
  position: pinPosition,
@@ -973,24 +977,24 @@ function generateLayoutPinDefinition(component) {
973
977
  useItems = [...items];
974
978
  }
975
979
  useItems.forEach(pinId => {
976
- if (existingPinIds.indexOf(pinId) !== -1) {
977
- const pin = pins.get(pinId);
978
- symbolPinDefinitions.push({
979
- side: key,
980
- pinId: pinId,
981
- text: pin.name,
982
- position: pin.position,
983
- pinType: pin.pinType,
984
- });
985
- addedPins.push(pinId);
980
+ if (pinId instanceof NumericValue) {
981
+ const pinIdValue = pinId.toNumber();
982
+ if (existingPinIds.indexOf(pinIdValue) !== -1) {
983
+ const pin = pins.get(pinIdValue);
984
+ symbolPinDefinitions.push({
985
+ side: key,
986
+ pinId: pinIdValue,
987
+ text: pin.name,
988
+ position: pin.position,
989
+ pinType: pin.pinType,
990
+ });
991
+ addedPins.push(pinIdValue);
992
+ }
986
993
  }
987
994
  });
988
995
  }
989
- const unplacedPins = [];
990
- existingPinIds.forEach(item => {
991
- if (addedPins.indexOf(item) === -1) {
992
- unplacedPins.push(item);
993
- }
996
+ const unplacedPins = existingPinIds.filter(pinId => {
997
+ return addedPins.indexOf(pinId) === -1;
994
998
  });
995
999
  if (unplacedPins.length > 0) {
996
1000
  throw "'arrange' property is defined, but not all pins are specified: " + unplacedPins.join(",");
@@ -1031,21 +1035,21 @@ export function getBounds(components, wires, junctions, frames) {
1031
1035
  const bbox = item.symbol.drawing.getBoundingBox();
1032
1036
  const [x1, y1] = bbox.start;
1033
1037
  const [x2, y2] = bbox.end;
1034
- points.push([x1 + item.x, y1 + item.y]);
1035
- points.push([x2 + item.x, y2 + item.y]);
1038
+ points.push([x1 + item.x.toNumber(), y1 + item.y.toNumber()]);
1039
+ points.push([x2 + item.x.toNumber(), y2 + item.y.toNumber()]);
1036
1040
  });
1037
1041
  wires.forEach(wire => {
1038
1042
  wire.points.forEach(point => {
1039
- points.push([wire.x + point.x, wire.y + point.y]);
1043
+ points.push([wire.x.add(point.x).toNumber(), wire.y.add(point.y).toNumber()]);
1040
1044
  });
1041
1045
  });
1042
1046
  junctions.forEach(item => {
1043
- points.push([item.x, item.y]);
1047
+ points.push([item.x.toNumber(), item.y.toNumber()]);
1044
1048
  });
1045
1049
  frames.forEach(item => {
1046
1050
  const { width, height } = getBoundsSize(item.bounds);
1047
- points.push([item.x, item.y]);
1048
- points.push([item.x + width, item.y + height]);
1051
+ points.push([item.x.toNumber(), item.y.toNumber()]);
1052
+ points.push([item.x.toNumber() + width, item.y.toNumber() + height]);
1049
1053
  });
1050
1054
  return getBoundsFromPoints(points);
1051
1055
  }
@@ -1061,8 +1065,8 @@ function getBoundsFromPoints(points) {
1061
1065
  };
1062
1066
  }
1063
1067
  export class RenderObject {
1064
- x = -1;
1065
- y = -1;
1068
+ x = numeric(-1);
1069
+ y = numeric(-1);
1066
1070
  isFloating = true;
1067
1071
  floatingRelativeTo = [];
1068
1072
  }
@@ -1105,7 +1109,7 @@ export class RenderWire extends RenderObject {
1105
1109
  tmpX += useValue;
1106
1110
  }
1107
1111
  else if (direction === WireAutoDirection.Auto || direction === WireAutoDirection.Auto_) {
1108
- const { valueXY = [0, 0] } = segment;
1112
+ const { valueXY = [numeric(0), numeric(0)] } = segment;
1109
1113
  const tmpPoints = this.getAutoPoints(valueXY, direction);
1110
1114
  tmpPoints.forEach(point => {
1111
1115
  if (point[0] !== 0 || point[1] !== 0) {
@@ -1123,8 +1127,8 @@ export class RenderWire extends RenderObject {
1123
1127
  this.points = points;
1124
1128
  }
1125
1129
  getAutoPoints(value, direction) {
1126
- const valueX = roundValue(value[0]);
1127
- const valueY = roundValue(value[1]);
1130
+ const valueX = roundValue(value[0]).toNumber();
1131
+ const valueY = roundValue(value[1]).toNumber();
1128
1132
  const inQuadrant = Geometry.getQuadrant(valueX, valueY);
1129
1133
  const [dx, dy] = [valueX, valueY];
1130
1134
  if (direction === WireAutoDirection.Auto) {
@@ -1180,16 +1184,16 @@ export class RenderWire extends RenderObject {
1180
1184
  useValue = value;
1181
1185
  }
1182
1186
  if (direction === Direction.Down) {
1183
- tmpY += useValue;
1187
+ tmpY = tmpY.add(useValue);
1184
1188
  }
1185
1189
  else if (direction === Direction.Up) {
1186
- tmpY -= useValue;
1190
+ tmpY = tmpY.sub(useValue);
1187
1191
  }
1188
1192
  else if (direction === Direction.Left) {
1189
- tmpX -= useValue;
1193
+ tmpX = tmpX.sub(useValue);
1190
1194
  }
1191
1195
  else if (direction === Direction.Right) {
1192
- tmpX += useValue;
1196
+ tmpX = tmpX.add(useValue);
1193
1197
  }
1194
1198
  });
1195
1199
  let useValue = null;
@@ -1197,22 +1201,22 @@ export class RenderWire extends RenderObject {
1197
1201
  const lastSegment = this.segments[this.segments.length - 1];
1198
1202
  switch (lastSegment.direction) {
1199
1203
  case Direction.Left:
1200
- useValue = tmpX - untilX;
1204
+ useValue = tmpX.sub(untilX);
1201
1205
  break;
1202
1206
  case Direction.Right:
1203
- useValue = untilX - tmpX;
1207
+ useValue = untilX.sub(tmpX);
1204
1208
  break;
1205
1209
  case Direction.Up:
1206
- useValue = untilY - tmpY;
1210
+ useValue = untilY.sub(tmpY);
1207
1211
  break;
1208
1212
  case Direction.Down:
1209
- useValue = tmpY - untilY;
1213
+ useValue = tmpY.sub(untilY);
1210
1214
  break;
1211
1215
  case WireAutoDirection.Auto:
1212
1216
  case WireAutoDirection.Auto_:
1213
1217
  valueXY = [
1214
- untilX - tmpX,
1215
- untilY - tmpY,
1218
+ untilX.sub(tmpX),
1219
+ untilY.sub(tmpY),
1216
1220
  ];
1217
1221
  useValue = 0;
1218
1222
  break;
@@ -1250,7 +1254,7 @@ export class RenderComponent extends RenderObject {
1250
1254
  }
1251
1255
  export class RenderText extends RenderObject {
1252
1256
  symbol;
1253
- _fontSize = 12;
1257
+ _fontSize = numeric(12);
1254
1258
  _fontWeight = 'regular';
1255
1259
  get fontSize() {
1256
1260
  return this._fontSize;
@@ -1279,11 +1283,10 @@ export class RenderFrame extends RenderObject {
1279
1283
  translateY = 0;
1280
1284
  padding = milsToMM(100);
1281
1285
  gap = milsToMM(100);
1286
+ borderWidth = numeric(5);
1282
1287
  direction = FramePlotDirection.Column;
1283
- borderWidth = 5;
1284
1288
  width = null;
1285
1289
  height = null;
1286
- size = null;
1287
1290
  subgraphId = "";
1288
1291
  type;
1289
1292
  containsTitle = false;
@@ -1300,7 +1303,8 @@ export class RenderFrame extends RenderObject {
1300
1303
  else if (this.type === RenderFrameType.Elements) {
1301
1304
  name = 'elements_' + this.subgraphId;
1302
1305
  }
1303
- return name + ": " + this.x + "," + this.y + " bounds:" + printBounds(this.bounds);
1306
+ return name + ": " + this.x + "," + this.y
1307
+ + " bounds:" + (this.bounds && printBounds(this.bounds));
1304
1308
  }
1305
1309
  }
1306
1310
  export var RenderFrameType;
@@ -1325,7 +1329,7 @@ export function CalculatePinPositions(component) {
1325
1329
  }
1326
1330
  else {
1327
1331
  const symbolPinDefinitions = generateLayoutPinDefinition(component);
1328
- tmpSymbol = new SymbolCustom(symbolPinDefinitions);
1332
+ tmpSymbol = new SymbolCustom(symbolPinDefinitions, component.pinsMaxPositions);
1329
1333
  }
1330
1334
  applyComponentParamsToSymbol(component, tmpSymbol);
1331
1335
  tmpSymbol.refreshDrawing();
@@ -4,7 +4,14 @@ export class Logger {
4
4
  this.add((new Date()).toISOString());
5
5
  this.add('starting logger...');
6
6
  }
7
- add(message) {
7
+ add(...args) {
8
+ let message = "";
9
+ if (args.length === 1) {
10
+ message = args[0].toString();
11
+ }
12
+ else {
13
+ message = args.join(" ");
14
+ }
8
15
  this.logs.push((new Date()).toISOString() + " | " + message);
9
16
  }
10
17
  dump() {