altium-toolkit 1.1.22 → 1.1.23
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 +34 -5
- package/docs/api.md +134 -23
- package/docs/model-format.md +174 -20
- package/docs/schemas/altium_toolkit/embedded_assets_a1.schema.json +56 -0
- package/docs/schemas/altium_toolkit/fixture_coverage_matrix_a1.schema.json +89 -0
- package/docs/schemas/altium_toolkit/geometry_bounds_a1.schema.json +86 -0
- package/docs/schemas/altium_toolkit/library_catalog_a1.schema.json +65 -0
- package/docs/schemas/altium_toolkit/library_diff_a1.schema.json +54 -0
- package/docs/schemas/altium_toolkit/library_inspection_a1.schema.json +94 -0
- package/docs/schemas/altium_toolkit/library_qa_a1.schema.json +4 -0
- package/docs/schemas/altium_toolkit/native_stream_inventory_a1.schema.json +66 -0
- package/docs/schemas/altium_toolkit/normalized_model_a1.schema.json +511 -1
- package/docs/schemas/altium_toolkit/parameter_record_inventory_a1.schema.json +84 -0
- package/docs/schemas/altium_toolkit/parser_diagnostics_a1.schema.json +63 -0
- package/docs/schemas/altium_toolkit/parser_value_verification_a1.schema.json +74 -0
- package/docs/schemas/altium_toolkit/pcb_class_report_a1.schema.json +79 -0
- package/docs/schemas/altium_toolkit/pcb_inspection_a1.schema.json +65 -0
- package/docs/schemas/altium_toolkit/pcb_net_membership_a1.schema.json +98 -0
- package/docs/schemas/altium_toolkit/project_bundle_a1.schema.json +3 -0
- package/docs/schemas/altium_toolkit/project_hierarchy_a1.schema.json +79 -0
- package/docs/schemas/altium_toolkit/unsupported_features_a1.schema.json +212 -0
- package/docs/testing.md +2 -0
- package/examples/README.md +21 -0
- package/examples/cli-utils.mjs +148 -0
- package/examples/corpus-smoke.mjs +523 -0
- package/examples/extract-bom.mjs +47 -0
- package/examples/generate-pnp.mjs +59 -0
- package/examples/inspect-board.mjs +70 -0
- package/examples/inspect-schematic.mjs +406 -0
- package/examples/library-catalog.mjs +115 -0
- package/examples/net-report.mjs +61 -0
- package/examples/validate-library.mjs +59 -0
- package/package.json +1 -1
- package/src/core/BinaryReader.mjs +213 -2
- package/src/core/altium/AltiumParser.mjs +352 -14
- package/src/core/altium/AltiumUnits.mjs +205 -0
- package/src/core/altium/AsciiRecordParser.mjs +9 -0
- package/src/core/altium/EmbeddedAssetReportBuilder.mjs +383 -0
- package/src/core/altium/FixtureCoverageMatrixBuilder.mjs +304 -0
- package/src/core/altium/GeometryBoundsReportBuilder.mjs +935 -0
- package/src/core/altium/LibraryCatalogArtifactBuilder.mjs +296 -0
- package/src/core/altium/LibraryDiffReportBuilder.mjs +260 -0
- package/src/core/altium/LibraryInspectionReportBuilder.mjs +156 -0
- package/src/core/altium/LibraryQaReportBuilder.mjs +374 -1
- package/src/core/altium/NativeStreamInventoryBuilder.mjs +177 -0
- package/src/core/altium/NormalizedModelSchema.mjs +3 -31
- package/src/core/altium/ParameterCollection.mjs +431 -0
- package/src/core/altium/ParameterRecordInventoryBuilder.mjs +274 -0
- package/src/core/altium/ParserCompatibilityFuzzer.mjs +106 -2
- package/src/core/altium/ParserDiagnosticNormalizer.mjs +213 -0
- package/src/core/altium/ParserErrors.mjs +90 -0
- package/src/core/altium/ParserFieldCoverageReportBuilder.mjs +656 -0
- package/src/core/altium/ParserUtils.mjs +24 -0
- package/src/core/altium/ParserValueVerificationReportBuilder.mjs +323 -0
- package/src/core/altium/PcbClassReportBuilder.mjs +366 -0
- package/src/core/altium/PcbInspectionReportBuilder.mjs +313 -0
- package/src/core/altium/PcbLayerGroups.mjs +308 -0
- package/src/core/altium/PcbLayerStackCustomDataParser.mjs +183 -0
- package/src/core/altium/PcbLayerStackInterchangeParser.mjs +473 -4
- package/src/core/altium/PcbLayerStackReadModelBuilder.mjs +83 -15
- package/src/core/altium/PcbLayerStackSourceMetadataParser.mjs +74 -4
- package/src/core/altium/PcbLibModelParser.mjs +20 -4
- package/src/core/altium/PcbLibStreamExtractor.mjs +49 -6
- package/src/core/altium/PcbModelParser.mjs +223 -4
- package/src/core/altium/PcbNetMembershipReportBuilder.mjs +270 -0
- package/src/core/altium/PcbStreamExtractor.mjs +130 -6
- package/src/core/altium/PcbTrackPrimitiveParser.mjs +66 -2
- package/src/core/altium/ProjectDesignBundleBuilder.mjs +15 -0
- package/src/core/altium/ProjectHierarchyReportBuilder.mjs +660 -0
- package/src/core/altium/ProjectNetlistExporter.mjs +2 -0
- package/src/core/altium/RawDataPreservationReportBuilder.mjs +348 -0
- package/src/core/altium/SchLibModelParser.mjs +840 -0
- package/src/core/altium/SchLibStreamExtractor.mjs +586 -0
- package/src/core/altium/SchematicBusEntryParser.mjs +3 -2
- package/src/core/altium/SchematicCodeSymbolParser.mjs +663 -0
- package/src/core/altium/SchematicConnectivityQaBuilder.mjs +177 -2
- package/src/core/altium/SchematicDisplayModeCatalogParser.mjs +10 -1
- package/src/core/altium/SchematicFieldCoverageReportBuilder.mjs +549 -0
- package/src/core/altium/SchematicHarnessParser.mjs +9 -3
- package/src/core/altium/SchematicHyperlinkParser.mjs +122 -0
- package/src/core/altium/SchematicNetlistBuilder.mjs +271 -8
- package/src/core/altium/SchematicOwnershipGraphParser.mjs +102 -3
- package/src/core/altium/SchematicPinParser.mjs +12 -45
- package/src/core/altium/SchematicPrimitiveParser.mjs +9 -14
- package/src/core/altium/SchematicQaReportBuilder.mjs +2 -0
- package/src/core/altium/SchematicRecordStreamParser.mjs +183 -0
- package/src/core/altium/SchematicRecordTypeRegistry.mjs +6 -1
- package/src/core/altium/SchematicSheetParser.mjs +8 -2
- package/src/core/altium/SchematicStreamExtractor.mjs +64 -25
- package/src/core/altium/SchematicTextOrientationResolver.mjs +76 -0
- package/src/core/altium/SchematicTextParser.mjs +28 -12
- package/src/core/altium/SchematicTextRunParser.mjs +81 -0
- package/src/core/altium/SchematicThumbnailParser.mjs +425 -0
- package/src/core/altium/UnsupportedFeatureReportBuilder.mjs +380 -0
- package/src/parser.mjs +35 -1
- package/src/renderers.mjs +1 -0
- package/src/ui/SchematicShapeRenderer.mjs +49 -6
- package/src/ui/SchematicSvgRenderer.mjs +37 -8
- package/src/ui/SchematicTypography.mjs +4 -3
|
@@ -62,6 +62,7 @@ export class PcbLayerStackReadModelBuilder {
|
|
|
62
62
|
layerById,
|
|
63
63
|
'backdrill'
|
|
64
64
|
)
|
|
65
|
+
const stackup = PcbLayerStackReadModelBuilder.#stackup(fields)
|
|
65
66
|
const diagnostics = PcbLayerStackReadModelBuilder.#diagnostics({
|
|
66
67
|
substacks,
|
|
67
68
|
branches,
|
|
@@ -105,6 +106,7 @@ export class PcbLayerStackReadModelBuilder {
|
|
|
105
106
|
branches,
|
|
106
107
|
topLevelBendLines,
|
|
107
108
|
cavityReport,
|
|
109
|
+
...(stackup ? { stackup } : {}),
|
|
108
110
|
impedanceProfiles,
|
|
109
111
|
transmissionLines,
|
|
110
112
|
viaSpans,
|
|
@@ -166,9 +168,9 @@ export class PcbLayerStackReadModelBuilder {
|
|
|
166
168
|
PcbLayerStackReadModelBuilder.#stripUndefined({
|
|
167
169
|
index: layer.index,
|
|
168
170
|
layerId: layer.layerId,
|
|
169
|
-
layerKey:
|
|
170
|
-
layer.layerId
|
|
171
|
-
|
|
171
|
+
layerKey: Number.isFinite(layer.layerId)
|
|
172
|
+
? 'L' + layer.layerId
|
|
173
|
+
: undefined,
|
|
172
174
|
name: layer.name,
|
|
173
175
|
kind: layer.kind,
|
|
174
176
|
material: layer.material,
|
|
@@ -189,9 +191,9 @@ export class PcbLayerStackReadModelBuilder {
|
|
|
189
191
|
PcbLayerStackReadModelBuilder.#stripUndefined({
|
|
190
192
|
index: index + 1,
|
|
191
193
|
layerId: layer.layerId,
|
|
192
|
-
layerKey:
|
|
193
|
-
layer.layerId
|
|
194
|
-
|
|
194
|
+
layerKey: Number.isFinite(layer.layerId)
|
|
195
|
+
? 'L' + layer.layerId
|
|
196
|
+
: undefined,
|
|
195
197
|
name: layer.name,
|
|
196
198
|
kind: layer.kind || layer.role,
|
|
197
199
|
...PcbLayerStackSourceMetadataParser.layerSourceFields(
|
|
@@ -592,6 +594,81 @@ export class PcbLayerStackReadModelBuilder {
|
|
|
592
594
|
)
|
|
593
595
|
}
|
|
594
596
|
|
|
597
|
+
/**
|
|
598
|
+
* Parses document-level layer-stack metadata.
|
|
599
|
+
* @param {Record<string, string | string[]>} fields Board fields.
|
|
600
|
+
* @returns {object | undefined}
|
|
601
|
+
*/
|
|
602
|
+
static #stackup(fields) {
|
|
603
|
+
const features = PcbLayerStackReadModelBuilder.#stackupFeatures(fields)
|
|
604
|
+
const stackup = PcbLayerStackReadModelBuilder.#stripUndefined({
|
|
605
|
+
serializerVersion: PcbLayerStackReadModelBuilder.#field(
|
|
606
|
+
fields,
|
|
607
|
+
'STACKUPX_SERIALIZER_VERSION'
|
|
608
|
+
),
|
|
609
|
+
revisionId: PcbLayerStackReadModelBuilder.#field(
|
|
610
|
+
fields,
|
|
611
|
+
'STACKUPX_REVISION_ID'
|
|
612
|
+
),
|
|
613
|
+
type: PcbLayerStackReadModelBuilder.#field(fields, 'STACKUPX_TYPE'),
|
|
614
|
+
roughnessType: PcbLayerStackReadModelBuilder.#field(
|
|
615
|
+
fields,
|
|
616
|
+
'STACKUPX_ROUGHNESS_TYPE'
|
|
617
|
+
),
|
|
618
|
+
roughnessFactorSR: PcbLayerStackReadModelBuilder.#field(
|
|
619
|
+
fields,
|
|
620
|
+
'STACKUPX_ROUGHNESS_FACTOR_SR'
|
|
621
|
+
),
|
|
622
|
+
roughnessFactor: PcbLayerStackReadModelBuilder.#field(
|
|
623
|
+
fields,
|
|
624
|
+
'STACKUPX_ROUGHNESS_FACTOR'
|
|
625
|
+
),
|
|
626
|
+
realisticRatio: PcbLayerStackReadModelBuilder.#optionalBoolean(
|
|
627
|
+
PcbLayerStackReadModelBuilder.#field(
|
|
628
|
+
fields,
|
|
629
|
+
'STACKUPX_REALISTIC_RATIO'
|
|
630
|
+
)
|
|
631
|
+
),
|
|
632
|
+
features: PcbLayerStackSourceMetadataParser.optionalArray(features)
|
|
633
|
+
})
|
|
634
|
+
|
|
635
|
+
return Object.keys(stackup).length ? stackup : undefined
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* Parses stackup feature rows.
|
|
640
|
+
* @param {Record<string, string | string[]>} fields Board fields.
|
|
641
|
+
* @returns {object[]}
|
|
642
|
+
*/
|
|
643
|
+
static #stackupFeatures(fields) {
|
|
644
|
+
return PcbLayerStackReadModelBuilder.#indexedRows(fields, [
|
|
645
|
+
/^STACKUPX_FEATURE(\d+)_ID$/iu,
|
|
646
|
+
/^STACKUP_FEATURE(\d+)_ID$/iu
|
|
647
|
+
]).map((index) =>
|
|
648
|
+
PcbLayerStackReadModelBuilder.#stripUndefined({
|
|
649
|
+
index,
|
|
650
|
+
id: PcbLayerStackReadModelBuilder.#indexedField(
|
|
651
|
+
fields,
|
|
652
|
+
['STACKUPX_FEATURE', 'STACKUP_FEATURE'],
|
|
653
|
+
index,
|
|
654
|
+
['ID']
|
|
655
|
+
),
|
|
656
|
+
name: PcbLayerStackReadModelBuilder.#indexedField(
|
|
657
|
+
fields,
|
|
658
|
+
['STACKUPX_FEATURE', 'STACKUP_FEATURE'],
|
|
659
|
+
index,
|
|
660
|
+
['NAME']
|
|
661
|
+
),
|
|
662
|
+
kind: PcbLayerStackReadModelBuilder.#indexedField(
|
|
663
|
+
fields,
|
|
664
|
+
['STACKUPX_FEATURE', 'STACKUP_FEATURE'],
|
|
665
|
+
index,
|
|
666
|
+
['KIND']
|
|
667
|
+
)
|
|
668
|
+
})
|
|
669
|
+
)
|
|
670
|
+
}
|
|
671
|
+
|
|
595
672
|
/**
|
|
596
673
|
* Builds preservation-first diagnostics for unresolved references.
|
|
597
674
|
* @param {object} input Sidecar sections.
|
|
@@ -903,15 +980,6 @@ export class PcbLayerStackReadModelBuilder {
|
|
|
903
980
|
return Number.isFinite(parsed) ? parsed : undefined
|
|
904
981
|
}
|
|
905
982
|
|
|
906
|
-
/**
|
|
907
|
-
* Builds a stable layer key.
|
|
908
|
-
* @param {number | null | undefined} layerId Layer id.
|
|
909
|
-
* @returns {string | undefined}
|
|
910
|
-
*/
|
|
911
|
-
static #layerKey(layerId) {
|
|
912
|
-
return Number.isFinite(layerId) ? 'L' + layerId : undefined
|
|
913
|
-
}
|
|
914
|
-
|
|
915
983
|
/**
|
|
916
984
|
* Removes undefined and empty string values while keeping false and empty
|
|
917
985
|
* arrays stable.
|
|
@@ -53,6 +53,50 @@ export class PcbLayerStackSourceMetadataParser {
|
|
|
53
53
|
'COVERLAYEXPANSION',
|
|
54
54
|
'COVERLAY_EXPANSION'
|
|
55
55
|
]),
|
|
56
|
+
process: layerField(['PROCESS']),
|
|
57
|
+
pullbackDistance: layerField([
|
|
58
|
+
'PULLBACKDISTANCE',
|
|
59
|
+
'PULLBACK_DISTANCE'
|
|
60
|
+
]),
|
|
61
|
+
copperOrientation: layerField([
|
|
62
|
+
'COPPERORIENTATION',
|
|
63
|
+
'COPPER_ORIENTATION'
|
|
64
|
+
]),
|
|
65
|
+
orientation: layerField(['ORIENTATION']),
|
|
66
|
+
note: layerField(['NOTE']),
|
|
67
|
+
comment: layerField(['COMMENT']),
|
|
68
|
+
materialManufacturer: layerField([
|
|
69
|
+
'MATERIALMANUFACTURER',
|
|
70
|
+
'MATERIAL_MANUFACTURER'
|
|
71
|
+
]),
|
|
72
|
+
materialDescription: layerField([
|
|
73
|
+
'MATERIALDESCRIPTION',
|
|
74
|
+
'MATERIAL_DESCRIPTION'
|
|
75
|
+
]),
|
|
76
|
+
materialGlassTransitionTemp: layerField([
|
|
77
|
+
'MATERIALGLASSTRANSITIONTEMP',
|
|
78
|
+
'MATERIAL_GLASS_TRANSITION_TEMP'
|
|
79
|
+
]),
|
|
80
|
+
glassTransitionTemp: layerField([
|
|
81
|
+
'GLASSTRANSITIONTEMP',
|
|
82
|
+
'GLASS_TRANSITION_TEMP'
|
|
83
|
+
]),
|
|
84
|
+
dielectricStrength: layerField([
|
|
85
|
+
'DIELECTRICSTRENGTH',
|
|
86
|
+
'DIELECTRIC_STRENGTH'
|
|
87
|
+
]),
|
|
88
|
+
volumeResistivity: layerField([
|
|
89
|
+
'VOLUMERESISTIVITY',
|
|
90
|
+
'VOLUME_RESISTIVITY'
|
|
91
|
+
]),
|
|
92
|
+
resin: layerField(['RESIN']),
|
|
93
|
+
solid: layerField(['SOLID']),
|
|
94
|
+
materialFrequency: layerField([
|
|
95
|
+
'MATERIALFREQUENCY',
|
|
96
|
+
'MATERIAL_FREQUENCY'
|
|
97
|
+
]),
|
|
98
|
+
frequency: layerField(['FREQUENCY']),
|
|
99
|
+
constructions: layerField(['CONSTRUCTIONS']),
|
|
56
100
|
isStiffener: PcbLayerStackSourceMetadataParser.#optionalBoolean(
|
|
57
101
|
layerField(['ISSTIFFENER', 'IS_STIFFENER'])
|
|
58
102
|
),
|
|
@@ -235,10 +279,17 @@ export class PcbLayerStackSourceMetadataParser {
|
|
|
235
279
|
* @returns {object[]}
|
|
236
280
|
*/
|
|
237
281
|
static #substackEnablement(fields, layerIndex) {
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
282
|
+
const prefix = 'V9_STACK_LAYER' + layerIndex + '_SUBSTACK'
|
|
283
|
+
if (
|
|
284
|
+
!PcbLayerStackSourceMetadataParser.#hasCaseInsensitivePrefix(
|
|
285
|
+
fields,
|
|
286
|
+
prefix
|
|
287
|
+
)
|
|
288
|
+
) {
|
|
289
|
+
return []
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const pattern = new RegExp('^' + prefix + '(\\d+)_ENABLED$', 'iu')
|
|
242
293
|
|
|
243
294
|
return Object.keys(fields)
|
|
244
295
|
.flatMap((key) => {
|
|
@@ -261,6 +312,25 @@ export class PcbLayerStackSourceMetadataParser {
|
|
|
261
312
|
.sort((left, right) => left.substackIndex - right.substackIndex)
|
|
262
313
|
}
|
|
263
314
|
|
|
315
|
+
/**
|
|
316
|
+
* Returns true when any field key starts with a prefix, ignoring case.
|
|
317
|
+
* @param {Record<string, string | string[]>} fields Source fields.
|
|
318
|
+
* @param {string} prefix Field-key prefix.
|
|
319
|
+
* @returns {boolean}
|
|
320
|
+
*/
|
|
321
|
+
static #hasCaseInsensitivePrefix(fields, prefix) {
|
|
322
|
+
const upperPrefix = prefix.toUpperCase()
|
|
323
|
+
for (const key of PcbLayerStackSourceMetadataParser.#fieldIndex(
|
|
324
|
+
fields
|
|
325
|
+
).keys()) {
|
|
326
|
+
if (key.startsWith(upperPrefix)) {
|
|
327
|
+
return true
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return false
|
|
332
|
+
}
|
|
333
|
+
|
|
264
334
|
/**
|
|
265
335
|
* Parses branch-section stack rows.
|
|
266
336
|
* @param {Record<string, string | string[]>} fields Board fields.
|
|
@@ -20,7 +20,7 @@ export class PcbLibModelParser {
|
|
|
20
20
|
/**
|
|
21
21
|
* Parses one extracted PcbLib into a normalized read-only model.
|
|
22
22
|
* @param {string} fileName
|
|
23
|
-
* @param {{ libraryHeader?: Record<string, string>, componentParamsToc?: Record<string, object>, sectionKeys?: Record<string, string>, footprints?: object[], embeddedFonts?: { fonts?: object[] }, streamNames?: string[], diagnostics?: Record<string, number> } | null} extraction
|
|
23
|
+
* @param {{ libraryHeader?: Record<string, string>, componentParamsToc?: Record<string, object>, sectionKeys?: Record<string, string>, footprints?: object[], embeddedFonts?: { fonts?: object[] }, nativeStreams?: object, streamNames?: string[], diagnostics?: Record<string, number> } | null} extraction
|
|
24
24
|
* @returns {{ schema: string, kind: 'pcb-library', fileType: 'PcbLib', fileName: string, summary: Record<string, number | string>, diagnostics: { severity: 'info' | 'warning', message: string }[], pcbLibrary: { libraryHeader: Record<string, string>, componentParamsToc: Record<string, object>, sectionKeys: Record<string, string>, footprints: object[], embeddedFonts: object[] }, bom: [] }}
|
|
25
25
|
*/
|
|
26
26
|
static parse(fileName, extraction) {
|
|
@@ -54,7 +54,8 @@ export class PcbLibModelParser {
|
|
|
54
54
|
fileName,
|
|
55
55
|
footprints,
|
|
56
56
|
embeddedFonts,
|
|
57
|
-
embeddedModels
|
|
57
|
+
embeddedModels,
|
|
58
|
+
safeExtraction.nativeStreams
|
|
58
59
|
)
|
|
59
60
|
const diagnostics = PcbLibModelParser.#buildDiagnostics(
|
|
60
61
|
footprints,
|
|
@@ -71,6 +72,9 @@ export class PcbLibModelParser {
|
|
|
71
72
|
embeddedFonts,
|
|
72
73
|
embeddedModels,
|
|
73
74
|
componentBodies,
|
|
75
|
+
...(safeExtraction.nativeStreams
|
|
76
|
+
? { nativeStreams: safeExtraction.nativeStreams }
|
|
77
|
+
: {}),
|
|
74
78
|
...(defaults ? { defaults } : {})
|
|
75
79
|
}
|
|
76
80
|
pcbLibrary.renderManifest =
|
|
@@ -94,9 +98,16 @@ export class PcbLibModelParser {
|
|
|
94
98
|
* @param {object[]} footprints
|
|
95
99
|
* @param {object[]} embeddedFonts
|
|
96
100
|
* @param {object[]} embeddedModels
|
|
101
|
+
* @param {object | undefined} nativeStreams Native stream inventory.
|
|
97
102
|
* @returns {Record<string, number | string>}
|
|
98
103
|
*/
|
|
99
|
-
static #buildSummary(
|
|
104
|
+
static #buildSummary(
|
|
105
|
+
fileName,
|
|
106
|
+
footprints,
|
|
107
|
+
embeddedFonts,
|
|
108
|
+
embeddedModels,
|
|
109
|
+
nativeStreams
|
|
110
|
+
) {
|
|
100
111
|
return {
|
|
101
112
|
title: stripExtension(fileName),
|
|
102
113
|
footprintCount: footprints.length,
|
|
@@ -116,7 +127,12 @@ export class PcbLibModelParser {
|
|
|
116
127
|
'rawRecords'
|
|
117
128
|
),
|
|
118
129
|
embeddedFontCount: embeddedFonts.length,
|
|
119
|
-
embeddedModelCount: embeddedModels.length
|
|
130
|
+
embeddedModelCount: embeddedModels.length,
|
|
131
|
+
...(nativeStreams?.summary?.streamCount
|
|
132
|
+
? {
|
|
133
|
+
nativeStreamCount: nativeStreams.summary.streamCount
|
|
134
|
+
}
|
|
135
|
+
: {})
|
|
120
136
|
}
|
|
121
137
|
}
|
|
122
138
|
|
|
@@ -7,6 +7,7 @@ import { PcbCustomPadShapeParser } from './PcbCustomPadShapeParser.mjs'
|
|
|
7
7
|
import { PcbEmbeddedFontExtractor } from './PcbEmbeddedFontExtractor.mjs'
|
|
8
8
|
import { PcbEmbeddedModelExtractor } from './PcbEmbeddedModelExtractor.mjs'
|
|
9
9
|
import { PcbExtendedPrimitiveInformationParser } from './PcbExtendedPrimitiveInformationParser.mjs'
|
|
10
|
+
import { NativeStreamInventoryBuilder } from './NativeStreamInventoryBuilder.mjs'
|
|
10
11
|
import { PcbRawRecordRegistry } from './PcbRawRecordRegistry.mjs'
|
|
11
12
|
import { OleCompoundDocument } from '../ole/OleCompoundDocument.mjs'
|
|
12
13
|
import { OleConstants } from '../ole/OleConstants.mjs'
|
|
@@ -164,18 +165,29 @@ export class PcbLibStreamExtractor {
|
|
|
164
165
|
PcbEmbeddedFontExtractor.extractFromStreams(streams)
|
|
165
166
|
const embeddedModels =
|
|
166
167
|
PcbEmbeddedModelExtractor.extractFromStreams(streams)
|
|
168
|
+
const usedStreamNames = PcbLibStreamExtractor.#collectUsedStreamNames(
|
|
169
|
+
footprints,
|
|
170
|
+
streams,
|
|
171
|
+
embeddedFonts,
|
|
172
|
+
embeddedModels
|
|
173
|
+
)
|
|
174
|
+
const nativeStreams = NativeStreamInventoryBuilder.buildFromStreams(
|
|
175
|
+
streams,
|
|
176
|
+
{
|
|
177
|
+
source: 'pcblib',
|
|
178
|
+
consumedStreamNames: usedStreamNames,
|
|
179
|
+
knownStreamNames:
|
|
180
|
+
PcbLibStreamExtractor.#knownStreamNames(streams)
|
|
181
|
+
}
|
|
182
|
+
)
|
|
167
183
|
|
|
168
184
|
return {
|
|
169
185
|
libraryHeader: parsedLibraryData.libraryHeader,
|
|
170
186
|
componentParamsToc,
|
|
171
187
|
sectionKeys,
|
|
172
188
|
footprints,
|
|
173
|
-
streamNames:
|
|
174
|
-
|
|
175
|
-
streams,
|
|
176
|
-
embeddedFonts,
|
|
177
|
-
embeddedModels
|
|
178
|
-
),
|
|
189
|
+
streamNames: usedStreamNames,
|
|
190
|
+
nativeStreams,
|
|
179
191
|
embeddedFonts,
|
|
180
192
|
embeddedModels,
|
|
181
193
|
diagnostics: {
|
|
@@ -999,6 +1011,37 @@ export class PcbLibStreamExtractor {
|
|
|
999
1011
|
return [...names].sort((left, right) => left.localeCompare(right))
|
|
1000
1012
|
}
|
|
1001
1013
|
|
|
1014
|
+
/**
|
|
1015
|
+
* Builds recognized PcbLib stream names from one stream map.
|
|
1016
|
+
* @param {Map<string, Uint8Array>} streams Native stream map.
|
|
1017
|
+
* @returns {string[]}
|
|
1018
|
+
*/
|
|
1019
|
+
static #knownStreamNames(streams) {
|
|
1020
|
+
return [...(streams || new Map()).keys()].filter((streamName) => {
|
|
1021
|
+
if (
|
|
1022
|
+
[
|
|
1023
|
+
'Library/Data',
|
|
1024
|
+
'Library/ComponentParamsTOC/Data',
|
|
1025
|
+
'SectionKeys'
|
|
1026
|
+
].includes(streamName)
|
|
1027
|
+
) {
|
|
1028
|
+
return true
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
const leafName = String(streamName || '')
|
|
1032
|
+
.split('/')
|
|
1033
|
+
.at(-1)
|
|
1034
|
+
return [
|
|
1035
|
+
'Header',
|
|
1036
|
+
'Data',
|
|
1037
|
+
'Parameters',
|
|
1038
|
+
'WideStrings',
|
|
1039
|
+
'ExtendedPrimitiveInformation',
|
|
1040
|
+
'CustomShapes'
|
|
1041
|
+
].includes(leafName)
|
|
1042
|
+
})
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1002
1045
|
/**
|
|
1003
1046
|
* Sanitizes one footprint name for legacy OLE storage lookup.
|
|
1004
1047
|
* @param {string} name
|