milsymbol-sidc 0.2.0 → 0.4.0
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 +266 -31
- package/dist/src/catalog.d.ts +39 -0
- package/dist/src/catalog.d.ts.map +1 -0
- package/dist/src/catalog.js +63 -0
- package/dist/src/catalog.js.map +1 -0
- package/dist/src/catalogs.generated.d.ts +20 -0
- package/dist/src/catalogs.generated.d.ts.map +1 -0
- package/dist/src/catalogs.generated.js +2241 -0
- package/dist/src/catalogs.generated.js.map +1 -0
- package/dist/src/enums.d.ts +47 -1
- package/dist/src/enums.d.ts.map +1 -1
- package/dist/src/enums.js +45 -1
- package/dist/src/enums.js.map +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/sidc.d.ts +93 -8
- package/dist/src/sidc.d.ts.map +1 -1
- package/dist/src/sidc.js +192 -46
- package/dist/src/sidc.js.map +1 -1
- package/dist/src/validate.d.ts +40 -7
- package/dist/src/validate.d.ts.map +1 -1
- package/dist/src/validate.js +132 -19
- package/dist/src/validate.js.map +1 -1
- package/package.json +34 -6
- package/dist/test/sidc.test.d.ts +0 -2
- package/dist/test/sidc.test.d.ts.map +0 -1
- package/dist/test/sidc.test.js +0 -384
- package/dist/test/sidc.test.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# milsymbol-sidc
|
|
2
2
|
|
|
3
|
+
[](https://github.com/psylsph/milsymbol-sidc/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/milsymbol-sidc)
|
|
5
|
+
[](https://www.npmjs.com/package/milsymbol-sidc)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
|
|
3
9
|
A fluent TypeScript builder for **20-character numeric SIDC strings** — the
|
|
4
10
|
symbol identification code format used by [MIL-STD-2525E](https://en.wikipedia.org/wiki/MIL-STD-2525)
|
|
5
11
|
and [APP-6](https://en.wikipedia.org/wiki/NATO_Joint_Military_Symbology) — made
|
|
@@ -7,6 +13,7 @@ for constructing symbols with the
|
|
|
7
13
|
[milsymbol](https://github.com/spatialillusions/milsymbol) library.
|
|
8
14
|
|
|
9
15
|
```ts
|
|
16
|
+
import ms from "milsymbol";
|
|
10
17
|
import { Sidc, StandardIdentity, SymbolSet } from "milsymbol-sidc";
|
|
11
18
|
|
|
12
19
|
const sidc = new Sidc()
|
|
@@ -23,15 +30,18 @@ new ms.Symbol(sidc).asSVG(); // friendly land unit icon
|
|
|
23
30
|
- **Validated output** — invalid values throw; inconsistent combinations warn
|
|
24
31
|
(or throw in `strict` mode), using the same rules milsymbol applies when it
|
|
25
32
|
parses a SIDC.
|
|
26
|
-
- **milsymbol-ready** —
|
|
27
|
-
|
|
33
|
+
- **milsymbol-ready** — every generated 20-character string is accepted by
|
|
34
|
+
milsymbol's numeric parser. Full rendering depends on the entity and
|
|
35
|
+
modifier codes you supply, exactly as it does for any raw SIDC.
|
|
28
36
|
|
|
29
|
-
> **Coverage:** positions 1–
|
|
30
|
-
>
|
|
31
|
-
> entity
|
|
37
|
+
> **Coverage:** complete structural encoding for positions 1–20 of the numeric
|
|
38
|
+
> SIDC. Positions 8–10 have named universal codes; positions 11–20 accept
|
|
39
|
+
> validated raw entity and modifier codes. A membership-only code catalog ships
|
|
40
|
+
> behind the `milsymbol-sidc/catalogs` subpath; semantic names remain future work.
|
|
32
41
|
|
|
33
42
|
## Installation
|
|
34
43
|
|
|
44
|
+
Published on npm as [`milsymbol-sidc`](https://www.npmjs.com/package/milsymbol-sidc).
|
|
35
45
|
Requires Node.js >= 18.
|
|
36
46
|
|
|
37
47
|
```bash
|
|
@@ -42,6 +52,15 @@ yarn add milsymbol-sidc
|
|
|
42
52
|
pnpm add milsymbol-sidc
|
|
43
53
|
```
|
|
44
54
|
|
|
55
|
+
The rendering examples use [`milsymbol`](https://github.com/spatialillusions/milsymbol)
|
|
56
|
+
to draw the generated SIDC. It is **not** a dependency of this package —
|
|
57
|
+
`milsymbol-sidc` has zero runtime dependencies — so install it alongside when
|
|
58
|
+
you want to render symbols:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm install milsymbol
|
|
62
|
+
```
|
|
63
|
+
|
|
45
64
|
The package ships ESM with bundled TypeScript declarations (`dist/`).
|
|
46
65
|
|
|
47
66
|
## Quick start
|
|
@@ -73,6 +92,8 @@ The builder is **immutable**: each setter returns a new instance, so a base
|
|
|
73
92
|
configuration can be safely reused:
|
|
74
93
|
|
|
75
94
|
```ts
|
|
95
|
+
import { Sidc, Standard, StandardIdentity } from "milsymbol-sidc";
|
|
96
|
+
|
|
76
97
|
const base = new Sidc({ standard: Standard.App6 });
|
|
77
98
|
|
|
78
99
|
const friendly = base.identity(StandardIdentity.Friend).toString();
|
|
@@ -82,24 +103,33 @@ const hostile = base.identity(StandardIdentity.SuspectJoker).toString();
|
|
|
82
103
|
|
|
83
104
|
## Anatomy of the generated SIDC
|
|
84
105
|
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
│
|
|
89
|
-
│
|
|
90
|
-
│
|
|
91
|
-
│
|
|
92
|
-
└
|
|
93
|
-
|
|
106
|
+
```text
|
|
107
|
+
13 0 3 10 0 2 16 123456 78 90
|
|
108
|
+
│ │ │ │ │ │ │ │ │ │
|
|
109
|
+
│ │ │ │ │ │ │ │ │ └ modifier 2 (19–20)
|
|
110
|
+
│ │ │ │ │ │ │ │ └ │ modifier 1 (17–18)
|
|
111
|
+
│ │ │ │ │ │ │ └ │ │ entity code (11–16)
|
|
112
|
+
│ │ │ │ │ │ └ │ │ │ amplifier (9–10)
|
|
113
|
+
│ │ │ │ │ └ │ │ │ │ HQ/task force/feint-dummy (8)
|
|
114
|
+
│ │ │ │ └ │ │ │ │ │ status (7)
|
|
115
|
+
│ │ │ └ │ │ │ │ │ │ symbol set (5–6)
|
|
116
|
+
│ │ └ │ │ │ │ │ │ │ standard identity (4)
|
|
117
|
+
│ └ │ │ │ │ │ │ │ │ context (3)
|
|
118
|
+
└ │ │ │ │ │ │ │ │ │ version / edition (1–2)
|
|
94
119
|
```
|
|
95
120
|
|
|
96
|
-
| Position | Field |
|
|
121
|
+
| Position | Field | API |
|
|
97
122
|
| -------- | ------------------ | ----------------- |
|
|
98
|
-
| 1–2 | Version / edition | `Version` |
|
|
99
|
-
| 3 | Context | `Context` |
|
|
100
|
-
| 4 | Standard identity | `StandardIdentity` |
|
|
101
|
-
| 5–6 | Symbol set | `SymbolSet` |
|
|
102
|
-
| 7 | Status / condition | `Status` |
|
|
123
|
+
| 1–2 | Version / edition | `Version`, `version()` |
|
|
124
|
+
| 3 | Context | `Context`, `context()` |
|
|
125
|
+
| 4 | Standard identity | `StandardIdentity`, `identity()` |
|
|
126
|
+
| 5–6 | Symbol set | `SymbolSet`, `symbolSet()` |
|
|
127
|
+
| 7 | Status / condition | `Status`, `status()` |
|
|
128
|
+
| 8 | HQ/task force/feint-dummy | `HqTaskForceDummy`, `hqTaskForceDummy()` |
|
|
129
|
+
| 9–10 | Amplifier | `Amplifier`, `amplifier()` |
|
|
130
|
+
| 11–16 | Entity code | `entity()` — six raw digits |
|
|
131
|
+
| 17–18 | Modifier 1 | `modifier1()` — two raw digits |
|
|
132
|
+
| 19–20 | Modifier 2 | `modifier2()` — two raw digits |
|
|
103
133
|
|
|
104
134
|
## API
|
|
105
135
|
|
|
@@ -113,6 +143,7 @@ Present. This remains the default for backward compatibility; configure
|
|
|
113
143
|
| ------ | ---- | ------- | ----------- |
|
|
114
144
|
| `strict` | `boolean` | `false` | Throw on invalid field combinations during `toString()` instead of warning. Invalid values always throw immediately regardless of this flag. |
|
|
115
145
|
| `standard` | `Standard` | Not configured (2525E behavior) | Select a standard family. `App6` defaults the version to APP-6 E (`"14"`); `MilStd2525` defaults it to MIL-STD-2525E (`"13"`). Explicit configuration also checks that later version choices belong to the selected family. |
|
|
146
|
+
| `onWarning` | `(problem: SidcProblem) => void` | `console.warn` | Receive non-fatal problems instead of writing to the console. `strict: true` still throws instead of reporting. |
|
|
116
147
|
|
|
117
148
|
### Methods
|
|
118
149
|
|
|
@@ -126,7 +157,20 @@ All setters validate their argument and return a new immutable `Sidc`.
|
|
|
126
157
|
| `identity(i)` | Position 4 | A `StandardIdentity` constant |
|
|
127
158
|
| `symbolSet(s)` | Positions 5–6 | A `SymbolSet` constant or any two-digit string |
|
|
128
159
|
| `status(s)` | Position 7 | A `Status` constant |
|
|
160
|
+
| `hqTaskForceDummy(v)` | Position 8 | An `HqTaskForceDummy` constant |
|
|
161
|
+
| `amplifier(v)` | Positions 9–10 | An `Amplifier` constant |
|
|
162
|
+
| `entity(v)` | Positions 11–16 | Any six-digit string; symbol-set-specific catalogs are not included |
|
|
163
|
+
| `modifier1(v)` | Positions 17–18 | Any two-digit string; symbol-set-specific catalogs are not included |
|
|
164
|
+
| `modifier2(v)` | Positions 19–20 | Any two-digit string; symbol-set-specific catalogs are not included |
|
|
129
165
|
| `toString()` | — | Validates combinations and renders the 20-character SIDC |
|
|
166
|
+
| `problems()` | — | Structured list of non-fatal problems; never throws |
|
|
167
|
+
| `isValid()` | — | `true` when `problems()` is empty |
|
|
168
|
+
| `with(fields)` | — | Applies a partial field record immutably; validates like the setters |
|
|
169
|
+
| `clone()` | — | Copies the fields into an independent builder |
|
|
170
|
+
| `equals(other)` | — | Compares encoded fields, ignoring `strict` and `standard` |
|
|
171
|
+
| `toObject()` / `toJSON()` | — | Plain, serializable snapshot of every encoded field |
|
|
172
|
+
| `Sidc.parse(s, options?)` | — | Parses a 20-character numeric SIDC; throws when invalid |
|
|
173
|
+
| `Sidc.tryParse(s, options?)` | — | Parses a SIDC or returns `undefined` |
|
|
130
174
|
|
|
131
175
|
### Enum reference
|
|
132
176
|
|
|
@@ -140,6 +184,63 @@ same constant can configure both libraries.
|
|
|
140
184
|
| `MilStd2525` | `"2525"` | US MIL-STD-2525 (**default behavior when omitted**) |
|
|
141
185
|
| `App6` | `"APP6"` | NATO APP-6 |
|
|
142
186
|
|
|
187
|
+
#### `HqTaskForceDummy`
|
|
188
|
+
|
|
189
|
+
Position 8 values identify headquarters, task force, and feint/dummy variants.
|
|
190
|
+
|
|
191
|
+
| Constant | Code | Meaning |
|
|
192
|
+
| -------- | ---- | ------- |
|
|
193
|
+
| `None` | `"0"` | None / not applicable |
|
|
194
|
+
| `FeintDummy` | `"1"` | Feint/dummy |
|
|
195
|
+
| `Headquarters` | `"2"` | Headquarters |
|
|
196
|
+
| `FeintDummyHeadquarters` | `"3"` | Feint/dummy headquarters |
|
|
197
|
+
| `TaskForce` | `"4"` | Task force |
|
|
198
|
+
| `FeintDummyTaskForce` | `"5"` | Feint/dummy task force |
|
|
199
|
+
| `TaskForceHeadquarters` | `"6"` | Task-force headquarters |
|
|
200
|
+
| `FeintDummyTaskForceHeadquarters` | `"7"` | Feint/dummy task-force headquarters |
|
|
201
|
+
|
|
202
|
+
#### `Amplifier`
|
|
203
|
+
|
|
204
|
+
Position 9–10 values identify echelon, mobility, leadership, or auxiliary
|
|
205
|
+
amplifiers. `None` writes the zero/no-amplifier code `"00"`.
|
|
206
|
+
|
|
207
|
+
| Constant | Code | Meaning |
|
|
208
|
+
| -------- | ---- | ------- |
|
|
209
|
+
| `None` | `"00"` | None / not specified |
|
|
210
|
+
| `TeamCrew` | `"11"` | Team/crew |
|
|
211
|
+
| `Squad` | `"12"` | Squad |
|
|
212
|
+
| `Section` | `"13"` | Section |
|
|
213
|
+
| `PlatoonDetachment` | `"14"` | Platoon/detachment |
|
|
214
|
+
| `CompanyBatteryTroop` | `"15"` | Company/battery/troop |
|
|
215
|
+
| `BattalionSquadron` | `"16"` | Battalion/squadron |
|
|
216
|
+
| `RegimentGroup` | `"17"` | Regiment/group |
|
|
217
|
+
| `Brigade` | `"18"` | Brigade |
|
|
218
|
+
| `Division` | `"21"` | Division |
|
|
219
|
+
| `CorpsMef` | `"22"` | Corps/MEF |
|
|
220
|
+
| `Army` | `"23"` | Army |
|
|
221
|
+
| `ArmyGroupFront` | `"24"` | Army group/front |
|
|
222
|
+
| `RegionTheater` | `"25"` | Region/theater |
|
|
223
|
+
| `Command` | `"26"` | Command |
|
|
224
|
+
| `WheeledLimitedCrossCountry` | `"31"` | Wheeled, limited cross-country |
|
|
225
|
+
| `WheeledCrossCountry` | `"32"` | Wheeled, cross-country |
|
|
226
|
+
| `Tracked` | `"33"` | Tracked |
|
|
227
|
+
| `WheeledTrackedCombination` | `"34"` | Wheeled and tracked combination |
|
|
228
|
+
| `Towed` | `"35"` | Towed |
|
|
229
|
+
| `Rail` | `"36"` | Rail |
|
|
230
|
+
| `PackAnimals` | `"37"` | Pack animals |
|
|
231
|
+
| `OverSnowPrimeMover` | `"41"` | Over snow, prime mover |
|
|
232
|
+
| `Sled` | `"42"` | Sled |
|
|
233
|
+
| `Barge` | `"51"` | Barge |
|
|
234
|
+
| `Amphibious` | `"52"` | Amphibious |
|
|
235
|
+
| `ShortTowedArray` | `"61"` | Short towed array |
|
|
236
|
+
| `LongTowedArray` | `"62"` | Long towed array |
|
|
237
|
+
| `LeaderIndividual` | `"71"` | Leader individual |
|
|
238
|
+
| `DeputyIndividual` | `"72"` | Deputy individual |
|
|
239
|
+
|
|
240
|
+
Entity and modifier setters intentionally accept raw digit strings so callers
|
|
241
|
+
can use codes specific to their symbol set and edition. They validate width and
|
|
242
|
+
ASCII digits but do not validate catalog membership.
|
|
243
|
+
|
|
143
244
|
#### `Version`
|
|
144
245
|
|
|
145
246
|
| Constant | Code | Standard |
|
|
@@ -216,8 +317,10 @@ string escape hatch.
|
|
|
216
317
|
Two layers of validation run at different times:
|
|
217
318
|
|
|
218
319
|
1. **Setter-time (`SidcValidationError`)** — thrown immediately for malformed
|
|
219
|
-
input (wrong number of digits) or unknown enum codes.
|
|
220
|
-
|
|
320
|
+
input (wrong number of digits) or unknown enum codes. Values must be
|
|
321
|
+
strings: passing a number or other non-string value throws rather than
|
|
322
|
+
being coerced. This catches bugs at the call site rather than deep inside
|
|
323
|
+
rendering code.
|
|
221
324
|
2. **`toString()`-time combination checks** — cross-field rules mirroring
|
|
222
325
|
milsymbol's parser. By default problems are emitted with `console.warn`;
|
|
223
326
|
with `{ strict: true }` they throw `SidcCombinationError`.
|
|
@@ -235,7 +338,18 @@ Active combination rules:
|
|
|
235
338
|
- Raw version/symbol-set codes outside milsymbol's known tables are reported.
|
|
236
339
|
|
|
237
340
|
```ts
|
|
238
|
-
import {
|
|
341
|
+
import {
|
|
342
|
+
Amplifier,
|
|
343
|
+
Context,
|
|
344
|
+
HqTaskForceDummy,
|
|
345
|
+
Sidc,
|
|
346
|
+
SidcCombinationError,
|
|
347
|
+
SidcValidationError,
|
|
348
|
+
Standard,
|
|
349
|
+
StandardIdentity,
|
|
350
|
+
Status,
|
|
351
|
+
SymbolSet,
|
|
352
|
+
} from "milsymbol-sidc";
|
|
239
353
|
|
|
240
354
|
// Throws immediately: "9" is not a valid identity code.
|
|
241
355
|
new Sidc().identity("9" as never); // SidcValidationError
|
|
@@ -252,6 +366,17 @@ new Sidc({ strict: true })
|
|
|
252
366
|
.symbolSet(SymbolSet.LandUnit)
|
|
253
367
|
.toString(); // "13161000000000000000", no warnings
|
|
254
368
|
|
|
369
|
+
// A complete structural 20-position SIDC using raw entity/modifier codes.
|
|
370
|
+
new Sidc({ standard: Standard.App6, strict: true })
|
|
371
|
+
.identity(StandardIdentity.Friend)
|
|
372
|
+
.symbolSet(SymbolSet.LandUnit)
|
|
373
|
+
.hqTaskForceDummy(HqTaskForceDummy.Headquarters)
|
|
374
|
+
.amplifier(Amplifier.BattalionSquadron)
|
|
375
|
+
.entity("123456")
|
|
376
|
+
.modifier1("01")
|
|
377
|
+
.modifier2("09")
|
|
378
|
+
.toString(); // "14031002161234560109"
|
|
379
|
+
|
|
255
380
|
// A real combination problem: condition status on a control measure.
|
|
256
381
|
new Sidc({ strict: true })
|
|
257
382
|
.symbolSet(SymbolSet.ControlMeasure)
|
|
@@ -275,6 +400,72 @@ try {
|
|
|
275
400
|
Error classes: `SidcError` (base) → `SidcValidationError`,
|
|
276
401
|
`SidcCombinationError`.
|
|
277
402
|
|
|
403
|
+
### Reading and reporting problems
|
|
404
|
+
|
|
405
|
+
`console.warn` is only the default. Inspect problems without side effects with
|
|
406
|
+
`problems()` and `isValid()`, or route them anywhere with `onWarning`:
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
import { Sidc, SymbolSet, Status } from "milsymbol-sidc";
|
|
410
|
+
|
|
411
|
+
const sidc = new Sidc()
|
|
412
|
+
.symbolSet(SymbolSet.ControlMeasure)
|
|
413
|
+
.status(Status.Destroyed);
|
|
414
|
+
|
|
415
|
+
sidc.problems();
|
|
416
|
+
// [{ code: "condition-status-control-measure", message: "…" }]
|
|
417
|
+
sidc.isValid(); // false
|
|
418
|
+
|
|
419
|
+
new Sidc({ onWarning: (problem) => log.warn(problem.code) })
|
|
420
|
+
.symbolSet(SymbolSet.ControlMeasure)
|
|
421
|
+
.status(Status.Destroyed)
|
|
422
|
+
.toString(); // no console output; onWarning is called once
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
Every problem carries a stable `code` and the exact legacy warning `message`.
|
|
426
|
+
`problems()` never throws, even for builders created with `{ strict: true }`;
|
|
427
|
+
`toString()` still throws `SidcCombinationError` in strict mode.
|
|
428
|
+
|
|
429
|
+
## Parsing a SIDC
|
|
430
|
+
|
|
431
|
+
`Sidc.parse()` turns a 20-character numeric SIDC back into a builder so you can
|
|
432
|
+
validate, edit, and re-render existing codes. `Sidc.tryParse()` returns
|
|
433
|
+
`undefined` instead of throwing.
|
|
434
|
+
|
|
435
|
+
```ts
|
|
436
|
+
import { Sidc } from "milsymbol-sidc";
|
|
437
|
+
|
|
438
|
+
const sidc = Sidc.parse("14031002161234560109");
|
|
439
|
+
sidc.toObject().entity; // "123456"
|
|
440
|
+
|
|
441
|
+
sidc.with({ modifier1: "02" }).toString(); // "14031002161234560209"
|
|
442
|
+
Sidc.tryParse("not-a-sidc"); // undefined
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
Round-tripping is guaranteed: `Sidc.parse(s).toString() === s` for any string
|
|
446
|
+
this library produces. Only the 20-character numeric form is supported today;
|
|
447
|
+
letter-based SIDCs and the 21–30 character extension are not.
|
|
448
|
+
|
|
449
|
+
## Catalogs (optional)
|
|
450
|
+
|
|
451
|
+
The `milsymbol-sidc/catalogs` subpath exposes a membership catalog generated from
|
|
452
|
+
milsymbol's numeric symbol data: which entity and modifier codes milsymbol
|
|
453
|
+
registers for each symbol set. It is a separate entry point, so the core builder
|
|
454
|
+
stays data-free unless you import it.
|
|
455
|
+
|
|
456
|
+
```ts
|
|
457
|
+
import { entityCodes, isKnownEntityCode } from "milsymbol-sidc/catalogs";
|
|
458
|
+
|
|
459
|
+
isKnownEntityCode("10", "121100"); // true — a registered land-unit entity
|
|
460
|
+
isKnownEntityCode("10", "999999"); // false
|
|
461
|
+
entityCodes("10").length; // number of registered land-unit codes
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
The catalog is **membership only**: it carries no semantic names and is never
|
|
465
|
+
consulted by `toString()`, so raw entity and modifier values still encode
|
|
466
|
+
without recognition warnings. Regenerate it with `npm run generate:catalogs`;
|
|
467
|
+
the milsymbol version it was derived from is exported as `CATALOG_SOURCE`.
|
|
468
|
+
|
|
278
469
|
## Using with milsymbol
|
|
279
470
|
|
|
280
471
|
milsymbol routes any SIDC whose first two characters are digits to its numeric
|
|
@@ -304,11 +495,29 @@ const svg = symbol.asSVG();
|
|
|
304
495
|
|
|
305
496
|
### Node.js (CommonJS)
|
|
306
497
|
|
|
498
|
+
`milsymbol-sidc` is ESM-only. From CommonJS, load it with dynamic `import()`.
|
|
499
|
+
`milsymbol` itself can be `require`d directly:
|
|
500
|
+
|
|
307
501
|
```js
|
|
308
502
|
const ms = require("milsymbol");
|
|
309
|
-
|
|
503
|
+
|
|
504
|
+
async function render() {
|
|
505
|
+
const { Sidc, Standard, StandardIdentity, SymbolSet } = await import(
|
|
506
|
+
"milsymbol-sidc"
|
|
507
|
+
);
|
|
508
|
+
|
|
509
|
+
const sidc = new Sidc({ standard: Standard.App6 })
|
|
510
|
+
.identity(StandardIdentity.Friend)
|
|
511
|
+
.symbolSet(SymbolSet.LandUnit)
|
|
512
|
+
.toString();
|
|
513
|
+
|
|
514
|
+
return new ms.Symbol(sidc, { size: 32 }).asSVG();
|
|
515
|
+
}
|
|
310
516
|
```
|
|
311
517
|
|
|
518
|
+
Node.js 20.19+ and 22.12+ can also `require("milsymbol-sidc")` directly via
|
|
519
|
+
`require(esm)`; earlier Node 18/20 releases must use `import()`.
|
|
520
|
+
|
|
312
521
|
### Browser
|
|
313
522
|
|
|
314
523
|
```html
|
|
@@ -330,6 +539,18 @@ const ms = require("milsymbol");
|
|
|
330
539
|
### Recipes
|
|
331
540
|
|
|
332
541
|
```ts
|
|
542
|
+
import {
|
|
543
|
+
Amplifier,
|
|
544
|
+
Context,
|
|
545
|
+
HqTaskForceDummy,
|
|
546
|
+
Sidc,
|
|
547
|
+
Standard,
|
|
548
|
+
StandardIdentity,
|
|
549
|
+
Status,
|
|
550
|
+
SymbolSet,
|
|
551
|
+
Version,
|
|
552
|
+
} from "milsymbol-sidc";
|
|
553
|
+
|
|
333
554
|
// Hostile planned armored unit
|
|
334
555
|
new Sidc()
|
|
335
556
|
.identity(StandardIdentity.SuspectJoker)
|
|
@@ -358,6 +579,15 @@ new Sidc({ standard: Standard.App6, strict: true })
|
|
|
358
579
|
.symbolSet(SymbolSet.SeaSubsurface)
|
|
359
580
|
.toString(); // "14153500000000000000"
|
|
360
581
|
|
|
582
|
+
// APP-6 unit with structural entity and modifier fields
|
|
583
|
+
new Sidc({ standard: Standard.App6, strict: true })
|
|
584
|
+
.identity(StandardIdentity.Friend)
|
|
585
|
+
.symbolSet(SymbolSet.LandUnit)
|
|
586
|
+
.entity("123456")
|
|
587
|
+
.modifier1("01")
|
|
588
|
+
.modifier2("09")
|
|
589
|
+
.toString(); // "14031000001234560109"
|
|
590
|
+
|
|
361
591
|
// APP-6 D configuration retains an explicitly selected compatible edition
|
|
362
592
|
new Sidc({ standard: Standard.App6, strict: true })
|
|
363
593
|
.version(Version.App6D)
|
|
@@ -370,20 +600,25 @@ new Sidc({ standard: Standard.App6, strict: true })
|
|
|
370
600
|
|
|
371
601
|
```bash
|
|
372
602
|
npm install
|
|
373
|
-
npm test
|
|
603
|
+
npm test # compiles with tsc, then runs node --test against dist/
|
|
374
604
|
npm run build
|
|
605
|
+
npm run lint # eslint
|
|
606
|
+
npm run format:check # prettier
|
|
607
|
+
npm run generate:catalogs # regenerate src/catalogs.generated.ts from milsymbol
|
|
375
608
|
```
|
|
376
609
|
|
|
610
|
+
CI runs the test suite on Node 18/20/22/24, plus lint, formatting, markdownlint,
|
|
611
|
+
coverage, and a check that the generated catalog is current.
|
|
612
|
+
|
|
377
613
|
Test coverage includes per-field offset encoding for every enum member,
|
|
378
|
-
defaults, immutability, setter validation errors,
|
|
379
|
-
both warn and strict modes, raw-code escape hatches,
|
|
380
|
-
hierarchy.
|
|
614
|
+
defaults, immutability, setter validation errors, extended-field offsets,
|
|
615
|
+
all combination rules in both warn and strict modes, raw-code escape hatches,
|
|
616
|
+
and error class hierarchy.
|
|
381
617
|
|
|
382
618
|
## Roadmap
|
|
383
619
|
|
|
384
|
-
-
|
|
385
|
-
|
|
386
|
-
- Parsing/decoding SIDC strings back into structured fields.
|
|
620
|
+
- Semantic entity and modifier names, layered on the membership catalog.
|
|
621
|
+
- Official positions 21–30 / Set C extension data.
|
|
387
622
|
|
|
388
623
|
## License
|
|
389
624
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional membership catalogs derived from milsymbol's numeric symbol data.
|
|
3
|
+
*
|
|
4
|
+
* Import from the `milsymbol-sidc/catalogs` subpath. This module is deliberately
|
|
5
|
+
* **not** part of the main entry point, so bundlers that only use the builder
|
|
6
|
+
* never include the catalog data.
|
|
7
|
+
*
|
|
8
|
+
* These catalogs answer "which codes does milsymbol register for this symbol
|
|
9
|
+
* set?". They intentionally carry no semantic names, and they are never
|
|
10
|
+
* consulted by `Sidc.toString()` - raw entity and modifier values continue to
|
|
11
|
+
* encode without recognition warnings.
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { isKnownEntityCode } from "milsymbol-sidc/catalogs";
|
|
15
|
+
*
|
|
16
|
+
* isKnownEntityCode("10", "121100"); // true for land units
|
|
17
|
+
* isKnownEntityCode("10", "999999"); // false
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
import { CATALOG_SOURCE } from "./catalogs.generated.js";
|
|
21
|
+
export { CATALOG_SOURCE };
|
|
22
|
+
export type CatalogSource = typeof CATALOG_SOURCE;
|
|
23
|
+
/** Every symbol set the catalog covers, sorted ascending. */
|
|
24
|
+
export declare function catalogSymbolSets(): readonly string[];
|
|
25
|
+
/** `true` when any catalog data exists for the symbol set. */
|
|
26
|
+
export declare function hasCatalog(symbolSet: string): boolean;
|
|
27
|
+
/** Six-digit entity codes milsymbol registers for a symbol set. */
|
|
28
|
+
export declare function entityCodes(symbolSet: string): readonly string[];
|
|
29
|
+
/** `true` when the entity code is registered for the symbol set. */
|
|
30
|
+
export declare function isKnownEntityCode(symbolSet: string, entity: string): boolean;
|
|
31
|
+
/** Two-digit modifier 1 codes milsymbol registers for a symbol set. */
|
|
32
|
+
export declare function modifier1Codes(symbolSet: string): readonly string[];
|
|
33
|
+
/** `true` when modifier 1 is registered for the symbol set. */
|
|
34
|
+
export declare function isKnownModifier1Code(symbolSet: string, modifier: string): boolean;
|
|
35
|
+
/** Two-digit modifier 2 codes milsymbol registers for a symbol set. */
|
|
36
|
+
export declare function modifier2Codes(symbolSet: string): readonly string[];
|
|
37
|
+
/** `true` when modifier 2 is registered for the symbol set. */
|
|
38
|
+
export declare function isKnownModifier2Code(symbolSet: string, modifier: string): boolean;
|
|
39
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,cAAc,EAIf,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,MAAM,MAAM,aAAa,GAAG,OAAO,cAAc,CAAC;AAiBlD,6DAA6D;AAC7D,wBAAgB,iBAAiB,IAAI,SAAS,MAAM,EAAE,CAErD;AAED,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAEhE;AAED,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5E;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAEnE;AAED,+DAA+D;AAC/D,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAET;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAEnE;AAED,+DAA+D;AAC/D,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAET"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional membership catalogs derived from milsymbol's numeric symbol data.
|
|
3
|
+
*
|
|
4
|
+
* Import from the `milsymbol-sidc/catalogs` subpath. This module is deliberately
|
|
5
|
+
* **not** part of the main entry point, so bundlers that only use the builder
|
|
6
|
+
* never include the catalog data.
|
|
7
|
+
*
|
|
8
|
+
* These catalogs answer "which codes does milsymbol register for this symbol
|
|
9
|
+
* set?". They intentionally carry no semantic names, and they are never
|
|
10
|
+
* consulted by `Sidc.toString()` - raw entity and modifier values continue to
|
|
11
|
+
* encode without recognition warnings.
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { isKnownEntityCode } from "milsymbol-sidc/catalogs";
|
|
15
|
+
*
|
|
16
|
+
* isKnownEntityCode("10", "121100"); // true for land units
|
|
17
|
+
* isKnownEntityCode("10", "999999"); // false
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
import { CATALOG_SOURCE, ENTITY_CODES, MODIFIER_1_CODES, MODIFIER_2_CODES, } from "./catalogs.generated.js";
|
|
21
|
+
export { CATALOG_SOURCE };
|
|
22
|
+
const EMPTY = Object.freeze([]);
|
|
23
|
+
const SYMBOL_SETS = new Set([
|
|
24
|
+
...Object.keys(ENTITY_CODES),
|
|
25
|
+
...Object.keys(MODIFIER_1_CODES),
|
|
26
|
+
...Object.keys(MODIFIER_2_CODES),
|
|
27
|
+
]);
|
|
28
|
+
function codesFor(table, symbolSet) {
|
|
29
|
+
return table[symbolSet] ?? EMPTY;
|
|
30
|
+
}
|
|
31
|
+
/** Every symbol set the catalog covers, sorted ascending. */
|
|
32
|
+
export function catalogSymbolSets() {
|
|
33
|
+
return Object.freeze([...SYMBOL_SETS].sort());
|
|
34
|
+
}
|
|
35
|
+
/** `true` when any catalog data exists for the symbol set. */
|
|
36
|
+
export function hasCatalog(symbolSet) {
|
|
37
|
+
return SYMBOL_SETS.has(symbolSet);
|
|
38
|
+
}
|
|
39
|
+
/** Six-digit entity codes milsymbol registers for a symbol set. */
|
|
40
|
+
export function entityCodes(symbolSet) {
|
|
41
|
+
return codesFor(ENTITY_CODES, symbolSet);
|
|
42
|
+
}
|
|
43
|
+
/** `true` when the entity code is registered for the symbol set. */
|
|
44
|
+
export function isKnownEntityCode(symbolSet, entity) {
|
|
45
|
+
return entityCodes(symbolSet).includes(entity);
|
|
46
|
+
}
|
|
47
|
+
/** Two-digit modifier 1 codes milsymbol registers for a symbol set. */
|
|
48
|
+
export function modifier1Codes(symbolSet) {
|
|
49
|
+
return codesFor(MODIFIER_1_CODES, symbolSet);
|
|
50
|
+
}
|
|
51
|
+
/** `true` when modifier 1 is registered for the symbol set. */
|
|
52
|
+
export function isKnownModifier1Code(symbolSet, modifier) {
|
|
53
|
+
return modifier1Codes(symbolSet).includes(modifier);
|
|
54
|
+
}
|
|
55
|
+
/** Two-digit modifier 2 codes milsymbol registers for a symbol set. */
|
|
56
|
+
export function modifier2Codes(symbolSet) {
|
|
57
|
+
return codesFor(MODIFIER_2_CODES, symbolSet);
|
|
58
|
+
}
|
|
59
|
+
/** `true` when modifier 2 is registered for the symbol set. */
|
|
60
|
+
export function isKnownModifier2Code(symbolSet, modifier) {
|
|
61
|
+
return modifier2Codes(symbolSet).includes(modifier);
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,CAAC;AAG1B,MAAM,KAAK,GAAsB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEnD,MAAM,WAAW,GAAwB,IAAI,GAAG,CAAC;IAC/C,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;IAC5B,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC;IAChC,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC;CACjC,CAAC,CAAC;AAEH,SAAS,QAAQ,CACf,KAAkD,EAClD,SAAiB;IAEjB,OAAO,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC;AACnC,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,iBAAiB;IAC/B,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,OAAO,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,WAAW,CAAC,SAAiB;IAC3C,OAAO,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;AAC3C,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAE,MAAc;IACjE,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACjD,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,QAAQ,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;AAC/C,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,oBAAoB,CAClC,SAAiB,EACjB,QAAgB;IAEhB,OAAO,cAAc,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACtD,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,QAAQ,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;AAC/C,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,oBAAoB,CAClC,SAAiB,EACjB,QAAgB;IAEhB,OAAO,cAAc,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED FILE - do not edit by hand.
|
|
3
|
+
*
|
|
4
|
+
* Membership catalog derived from milsymbol 3.0.4 (MIT),
|
|
5
|
+
* Copyright (c) 2017 Måns Beckman - https://www.spatialillusions.com
|
|
6
|
+
*
|
|
7
|
+
* Regenerate with `npm run generate:catalogs`.
|
|
8
|
+
*/
|
|
9
|
+
/** Package and version the catalog was generated from. */
|
|
10
|
+
export declare const CATALOG_SOURCE: {
|
|
11
|
+
readonly name: "milsymbol";
|
|
12
|
+
readonly version: "3.0.4";
|
|
13
|
+
};
|
|
14
|
+
/** Six-digit entity codes milsymbol registers, keyed by symbol set. */
|
|
15
|
+
export declare const ENTITY_CODES: Readonly<Record<string, readonly string[]>>;
|
|
16
|
+
/** Two-digit modifier 1 codes milsymbol registers, keyed by symbol set. */
|
|
17
|
+
export declare const MODIFIER_1_CODES: Readonly<Record<string, readonly string[]>>;
|
|
18
|
+
/** Two-digit modifier 2 codes milsymbol registers, keyed by symbol set. */
|
|
19
|
+
export declare const MODIFIER_2_CODES: Readonly<Record<string, readonly string[]>>;
|
|
20
|
+
//# sourceMappingURL=catalogs.generated.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalogs.generated.d.ts","sourceRoot":"","sources":["../../src/catalogs.generated.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,0DAA0D;AAC1D,eAAO,MAAM,cAAc;;;CAGjB,CAAC;AAEX,uEAAuE;AACvE,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CA0sCjE,CAAC;AAEL,2EAA2E;AAC3E,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CA0uBrE,CAAC;AAEL,2EAA2E;AAC3E,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CA4PrE,CAAC"}
|