altium-toolkit 1.0.8 → 1.0.10
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 +18 -6
- package/docs/api.md +78 -16
- package/docs/model-format.md +229 -8
- package/docs/schemas/altium_toolkit/ci_artifact_bundle_a1.schema.json +76 -0
- package/docs/schemas/altium_toolkit/draftsman_digest_a1.schema.json +35 -0
- package/docs/schemas/altium_toolkit/netlist_a1.schema.json +53 -0
- package/docs/schemas/altium_toolkit/normalized_model_a1.schema.json +1826 -110
- package/docs/schemas/altium_toolkit/parser_compatibility_fuzz_a1.schema.json +25 -0
- package/docs/schemas/altium_toolkit/pcb_svg_semantics_a1.schema.json +86 -0
- package/docs/schemas/altium_toolkit/project_bundle_a1.schema.json +63 -0
- package/docs/schemas/altium_toolkit/project_document_graph_a1.schema.json +33 -0
- package/docs/schemas/altium_toolkit/schematic_svg_semantics_a1.schema.json +50 -0
- package/docs/schemas/altium_toolkit/svg_model_cross_link_a1.schema.json +39 -0
- package/docs/testing.md +9 -3
- package/package.json +1 -1
- package/spec/library-scope.md +7 -1
- package/src/core/altium/AltiumLayoutParser.mjs +104 -8
- package/src/core/altium/AltiumParser.mjs +196 -45
- package/src/core/altium/CiArtifactBundleBuilder.mjs +202 -0
- package/src/core/altium/DraftsmanDigestParser.mjs +689 -0
- package/src/core/altium/EmbeddedFileInventoryBuilder.mjs +255 -0
- package/src/core/altium/IntLibModelParser.mjs +240 -0
- package/src/core/altium/IntLibStreamExtractor.mjs +366 -0
- package/src/core/altium/LibraryRenderManifestBuilder.mjs +417 -0
- package/src/core/altium/LibrarySearchIndex.mjs +215 -0
- package/src/core/altium/NormalizedModelSchema.mjs +36 -0
- package/src/core/altium/ParserCompatibilityFuzzer.mjs +192 -0
- package/src/core/altium/PcbCustomPadShapeParser.mjs +244 -0
- package/src/core/altium/PcbDefaultsParser.mjs +171 -0
- package/src/core/altium/PcbDimensionParser.mjs +229 -0
- package/src/core/altium/PcbEmbeddedModelExtractor.mjs +232 -6
- package/src/core/altium/PcbExtendedPrimitiveInformationParser.mjs +256 -0
- package/src/core/altium/PcbLibModelParser.mjs +235 -14
- package/src/core/altium/PcbLibStreamExtractor.mjs +62 -4
- package/src/core/altium/PcbMaskPasteResolver.mjs +354 -0
- package/src/core/altium/PcbMechanicalLayerPairParser.mjs +204 -0
- package/src/core/altium/PcbModelParser.mjs +495 -32
- package/src/core/altium/PcbOwnershipGraphBuilder.mjs +245 -0
- package/src/core/altium/PcbPadPrimitiveParser.mjs +78 -65
- package/src/core/altium/PcbPadStackParser.mjs +229 -2
- package/src/core/altium/PcbPickPlacePositionResolver.mjs +224 -0
- package/src/core/altium/PcbPrimitiveParameterParser.mjs +3 -2
- package/src/core/altium/PcbRawRecordRegistry.mjs +121 -130
- package/src/core/altium/PcbRegionPrimitiveParser.mjs +76 -3
- package/src/core/altium/PcbRouteAnalysisBuilder.mjs +730 -0
- package/src/core/altium/PcbRuleParser.mjs +354 -33
- package/src/core/altium/PcbSidecarRecordParser.mjs +177 -0
- package/src/core/altium/PcbSpecialStringResolver.mjs +220 -0
- package/src/core/altium/PcbStatisticsBuilder.mjs +541 -0
- package/src/core/altium/PcbStreamExtractor.mjs +111 -4
- package/src/core/altium/PcbTextPrimitiveParser.mjs +60 -0
- package/src/core/altium/PcbUnionParser.mjs +307 -0
- package/src/core/altium/PcbViaStackParser.mjs +98 -10
- package/src/core/altium/PcbViaStructureParser.mjs +335 -0
- package/src/core/altium/PrintableTextDecoder.mjs +53 -3
- package/src/core/altium/PrjPcbModelParser.mjs +281 -7
- package/src/core/altium/ProjectAnnotationParser.mjs +205 -0
- package/src/core/altium/ProjectDesignBundleBuilder.mjs +492 -0
- package/src/core/altium/ProjectDocumentGraphBuilder.mjs +280 -0
- package/src/core/altium/ProjectNetlistExporter.mjs +503 -0
- package/src/core/altium/ProjectOutJobDigestBuilder.mjs +109 -0
- package/src/core/altium/ProjectVariantViewBuilder.mjs +334 -0
- package/src/core/altium/SchematicBindingProvenanceParser.mjs +223 -0
- package/src/core/altium/SchematicComponentOwnerTextResolver.mjs +312 -0
- package/src/core/altium/SchematicComponentTextResolver.mjs +72 -19
- package/src/core/altium/SchematicConnectivityQaBuilder.mjs +271 -0
- package/src/core/altium/SchematicCrossSheetConnectorParser.mjs +140 -0
- package/src/core/altium/SchematicDirectiveParser.mjs +312 -0
- package/src/core/altium/SchematicDisplayModeCatalogParser.mjs +231 -0
- package/src/core/altium/SchematicHarnessParser.mjs +302 -0
- package/src/core/altium/SchematicImageParser.mjs +474 -3
- package/src/core/altium/SchematicImplementationParser.mjs +518 -0
- package/src/core/altium/SchematicNetlistBuilder.mjs +15 -2
- package/src/core/altium/SchematicOwnershipGraphParser.mjs +195 -0
- package/src/core/altium/SchematicPinParser.mjs +84 -1
- package/src/core/altium/SchematicPrimitiveParser.mjs +301 -0
- package/src/core/altium/SchematicProjectParameterResolver.mjs +361 -0
- package/src/core/altium/SchematicQaReportBuilder.mjs +284 -0
- package/src/core/altium/SchematicRecordTypeRegistry.mjs +137 -0
- package/src/core/altium/SchematicRepeatedChannelParser.mjs +229 -0
- package/src/core/altium/SchematicStreamExtractor.mjs +10 -1
- package/src/core/altium/SchematicTemplateParser.mjs +256 -0
- package/src/core/altium/SchematicTextParser.mjs +123 -0
- package/src/core/altium/SvgModelCrossLinkValidator.mjs +402 -0
- package/src/core/circuit-json/CircuitJsonModelAdapter.mjs +136 -96
- package/src/core/circuit-json/CircuitJsonModelAdapterPcbElements.mjs +244 -0
- package/src/core/circuit-json/CircuitJsonModelSchema.mjs +1 -1
- package/src/core/ole/OleCompoundDocument.mjs +20 -0
- package/src/parser.mjs +35 -0
- package/src/styles/altium-renderers.css +19 -0
- package/src/ui/PcbBarcodeTextRenderer.mjs +436 -0
- package/src/ui/PcbInteractionIndex.mjs +9 -4
- package/src/ui/PcbScene3dBuilder.mjs +137 -3
- package/src/ui/PcbScene3dModelRegistry.mjs +74 -0
- package/src/ui/PcbSvgRenderer.mjs +1252 -34
- package/src/ui/PcbTextPrimitiveRenderer.mjs +193 -7
- package/src/ui/SchematicNoteRenderer.mjs +9 -2
- package/src/ui/SchematicOwnerPinLabelLayout.mjs +206 -0
- package/src/ui/SchematicShapeRenderer.mjs +362 -0
- package/src/ui/SchematicSvgRenderer.mjs +1442 -92
- package/src/ui/SchematicTypography.mjs +48 -5
- package/src/ui/TextGeometrySidecarBuilder.mjs +147 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "altium-toolkit.parser-compatibility-fuzz.a1",
|
|
4
|
+
"title": "Altium Toolkit Parser Compatibility Fuzz A1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"required": ["schema", "summary", "cases"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schema": {
|
|
10
|
+
"const": "altium-toolkit.parser-compatibility-fuzz.a1"
|
|
11
|
+
},
|
|
12
|
+
"summary": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"additionalProperties": true
|
|
15
|
+
},
|
|
16
|
+
"cases": {
|
|
17
|
+
"type": "array",
|
|
18
|
+
"items": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"additionalProperties": true,
|
|
21
|
+
"required": ["key", "status"]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "altium-toolkit.pcb.svg.semantics.a1",
|
|
4
|
+
"title": "Altium Toolkit PCB SVG Semantics A1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"required": ["schema", "view", "layers", "elements"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schema": {
|
|
10
|
+
"const": "altium-toolkit.pcb.svg.semantics.a1"
|
|
11
|
+
},
|
|
12
|
+
"view": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"additionalProperties": true,
|
|
15
|
+
"properties": {
|
|
16
|
+
"kind": {
|
|
17
|
+
"type": "string"
|
|
18
|
+
},
|
|
19
|
+
"layerSet": {
|
|
20
|
+
"type": "object"
|
|
21
|
+
},
|
|
22
|
+
"board": {
|
|
23
|
+
"type": "object"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"boardOutline": {
|
|
28
|
+
"type": "object"
|
|
29
|
+
},
|
|
30
|
+
"lookups": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"additionalProperties": true,
|
|
33
|
+
"properties": {
|
|
34
|
+
"netsByIndex": {
|
|
35
|
+
"type": "object"
|
|
36
|
+
},
|
|
37
|
+
"netIndexByName": {
|
|
38
|
+
"type": "object"
|
|
39
|
+
},
|
|
40
|
+
"netClassesByName": {
|
|
41
|
+
"type": "object"
|
|
42
|
+
},
|
|
43
|
+
"componentsByIndex": {
|
|
44
|
+
"type": "object"
|
|
45
|
+
},
|
|
46
|
+
"componentIndexByDesignator": {
|
|
47
|
+
"type": "object"
|
|
48
|
+
},
|
|
49
|
+
"layersByKey": {
|
|
50
|
+
"type": "object"
|
|
51
|
+
},
|
|
52
|
+
"layerKeyByDisplayName": {
|
|
53
|
+
"type": "object"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"layers": {
|
|
58
|
+
"type": "array"
|
|
59
|
+
},
|
|
60
|
+
"elements": {
|
|
61
|
+
"type": "array",
|
|
62
|
+
"items": {
|
|
63
|
+
"type": "object",
|
|
64
|
+
"additionalProperties": true,
|
|
65
|
+
"required": ["elementKey", "primitive"],
|
|
66
|
+
"properties": {
|
|
67
|
+
"elementKey": {
|
|
68
|
+
"type": "string"
|
|
69
|
+
},
|
|
70
|
+
"primitive": {
|
|
71
|
+
"type": "string"
|
|
72
|
+
},
|
|
73
|
+
"layerKey": {
|
|
74
|
+
"type": "string"
|
|
75
|
+
},
|
|
76
|
+
"net": {
|
|
77
|
+
"type": "string"
|
|
78
|
+
},
|
|
79
|
+
"component": {
|
|
80
|
+
"type": "string"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "urn:altium-toolkit:project-bundle:a1",
|
|
4
|
+
"title": "Altium Toolkit Project Bundle A1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema",
|
|
9
|
+
"kind",
|
|
10
|
+
"project",
|
|
11
|
+
"sheets",
|
|
12
|
+
"components",
|
|
13
|
+
"nets",
|
|
14
|
+
"indexes"
|
|
15
|
+
],
|
|
16
|
+
"properties": {
|
|
17
|
+
"schema": {
|
|
18
|
+
"const": "urn:altium-toolkit:normalized-model:a1"
|
|
19
|
+
},
|
|
20
|
+
"kind": {
|
|
21
|
+
"const": "design-bundle"
|
|
22
|
+
},
|
|
23
|
+
"project": {
|
|
24
|
+
"type": "object"
|
|
25
|
+
},
|
|
26
|
+
"units": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"additionalProperties": {
|
|
29
|
+
"type": "string"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"variants": {
|
|
33
|
+
"type": "array"
|
|
34
|
+
},
|
|
35
|
+
"sheets": {
|
|
36
|
+
"type": "array"
|
|
37
|
+
},
|
|
38
|
+
"components": {
|
|
39
|
+
"type": "array"
|
|
40
|
+
},
|
|
41
|
+
"schematic_hierarchy": {
|
|
42
|
+
"type": "object"
|
|
43
|
+
},
|
|
44
|
+
"pnp": {
|
|
45
|
+
"type": "object"
|
|
46
|
+
},
|
|
47
|
+
"nets": {
|
|
48
|
+
"type": "array"
|
|
49
|
+
},
|
|
50
|
+
"annotations": {
|
|
51
|
+
"type": "object"
|
|
52
|
+
},
|
|
53
|
+
"indexes": {
|
|
54
|
+
"type": "object"
|
|
55
|
+
},
|
|
56
|
+
"bom": {
|
|
57
|
+
"type": "array"
|
|
58
|
+
},
|
|
59
|
+
"effectiveVariant": {
|
|
60
|
+
"type": "object"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "altium-toolkit.project.document-graph.a1",
|
|
4
|
+
"title": "Altium Toolkit Project Document Graph A1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"required": ["schema", "summary", "documents", "groups", "indexes"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schema": {
|
|
10
|
+
"const": "altium-toolkit.project.document-graph.a1"
|
|
11
|
+
},
|
|
12
|
+
"summary": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"additionalProperties": true
|
|
15
|
+
},
|
|
16
|
+
"documents": {
|
|
17
|
+
"type": "array",
|
|
18
|
+
"items": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"additionalProperties": true,
|
|
21
|
+
"required": ["normalizedPath", "kind"]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"groups": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"additionalProperties": true
|
|
27
|
+
},
|
|
28
|
+
"indexes": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"additionalProperties": true
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "altium-toolkit.schematic.svg.semantics.a1",
|
|
4
|
+
"title": "Altium Toolkit Schematic SVG Semantics A1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"required": ["schema", "elements"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schema": {
|
|
10
|
+
"const": "altium-toolkit.schematic.svg.semantics.a1"
|
|
11
|
+
},
|
|
12
|
+
"nets": {
|
|
13
|
+
"type": "array"
|
|
14
|
+
},
|
|
15
|
+
"components": {
|
|
16
|
+
"type": "array"
|
|
17
|
+
},
|
|
18
|
+
"elements": {
|
|
19
|
+
"type": "array",
|
|
20
|
+
"items": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"additionalProperties": true,
|
|
23
|
+
"required": ["elementKey"],
|
|
24
|
+
"properties": {
|
|
25
|
+
"elementKey": {
|
|
26
|
+
"type": "string"
|
|
27
|
+
},
|
|
28
|
+
"primitive": {
|
|
29
|
+
"type": "string"
|
|
30
|
+
},
|
|
31
|
+
"recordId": {
|
|
32
|
+
"type": "string"
|
|
33
|
+
},
|
|
34
|
+
"component": {
|
|
35
|
+
"type": "string"
|
|
36
|
+
},
|
|
37
|
+
"componentUniqueId": {
|
|
38
|
+
"type": "string"
|
|
39
|
+
},
|
|
40
|
+
"net": {
|
|
41
|
+
"type": "string"
|
|
42
|
+
},
|
|
43
|
+
"pin": {
|
|
44
|
+
"type": "string"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "altium-toolkit.svg-model-cross-link.a1",
|
|
4
|
+
"title": "Altium Toolkit SVG Model Cross-Link A1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"required": [
|
|
8
|
+
"schema",
|
|
9
|
+
"documentKind",
|
|
10
|
+
"summary",
|
|
11
|
+
"missingElements",
|
|
12
|
+
"orphanElements",
|
|
13
|
+
"unresolvedReferences"
|
|
14
|
+
],
|
|
15
|
+
"properties": {
|
|
16
|
+
"schema": {
|
|
17
|
+
"const": "altium-toolkit.svg-model-cross-link.a1"
|
|
18
|
+
},
|
|
19
|
+
"documentKind": {
|
|
20
|
+
"enum": ["schematic", "pcb", "unknown"]
|
|
21
|
+
},
|
|
22
|
+
"summary": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"additionalProperties": true
|
|
25
|
+
},
|
|
26
|
+
"missingElements": {
|
|
27
|
+
"type": "array"
|
|
28
|
+
},
|
|
29
|
+
"orphanElements": {
|
|
30
|
+
"type": "array"
|
|
31
|
+
},
|
|
32
|
+
"unresolvedReferences": {
|
|
33
|
+
"type": "array"
|
|
34
|
+
},
|
|
35
|
+
"metadata": {
|
|
36
|
+
"type": "object"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
package/docs/testing.md
CHANGED
|
@@ -16,10 +16,11 @@ The tests cover:
|
|
|
16
16
|
|
|
17
17
|
- Binary and OLE helpers
|
|
18
18
|
- Printable and binary Altium parser recovery for `.SchDoc`, `.PcbDoc`,
|
|
19
|
-
`.PcbLib`, and `.
|
|
19
|
+
`.PcbLib`, `.PrjPcb`, and `.IntLib` entrypoints
|
|
20
20
|
- PCB primitive stream slicing and focused decoders for tracks, fills, arcs,
|
|
21
21
|
vias, pads, text, regions, rules, raw records, board regions, ownership
|
|
22
|
-
indexes, sidecar PrimitiveParameters/Text tables,
|
|
22
|
+
indexes, sidecar PrimitiveParameters/Text tables, extended primitive
|
|
23
|
+
information, custom pad shapes, union metadata, and embedded font metadata
|
|
23
24
|
- Obfuscated fake schematic and PCB fixture shards
|
|
24
25
|
- Schematic SVG, side-resolved PCB SVG, BOM HTML, and static 3D summary
|
|
25
26
|
renderers
|
|
@@ -27,4 +28,9 @@ The tests cover:
|
|
|
27
28
|
|
|
28
29
|
Fixture data must remain repo-owned and obfuscated. Do not add native provided
|
|
29
30
|
Altium files, real customer identifiers, real vendor identifiers, or
|
|
30
|
-
source-descriptive fixture names.
|
|
31
|
+
source-descriptive fixture names. The machine-readable
|
|
32
|
+
`tests/fixtures/fixture-manifest.json` catalog tracks synthetic fixture coverage
|
|
33
|
+
areas and must keep `assetPolicy` set to `repo-owned-synthetic-only`. Each
|
|
34
|
+
fixture entry records `source: inline-synthetic-records` plus expected parser,
|
|
35
|
+
SVG, schema, and diagnostic contracts so tests can catch drift between fake
|
|
36
|
+
fixtures and public read-model coverage.
|
package/package.json
CHANGED
package/spec/library-scope.md
CHANGED
|
@@ -11,7 +11,8 @@ rendering primitives.
|
|
|
11
11
|
|
|
12
12
|
## In Scope
|
|
13
13
|
|
|
14
|
-
- `.SchDoc`, `.PcbDoc`, `.PcbLib`, and `.
|
|
14
|
+
- `.SchDoc`, `.PcbDoc`, `.PcbLib`, `.PrjPcb`, and `.IntLib` parsing from
|
|
15
|
+
`ArrayBuffer`
|
|
15
16
|
- OLE and binary stream helpers needed by parser recovery
|
|
16
17
|
- Schematic SVG rendering
|
|
17
18
|
- PCB SVG rendering
|
|
@@ -22,6 +23,9 @@ rendering primitives.
|
|
|
22
23
|
SVG rendering
|
|
23
24
|
- Read-only PCB primitive record registry metadata and base64 raw-record
|
|
24
25
|
preservation for unsupported or partially decoded PcbDoc/PcbLib streams
|
|
26
|
+
- Read-only PCB pad/via detail recovery, including hole tolerances,
|
|
27
|
+
mask/paste semantics, stack metadata, via-protection sidecars, custom pad
|
|
28
|
+
shape links, and PCB union metadata
|
|
25
29
|
- Static 3D summary HTML
|
|
26
30
|
- Parser worker entrypoint for host applications
|
|
27
31
|
- Optional renderer CSS
|
|
@@ -37,3 +41,5 @@ rendering primitives.
|
|
|
37
41
|
- STEP mesh loading and browser script injection
|
|
38
42
|
- Model ZIP export UI and download orchestration
|
|
39
43
|
- Server, deployment, and app metadata endpoints
|
|
44
|
+
- Native document authoring, round-trip writing, GUI automation, and compiled
|
|
45
|
+
multi-sheet project netlist generation
|
|
@@ -114,19 +114,115 @@ export class AltiumLayoutParser {
|
|
|
114
114
|
if (!match) continue
|
|
115
115
|
|
|
116
116
|
const index = Number.parseInt(match[1], 10)
|
|
117
|
-
layers.push(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
117
|
+
layers.push(
|
|
118
|
+
AltiumLayoutParser.#stripUndefined({
|
|
119
|
+
index,
|
|
120
|
+
name: getField(fields, key),
|
|
121
|
+
layerId: parseNumericField(
|
|
122
|
+
fields,
|
|
123
|
+
'V9_STACK_LAYER' + index + '_LAYERID'
|
|
124
|
+
),
|
|
125
|
+
kind: AltiumLayoutParser.#firstLayerStackTextField(
|
|
126
|
+
fields,
|
|
127
|
+
index,
|
|
128
|
+
['KIND', 'TYPE', 'ROLE']
|
|
129
|
+
),
|
|
130
|
+
material: AltiumLayoutParser.#firstLayerStackTextField(
|
|
131
|
+
fields,
|
|
132
|
+
index,
|
|
133
|
+
['MATERIAL', 'MATERIALNAME']
|
|
134
|
+
),
|
|
135
|
+
thicknessMil:
|
|
136
|
+
AltiumLayoutParser.#firstLayerStackNumericField(
|
|
137
|
+
fields,
|
|
138
|
+
index,
|
|
139
|
+
['THICKNESS', 'DIELECTRICTHICKNESS']
|
|
140
|
+
),
|
|
141
|
+
copperThicknessMil:
|
|
142
|
+
AltiumLayoutParser.#firstLayerStackNumericField(
|
|
143
|
+
fields,
|
|
144
|
+
index,
|
|
145
|
+
['COPPERTHICKNESS', 'COPPER_THICKNESS']
|
|
146
|
+
),
|
|
147
|
+
copperWeight: AltiumLayoutParser.#firstLayerStackTextField(
|
|
148
|
+
fields,
|
|
149
|
+
index,
|
|
150
|
+
['COPPERWEIGHT', 'COPPER_WEIGHT']
|
|
151
|
+
),
|
|
152
|
+
dielectricConstant:
|
|
153
|
+
AltiumLayoutParser.#firstLayerStackNumericField(
|
|
154
|
+
fields,
|
|
155
|
+
index,
|
|
156
|
+
['DK', 'DIELECTRICCONSTANT', 'DIELECTRIC_CONSTANT']
|
|
157
|
+
),
|
|
158
|
+
dissipationFactor:
|
|
159
|
+
AltiumLayoutParser.#firstLayerStackNumericField(
|
|
160
|
+
fields,
|
|
161
|
+
index,
|
|
162
|
+
['DF', 'DISSIPATIONFACTOR', 'DISSIPATION_FACTOR']
|
|
163
|
+
)
|
|
164
|
+
})
|
|
165
|
+
)
|
|
125
166
|
}
|
|
126
167
|
|
|
127
168
|
return layers.sort((left, right) => left.index - right.index)
|
|
128
169
|
}
|
|
129
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Reads the first non-empty text field from a layer-stack entry.
|
|
173
|
+
* @param {Record<string, string | string[]>} fields Source fields.
|
|
174
|
+
* @param {number} index Layer-stack index.
|
|
175
|
+
* @param {string[]} suffixes Candidate suffixes.
|
|
176
|
+
* @returns {string | undefined}
|
|
177
|
+
*/
|
|
178
|
+
static #firstLayerStackTextField(fields, index, suffixes) {
|
|
179
|
+
for (const suffix of suffixes) {
|
|
180
|
+
const value = getField(
|
|
181
|
+
fields,
|
|
182
|
+
'V9_STACK_LAYER' + index + '_' + suffix
|
|
183
|
+
)
|
|
184
|
+
if (value) {
|
|
185
|
+
return value
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return undefined
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Reads the first finite numeric field from a layer-stack entry.
|
|
194
|
+
* @param {Record<string, string | string[]>} fields Source fields.
|
|
195
|
+
* @param {number} index Layer-stack index.
|
|
196
|
+
* @param {string[]} suffixes Candidate suffixes.
|
|
197
|
+
* @returns {number | undefined}
|
|
198
|
+
*/
|
|
199
|
+
static #firstLayerStackNumericField(fields, index, suffixes) {
|
|
200
|
+
for (const suffix of suffixes) {
|
|
201
|
+
const value = parseNumericField(
|
|
202
|
+
fields,
|
|
203
|
+
'V9_STACK_LAYER' + index + '_' + suffix
|
|
204
|
+
)
|
|
205
|
+
if (value !== null) {
|
|
206
|
+
return value
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return undefined
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Removes undefined object values for stable parser output.
|
|
215
|
+
* @param {object} value Source object.
|
|
216
|
+
* @returns {object}
|
|
217
|
+
*/
|
|
218
|
+
static #stripUndefined(value) {
|
|
219
|
+
return Object.fromEntries(
|
|
220
|
+
Object.entries(value).filter(
|
|
221
|
+
([, entryValue]) => entryValue !== undefined
|
|
222
|
+
)
|
|
223
|
+
)
|
|
224
|
+
}
|
|
225
|
+
|
|
130
226
|
/**
|
|
131
227
|
* Extracts legacy primitive-layer names keyed by the numeric layer IDs used
|
|
132
228
|
* by decoded binary track and fill streams.
|