milsymbol-sidc 0.3.0 → 0.5.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 +320 -157
- package/dist/src/catalog.d.ts +47 -0
- package/dist/src/catalog.d.ts.map +1 -0
- package/dist/src/catalog.js +81 -0
- package/dist/src/catalog.js.map +1 -0
- package/dist/src/catalogs.generated.d.ts +24 -0
- package/dist/src/catalogs.generated.d.ts.map +1 -0
- package/dist/src/catalogs.generated.js +4187 -0
- package/dist/src/catalogs.generated.js.map +1 -0
- package/dist/src/enums.d.ts +15 -0
- package/dist/src/enums.d.ts.map +1 -1
- package/dist/src/enums.js +14 -0
- 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 +92 -12
- package/dist/src/sidc.d.ts.map +1 -1
- package/dist/src/sidc.js +196 -25
- package/dist/src/sidc.js.map +1 -1
- package/dist/src/validate.d.ts +40 -13
- package/dist/src/validate.d.ts.map +1 -1
- package/dist/src/validate.js +104 -22
- package/dist/src/validate.js.map +1 -1
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# milsymbol-sidc
|
|
2
2
|
|
|
3
|
+
[](https://github.com/psylsph/milsymbol-sidc/actions/workflows/ci.yml)
|
|
3
4
|
[](https://www.npmjs.com/package/milsymbol-sidc)
|
|
4
5
|
[](https://www.npmjs.com/package/milsymbol-sidc)
|
|
5
6
|
[](LICENSE)
|
|
6
7
|
[](https://www.typescriptlang.org/)
|
|
7
8
|
|
|
8
|
-
A fluent TypeScript builder for **
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
A fluent TypeScript builder for **numeric SIDC strings** — 20 characters by
|
|
10
|
+
default, with opt-in positions 21–23 (extended modifiers and frame shape) for
|
|
11
|
+
[MIL-STD-2525E](https://en.wikipedia.org/wiki/MIL-STD-2525) and
|
|
12
|
+
[APP-6](https://en.wikipedia.org/wiki/NATO_Joint_Military_Symbology) symbols —
|
|
13
|
+
made for constructing symbols with the
|
|
12
14
|
[milsymbol](https://github.com/spatialillusions/milsymbol) library.
|
|
13
15
|
|
|
14
16
|
```ts
|
|
@@ -29,14 +31,16 @@ new ms.Symbol(sidc).asSVG(); // friendly land unit icon
|
|
|
29
31
|
- **Validated output** — invalid values throw; inconsistent combinations warn
|
|
30
32
|
(or throw in `strict` mode), using the same rules milsymbol applies when it
|
|
31
33
|
parses a SIDC.
|
|
32
|
-
- **milsymbol-ready** — every generated
|
|
34
|
+
- **milsymbol-ready** — every generated string is accepted by
|
|
33
35
|
milsymbol's numeric parser. Full rendering depends on the entity and
|
|
34
36
|
modifier codes you supply, exactly as it does for any raw SIDC.
|
|
35
37
|
|
|
36
38
|
> **Coverage:** complete structural encoding for positions 1–20 of the numeric
|
|
37
|
-
> SIDC
|
|
38
|
-
>
|
|
39
|
-
>
|
|
39
|
+
> SIDC, plus opt-in positions 21–23 (extended modifiers and frame shape) that
|
|
40
|
+
> milsymbol consumes for 2525E/APP-6 E symbols. Positions 8–10 have named
|
|
41
|
+
> universal codes; positions 11–20 accept validated raw entity and modifier
|
|
42
|
+
> codes. A membership-only code catalog ships behind the `milsymbol-sidc/catalogs`
|
|
43
|
+
> subpath; semantic names remain future work.
|
|
40
44
|
|
|
41
45
|
## Installation
|
|
42
46
|
|
|
@@ -77,11 +81,11 @@ import {
|
|
|
77
81
|
|
|
78
82
|
// A hostile planned air missile track under MIL-STD-2525E:
|
|
79
83
|
const sidc = new Sidc()
|
|
80
|
-
.version(Version.MilStd2525E)
|
|
81
|
-
.context(Context.Reality)
|
|
84
|
+
.version(Version.MilStd2525E) // pos 1-2 → "13"
|
|
85
|
+
.context(Context.Reality) // pos 3 → "0"
|
|
82
86
|
.identity(StandardIdentity.SuspectJoker) // pos 4 → "5"
|
|
83
|
-
.symbolSet(SymbolSet.AirMissile)
|
|
84
|
-
.status(Status.Planned)
|
|
87
|
+
.symbolSet(SymbolSet.AirMissile) // pos 5-6 → "02"
|
|
88
|
+
.status(Status.Planned) // pos 7 → "1"
|
|
85
89
|
.toString();
|
|
86
90
|
|
|
87
91
|
console.log(sidc); // "13050210000000000000"
|
|
@@ -103,32 +107,43 @@ const hostile = base.identity(StandardIdentity.SuspectJoker).toString();
|
|
|
103
107
|
## Anatomy of the generated SIDC
|
|
104
108
|
|
|
105
109
|
```text
|
|
106
|
-
13 0 3 10 0 2 16 123456 78 90
|
|
107
|
-
│ │ │ │ │ │ │ │ │ │
|
|
108
|
-
│ │ │ │ │ │ │ │ │ └
|
|
109
|
-
│ │ │ │ │ │ │ │
|
|
110
|
-
│ │ │ │ │ │ │
|
|
111
|
-
│ │ │ │ │ │
|
|
112
|
-
│ │ │ │ │
|
|
113
|
-
│ │ │ │
|
|
114
|
-
│ │ │
|
|
115
|
-
│ │
|
|
116
|
-
│
|
|
117
|
-
|
|
110
|
+
13 0 3 10 0 2 16 123456 78 90 0 0 A
|
|
111
|
+
│ │ │ │ │ │ │ │ │ │ │ │ │
|
|
112
|
+
│ │ │ │ │ │ │ │ │ │ │ │ └ frame shape (23) — `A` = no frame
|
|
113
|
+
│ │ │ │ │ │ │ │ │ │ │ └ │ modifier 2 extension (22)
|
|
114
|
+
│ │ │ │ │ │ │ │ │ │ └ │ │ modifier 1 extension (21)
|
|
115
|
+
│ │ │ │ │ │ │ │ │ └ │ │ │ modifier 2 (19–20)
|
|
116
|
+
│ │ │ │ │ │ │ │ └ │ │ │ │ modifier 1 (17–18)
|
|
117
|
+
│ │ │ │ │ │ │ └ │ │ │ │ │ entity code (11–16)
|
|
118
|
+
│ │ │ │ │ │ └ │ │ │ │ │ │ amplifier (9–10)
|
|
119
|
+
│ │ │ │ │ └ │ │ │ │ │ │ │ HQ/task force/feint-dummy (8)
|
|
120
|
+
│ │ │ │ └ │ │ │ │ │ │ │ │ status (7)
|
|
121
|
+
│ │ │ └ │ │ │ │ │ │ │ │ │ symbol set (5–6)
|
|
122
|
+
│ │ └ │ │ │ │ │ │ │ │ │ │ standard identity (4)
|
|
123
|
+
│ └ │ │ │ │ │ │ │ │ │ │ │ context (3)
|
|
124
|
+
└ │ │ │ │ │ │ │ │ │ │ │ │ version / edition (1–2)
|
|
118
125
|
```
|
|
119
126
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
|
|
|
131
|
-
|
|
|
127
|
+
Positions 21–23 are emitted only when an extension field is set explicitly;
|
|
128
|
+
otherwise `toString()` produces the classic 20-character SIDC.
|
|
129
|
+
|
|
130
|
+
| Position | Field | API |
|
|
131
|
+
| -------- | ------------------------- | ------------------------------------------------------------ |
|
|
132
|
+
| 1–2 | Version / edition | `Version`, `version()` |
|
|
133
|
+
| 3 | Context | `Context`, `context()` |
|
|
134
|
+
| 4 | Standard identity | `StandardIdentity`, `identity()` |
|
|
135
|
+
| 5–6 | Symbol set | `SymbolSet`, `symbolSet()` |
|
|
136
|
+
| 7 | Status / condition | `Status`, `status()` |
|
|
137
|
+
| 8 | HQ/task force/feint-dummy | `HqTaskForceDummy`, `hqTaskForceDummy()` |
|
|
138
|
+
| 9–10 | Amplifier | `Amplifier`, `amplifier()` |
|
|
139
|
+
| 11–16 | Entity code | `entity()` — six raw digits |
|
|
140
|
+
| 17–18 | Modifier 1 | `modifier1()` — two raw digits, or `extendedModifier1()` |
|
|
141
|
+
| 19–20 | Modifier 2 | `modifier2()` — two raw digits, or `extendedModifier2()` |
|
|
142
|
+
| 21 | Modifier 1 extension | `extendedModifier1()` — hundreds digit of a three-digit code |
|
|
143
|
+
| 22 | Modifier 2 extension | `extendedModifier2()` — hundreds digit of a three-digit code |
|
|
144
|
+
| 23 | Frame shape | `frameShape()` — `0`–`9`, or `A` (no frame) |
|
|
145
|
+
| 17–18 | Modifier 1 | `modifier1()` — two raw digits |
|
|
146
|
+
| 19–20 | Modifier 2 | `modifier2()` — two raw digits |
|
|
132
147
|
|
|
133
148
|
## API
|
|
134
149
|
|
|
@@ -138,29 +153,42 @@ Creates a builder preconfigured to 2525E / Reality / Unknown / Unknown set /
|
|
|
138
153
|
Present. This remains the default for backward compatibility; configure
|
|
139
154
|
`Standard.App6` to default to APP-6 E instead.
|
|
140
155
|
|
|
141
|
-
| Option
|
|
142
|
-
|
|
|
143
|
-
| `strict`
|
|
144
|
-
| `standard`
|
|
156
|
+
| Option | Type | Default | Description |
|
|
157
|
+
| ----------- | -------------------------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
158
|
+
| `strict` | `boolean` | `false` | Throw on invalid field combinations during `toString()` instead of warning. Invalid values always throw immediately regardless of this flag. |
|
|
159
|
+
| `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. |
|
|
160
|
+
| `onWarning` | `(problem: SidcProblem) => void` | `console.warn` | Receive non-fatal problems instead of writing to the console. `strict: true` still throws instead of reporting. |
|
|
145
161
|
|
|
146
162
|
### Methods
|
|
147
163
|
|
|
148
164
|
All setters validate their argument and return a new immutable `Sidc`.
|
|
149
165
|
|
|
150
|
-
| Method
|
|
151
|
-
|
|
|
152
|
-
| `standard(s)`
|
|
153
|
-
| `version(v)`
|
|
154
|
-
| `context(c)`
|
|
155
|
-
| `identity(i)`
|
|
156
|
-
| `symbolSet(s)`
|
|
157
|
-
| `status(s)`
|
|
158
|
-
| `hqTaskForceDummy(v)`
|
|
159
|
-
| `amplifier(v)`
|
|
160
|
-
| `entity(v)`
|
|
161
|
-
| `modifier1(v)`
|
|
162
|
-
| `modifier2(v)`
|
|
163
|
-
| `
|
|
166
|
+
| Method | Field | Accepts |
|
|
167
|
+
| ---------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
168
|
+
| `standard(s)` | Version default + validation rules | A `Standard` constant. It retains a compatible current version; otherwise it selects that family's latest edition. |
|
|
169
|
+
| `version(v)` | Positions 1–2 | A `Version` constant or any two-digit string (escape hatch for future editions) |
|
|
170
|
+
| `context(c)` | Position 3 | A `Context` constant |
|
|
171
|
+
| `identity(i)` | Position 4 | A `StandardIdentity` constant |
|
|
172
|
+
| `symbolSet(s)` | Positions 5–6 | A `SymbolSet` constant or any two-digit string |
|
|
173
|
+
| `status(s)` | Position 7 | A `Status` constant |
|
|
174
|
+
| `hqTaskForceDummy(v)` | Position 8 | An `HqTaskForceDummy` constant |
|
|
175
|
+
| `amplifier(v)` | Positions 9–10 | An `Amplifier` constant |
|
|
176
|
+
| `entity(v)` | Positions 11–16 | Any six-digit string; symbol-set-specific catalogs are not included |
|
|
177
|
+
| `modifier1(v)` | Positions 17–18 | Any two-digit string; resets the modifier-1 extension digit to `0` when a tail exists |
|
|
178
|
+
| `modifier2(v)` | Positions 19–20 | Any two-digit string; resets the modifier-2 extension digit to `0` when a tail exists |
|
|
179
|
+
| `extendedModifier1(v)` | Positions 17–18 + 21 | Any three-digit string; hundreds digit lands at position 21 |
|
|
180
|
+
| `extendedModifier2(v)` | Positions 19–20 + 22 | Any three-digit string; hundreds digit lands at position 22 |
|
|
181
|
+
| `frameShape(v)` | Position 23 | A `FrameShape` constant |
|
|
182
|
+
| `withoutExtension()` | Positions 21–23 | Drops the tail, keeping the two-digit modifier slots (may change rendering) |
|
|
183
|
+
| `toString()` | — | Validates combinations and renders the 20- or 23-character SIDC |
|
|
184
|
+
| `problems()` | — | Structured list of non-fatal problems; never throws |
|
|
185
|
+
| `isValid()` | — | `true` when `problems()` is empty |
|
|
186
|
+
| `with(fields)` | — | Applies a partial field record immutably; validates like the setters |
|
|
187
|
+
| `clone()` | — | Copies the fields into an independent builder |
|
|
188
|
+
| `equals(other)` | — | Compares encoded fields, ignoring `strict` and `standard` |
|
|
189
|
+
| `toObject()` / `toJSON()` | — | Plain, serializable snapshot of every encoded field |
|
|
190
|
+
| `Sidc.parse(s, options?)` | — | Parses a 20- or 23-character numeric SIDC; throws when invalid |
|
|
191
|
+
| `Sidc.tryParse(s, options?)` | — | Parses a SIDC or returns `undefined` |
|
|
164
192
|
|
|
165
193
|
### Enum reference
|
|
166
194
|
|
|
@@ -169,24 +197,24 @@ All setters validate their argument and return a new immutable `Sidc`.
|
|
|
169
197
|
Values match milsymbol's `standard` option and `ms.setStandard()` API, so the
|
|
170
198
|
same constant can configure both libraries.
|
|
171
199
|
|
|
172
|
-
| Constant
|
|
173
|
-
|
|
|
200
|
+
| Constant | Value | Standard family |
|
|
201
|
+
| ------------ | -------- | --------------------------------------------------- |
|
|
174
202
|
| `MilStd2525` | `"2525"` | US MIL-STD-2525 (**default behavior when omitted**) |
|
|
175
|
-
| `App6`
|
|
203
|
+
| `App6` | `"APP6"` | NATO APP-6 |
|
|
176
204
|
|
|
177
205
|
#### `HqTaskForceDummy`
|
|
178
206
|
|
|
179
207
|
Position 8 values identify headquarters, task force, and feint/dummy variants.
|
|
180
208
|
|
|
181
|
-
| Constant
|
|
182
|
-
|
|
|
183
|
-
| `None`
|
|
184
|
-
| `FeintDummy`
|
|
185
|
-
| `Headquarters`
|
|
186
|
-
| `FeintDummyHeadquarters`
|
|
187
|
-
| `TaskForce`
|
|
188
|
-
| `FeintDummyTaskForce`
|
|
189
|
-
| `TaskForceHeadquarters`
|
|
209
|
+
| Constant | Code | Meaning |
|
|
210
|
+
| --------------------------------- | ----- | ----------------------------------- |
|
|
211
|
+
| `None` | `"0"` | None / not applicable |
|
|
212
|
+
| `FeintDummy` | `"1"` | Feint/dummy |
|
|
213
|
+
| `Headquarters` | `"2"` | Headquarters |
|
|
214
|
+
| `FeintDummyHeadquarters` | `"3"` | Feint/dummy headquarters |
|
|
215
|
+
| `TaskForce` | `"4"` | Task force |
|
|
216
|
+
| `FeintDummyTaskForce` | `"5"` | Feint/dummy task force |
|
|
217
|
+
| `TaskForceHeadquarters` | `"6"` | Task-force headquarters |
|
|
190
218
|
| `FeintDummyTaskForceHeadquarters` | `"7"` | Feint/dummy task-force headquarters |
|
|
191
219
|
|
|
192
220
|
#### `Amplifier`
|
|
@@ -194,113 +222,134 @@ Position 8 values identify headquarters, task force, and feint/dummy variants.
|
|
|
194
222
|
Position 9–10 values identify echelon, mobility, leadership, or auxiliary
|
|
195
223
|
amplifiers. `None` writes the zero/no-amplifier code `"00"`.
|
|
196
224
|
|
|
197
|
-
| Constant
|
|
198
|
-
|
|
|
199
|
-
| `None`
|
|
200
|
-
| `TeamCrew`
|
|
201
|
-
| `Squad`
|
|
202
|
-
| `Section`
|
|
203
|
-
| `PlatoonDetachment`
|
|
204
|
-
| `CompanyBatteryTroop`
|
|
205
|
-
| `BattalionSquadron`
|
|
206
|
-
| `RegimentGroup`
|
|
207
|
-
| `Brigade`
|
|
208
|
-
| `Division`
|
|
209
|
-
| `CorpsMef`
|
|
210
|
-
| `Army`
|
|
211
|
-
| `ArmyGroupFront`
|
|
212
|
-
| `RegionTheater`
|
|
213
|
-
| `Command`
|
|
214
|
-
| `WheeledLimitedCrossCountry` | `"31"` | Wheeled, limited cross-country
|
|
215
|
-
| `WheeledCrossCountry`
|
|
216
|
-
| `Tracked`
|
|
217
|
-
| `WheeledTrackedCombination`
|
|
218
|
-
| `Towed`
|
|
219
|
-
| `Rail`
|
|
220
|
-
| `PackAnimals`
|
|
221
|
-
| `OverSnowPrimeMover`
|
|
222
|
-
| `Sled`
|
|
223
|
-
| `Barge`
|
|
224
|
-
| `Amphibious`
|
|
225
|
-
| `ShortTowedArray`
|
|
226
|
-
| `LongTowedArray`
|
|
227
|
-
| `LeaderIndividual`
|
|
228
|
-
| `DeputyIndividual`
|
|
225
|
+
| Constant | Code | Meaning |
|
|
226
|
+
| ---------------------------- | ------ | ------------------------------- |
|
|
227
|
+
| `None` | `"00"` | None / not specified |
|
|
228
|
+
| `TeamCrew` | `"11"` | Team/crew |
|
|
229
|
+
| `Squad` | `"12"` | Squad |
|
|
230
|
+
| `Section` | `"13"` | Section |
|
|
231
|
+
| `PlatoonDetachment` | `"14"` | Platoon/detachment |
|
|
232
|
+
| `CompanyBatteryTroop` | `"15"` | Company/battery/troop |
|
|
233
|
+
| `BattalionSquadron` | `"16"` | Battalion/squadron |
|
|
234
|
+
| `RegimentGroup` | `"17"` | Regiment/group |
|
|
235
|
+
| `Brigade` | `"18"` | Brigade |
|
|
236
|
+
| `Division` | `"21"` | Division |
|
|
237
|
+
| `CorpsMef` | `"22"` | Corps/MEF |
|
|
238
|
+
| `Army` | `"23"` | Army |
|
|
239
|
+
| `ArmyGroupFront` | `"24"` | Army group/front |
|
|
240
|
+
| `RegionTheater` | `"25"` | Region/theater |
|
|
241
|
+
| `Command` | `"26"` | Command |
|
|
242
|
+
| `WheeledLimitedCrossCountry` | `"31"` | Wheeled, limited cross-country |
|
|
243
|
+
| `WheeledCrossCountry` | `"32"` | Wheeled, cross-country |
|
|
244
|
+
| `Tracked` | `"33"` | Tracked |
|
|
245
|
+
| `WheeledTrackedCombination` | `"34"` | Wheeled and tracked combination |
|
|
246
|
+
| `Towed` | `"35"` | Towed |
|
|
247
|
+
| `Rail` | `"36"` | Rail |
|
|
248
|
+
| `PackAnimals` | `"37"` | Pack animals |
|
|
249
|
+
| `OverSnowPrimeMover` | `"41"` | Over snow, prime mover |
|
|
250
|
+
| `Sled` | `"42"` | Sled |
|
|
251
|
+
| `Barge` | `"51"` | Barge |
|
|
252
|
+
| `Amphibious` | `"52"` | Amphibious |
|
|
253
|
+
| `ShortTowedArray` | `"61"` | Short towed array |
|
|
254
|
+
| `LongTowedArray` | `"62"` | Long towed array |
|
|
255
|
+
| `LeaderIndividual` | `"71"` | Leader individual |
|
|
256
|
+
| `DeputyIndividual` | `"72"` | Deputy individual |
|
|
229
257
|
|
|
230
258
|
Entity and modifier setters intentionally accept raw digit strings so callers
|
|
231
259
|
can use codes specific to their symbol set and edition. They validate width and
|
|
232
260
|
ASCII digits but do not validate catalog membership.
|
|
233
261
|
|
|
262
|
+
#### `FrameShape`
|
|
263
|
+
|
|
264
|
+
Position 23, consumed by milsymbol for E-edition shape overrides (`1`–`9` are
|
|
265
|
+
ignored upstream unless the version is E; `A` applies on any edition).
|
|
266
|
+
Selectors are named after the frame they select; `NoFrame` (`A`) is the only
|
|
267
|
+
letter-valued code in the SIDC.
|
|
268
|
+
|
|
269
|
+
| Constant | Code | Meaning |
|
|
270
|
+
| -------------------------- | ----- | -------------------------------------------------- |
|
|
271
|
+
| `Default` | `"0"` | No override (**implied when no extension is set**) |
|
|
272
|
+
| `Space` | `"1"` | Space frame |
|
|
273
|
+
| `Air` | `"2"` | Air frame |
|
|
274
|
+
| `LandUnit` | `"3"` | Land unit frame |
|
|
275
|
+
| `LandEquipmentSeaSurface` | `"4"` | Land equipment / sea surface frame |
|
|
276
|
+
| `Installation` | `"5"` | Installation frame |
|
|
277
|
+
| `LandDismountedIndividual` | `"6"` | Dismounted individual frame |
|
|
278
|
+
| `SeaSubsurface` | `"7"` | Sea subsurface frame |
|
|
279
|
+
| `ActivityEvent` | `"8"` | Activity / event frame |
|
|
280
|
+
| `Cyberspace` | `"9"` | Cyberspace frame |
|
|
281
|
+
| `NoFrame` | `"A"` | Suppress the frame entirely |
|
|
282
|
+
|
|
234
283
|
#### `Version`
|
|
235
284
|
|
|
236
|
-
| Constant
|
|
237
|
-
|
|
|
238
|
-
| `MilStd2525D` | `"10"` | MIL-STD-2525D
|
|
239
|
-
| `App6D`
|
|
285
|
+
| Constant | Code | Standard |
|
|
286
|
+
| ------------- | ------ | --------------------------- |
|
|
287
|
+
| `MilStd2525D` | `"10"` | MIL-STD-2525D |
|
|
288
|
+
| `App6D` | `"11"` | APP-6 D |
|
|
240
289
|
| `MilStd2525E` | `"13"` | MIL-STD-2525E (**default**) |
|
|
241
|
-
| `App6E`
|
|
290
|
+
| `App6E` | `"14"` | APP-6 E |
|
|
242
291
|
|
|
243
292
|
#### `Context`
|
|
244
293
|
|
|
245
|
-
| Constant
|
|
246
|
-
|
|
|
247
|
-
| `Reality`
|
|
248
|
-
| `Exercise`
|
|
249
|
-
| `Simulation` | `"2"` | Simulation
|
|
294
|
+
| Constant | Code | Meaning |
|
|
295
|
+
| ------------ | ----- | ---------------------------------- |
|
|
296
|
+
| `Reality` | `"0"` | Real-world operation (**default**) |
|
|
297
|
+
| `Exercise` | `"1"` | Training/exercise |
|
|
298
|
+
| `Simulation` | `"2"` | Simulation |
|
|
250
299
|
|
|
251
300
|
#### `StandardIdentity`
|
|
252
301
|
|
|
253
|
-
| Constant
|
|
254
|
-
|
|
|
255
|
-
| `Pending`
|
|
256
|
-
| `Unknown`
|
|
257
|
-
| `AssumedFriend` | `"2"` | Blue frame, dashed
|
|
258
|
-
| `Friend`
|
|
259
|
-
| `Neutral`
|
|
260
|
-
| `SuspectJoker`
|
|
261
|
-
| `HostileFaker`
|
|
302
|
+
| Constant | Code | Frame drawn |
|
|
303
|
+
| --------------- | ----- | ------------------------------------------------------------------ |
|
|
304
|
+
| `Pending` | `"0"` | Unknown shape, dashed |
|
|
305
|
+
| `Unknown` | `"1"` | Yellow octagonal frame (**default**) |
|
|
306
|
+
| `AssumedFriend` | `"2"` | Blue frame, dashed |
|
|
307
|
+
| `Friend` | `"3"` | Blue frame |
|
|
308
|
+
| `Neutral` | `"4"` | Green frame |
|
|
309
|
+
| `SuspectJoker` | `"5"` | Red frame, dashed — **Suspect** in reality, **Joker** in exercises |
|
|
310
|
+
| `HostileFaker` | `"6"` | Red frame — **Hostile** in reality, **Faker** in exercises |
|
|
262
311
|
|
|
263
312
|
#### `SymbolSet`
|
|
264
313
|
|
|
265
314
|
Only sets that milsymbol can render are listed.
|
|
266
315
|
|
|
267
|
-
| Constant
|
|
268
|
-
|
|
|
269
|
-
| `Unknown`
|
|
270
|
-
| `Air`
|
|
271
|
-
| `AirMissile`
|
|
272
|
-
| `Space`
|
|
273
|
-
| `SpaceMissile`
|
|
274
|
-
| `LandUnit`
|
|
275
|
-
| `LandCivilianUnit`
|
|
276
|
-
| `LandEquipment`
|
|
277
|
-
| `Installation`
|
|
278
|
-
| `ControlMeasure`
|
|
279
|
-
| `LandDismountedIndividual`
|
|
280
|
-
| `SeaSurface`
|
|
281
|
-
| `SeaSubsurface`
|
|
282
|
-
| `MineWarfare`
|
|
283
|
-
| `Activity`
|
|
284
|
-
| `SignalsIntelligenceSpace`
|
|
285
|
-
| `SignalsIntelligenceAir`
|
|
286
|
-
| `SignalsIntelligenceLand`
|
|
287
|
-
| `SignalsIntelligenceSeaSurface` | `"53"` | SIGINT sea surface
|
|
288
|
-
| `SignalsIntelligenceSubsurface` | `"54"` | SIGINT subsurface
|
|
289
|
-
| `Cyberspace`
|
|
316
|
+
| Constant | Code | Domain |
|
|
317
|
+
| ------------------------------- | ------ | ------------------------------------ |
|
|
318
|
+
| `Unknown` | `"00"` | Unknown |
|
|
319
|
+
| `Air` | `"01"` | Air tracks |
|
|
320
|
+
| `AirMissile` | `"02"` | Air missiles |
|
|
321
|
+
| `Space` | `"05"` | Space |
|
|
322
|
+
| `SpaceMissile` | `"06"` | Space missiles |
|
|
323
|
+
| `LandUnit` | `"10"` | Land units |
|
|
324
|
+
| `LandCivilianUnit` | `"11"` | Land civilian units |
|
|
325
|
+
| `LandEquipment` | `"15"` | Land equipment |
|
|
326
|
+
| `Installation` | `"20"` | Installations |
|
|
327
|
+
| `ControlMeasure` | `"25"` | Tactical graphics / control measures |
|
|
328
|
+
| `LandDismountedIndividual` | `"27"` | Dismounted individuals |
|
|
329
|
+
| `SeaSurface` | `"30"` | Sea surface tracks |
|
|
330
|
+
| `SeaSubsurface` | `"35"` | Subsurface tracks |
|
|
331
|
+
| `MineWarfare` | `"36"` | Sea mines |
|
|
332
|
+
| `Activity` | `"40"` | Activities/events |
|
|
333
|
+
| `SignalsIntelligenceSpace` | `"50"` | SIGINT space |
|
|
334
|
+
| `SignalsIntelligenceAir` | `"51"` | SIGINT air |
|
|
335
|
+
| `SignalsIntelligenceLand` | `"52"` | SIGINT land |
|
|
336
|
+
| `SignalsIntelligenceSeaSurface` | `"53"` | SIGINT sea surface |
|
|
337
|
+
| `SignalsIntelligenceSubsurface` | `"54"` | SIGINT subsurface |
|
|
338
|
+
| `Cyberspace` | `"60"` | Cyberspace |
|
|
290
339
|
|
|
291
340
|
Codes `"12"` and `"39"` have no named constant but are recognized via the raw
|
|
292
341
|
string escape hatch.
|
|
293
342
|
|
|
294
343
|
#### `Status`
|
|
295
344
|
|
|
296
|
-
| Constant
|
|
297
|
-
|
|
|
298
|
-
| `Present`
|
|
299
|
-
| `Planned`
|
|
300
|
-
| `FullyCapable`
|
|
301
|
-
| `Damaged`
|
|
302
|
-
| `Destroyed`
|
|
303
|
-
| `FullToCapacity` | `"5"` | Condition bar: full to capacity
|
|
345
|
+
| Constant | Code | Meaning |
|
|
346
|
+
| ---------------- | ----- | ------------------------------------ |
|
|
347
|
+
| `Present` | `"0"` | Present / actual (**default**) |
|
|
348
|
+
| `Planned` | `"1"` | Planned / anticipated (dashed frame) |
|
|
349
|
+
| `FullyCapable` | `"2"` | Condition bar: fully capable |
|
|
350
|
+
| `Damaged` | `"3"` | Condition bar: damaged |
|
|
351
|
+
| `Destroyed` | `"4"` | Condition bar: destroyed |
|
|
352
|
+
| `FullToCapacity` | `"5"` | Condition bar: full to capacity |
|
|
304
353
|
|
|
305
354
|
## Validation and error handling
|
|
306
355
|
|
|
@@ -323,6 +372,12 @@ Active combination rules:
|
|
|
323
372
|
identity is pending/unknown.
|
|
324
373
|
- Symbol set 27 is unsupported in MIL-STD-2525D; symbol set 60 is unsupported
|
|
325
374
|
in APP-6 D.
|
|
375
|
+
- Non-default extension values (nonzero modifier extension digits or a frame
|
|
376
|
+
shape other than `Default`) are reported for D-edition versions `"10"`,
|
|
377
|
+
`"11"`, and `"12"`. This is the library's support policy, not a milsymbol
|
|
378
|
+
restriction: upstream consumes positions 21–22 and `A` on any edition, while
|
|
379
|
+
shape selectors `1`–`9` only take effect for E editions. Explicit all-zero
|
|
380
|
+
tails never warn.
|
|
326
381
|
- When a `Standard` is explicitly configured, official version codes from the
|
|
327
382
|
other standard family are reported.
|
|
328
383
|
- Raw version/symbol-set codes outside milsymbol's known tables are reported.
|
|
@@ -390,6 +445,87 @@ try {
|
|
|
390
445
|
Error classes: `SidcError` (base) → `SidcValidationError`,
|
|
391
446
|
`SidcCombinationError`.
|
|
392
447
|
|
|
448
|
+
### Reading and reporting problems
|
|
449
|
+
|
|
450
|
+
`console.warn` is only the default. Inspect problems without side effects with
|
|
451
|
+
`problems()` and `isValid()`, or route them anywhere with `onWarning`:
|
|
452
|
+
|
|
453
|
+
```ts
|
|
454
|
+
import { Sidc, SymbolSet, Status } from "milsymbol-sidc";
|
|
455
|
+
|
|
456
|
+
const sidc = new Sidc()
|
|
457
|
+
.symbolSet(SymbolSet.ControlMeasure)
|
|
458
|
+
.status(Status.Destroyed);
|
|
459
|
+
|
|
460
|
+
sidc.problems();
|
|
461
|
+
// [{ code: "condition-status-control-measure", message: "…" }]
|
|
462
|
+
sidc.isValid(); // false
|
|
463
|
+
|
|
464
|
+
new Sidc({ onWarning: (problem) => log.warn(problem.code) })
|
|
465
|
+
.symbolSet(SymbolSet.ControlMeasure)
|
|
466
|
+
.status(Status.Destroyed)
|
|
467
|
+
.toString(); // no console output; onWarning is called once
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
Every problem carries a stable `code` and the exact legacy warning `message`.
|
|
471
|
+
`problems()` never throws, even for builders created with `{ strict: true }`;
|
|
472
|
+
`toString()` still throws `SidcCombinationError` in strict mode.
|
|
473
|
+
|
|
474
|
+
## Parsing a SIDC
|
|
475
|
+
|
|
476
|
+
`Sidc.parse()` turns a 20- or 23-character numeric SIDC back into a builder so
|
|
477
|
+
you can
|
|
478
|
+
validate, edit, and re-render existing codes. `Sidc.tryParse()` returns
|
|
479
|
+
`undefined` instead of throwing.
|
|
480
|
+
|
|
481
|
+
```ts
|
|
482
|
+
import { Sidc } from "milsymbol-sidc";
|
|
483
|
+
|
|
484
|
+
const sidc = Sidc.parse("14031002161234560109");
|
|
485
|
+
sidc.toObject().entity; // "123456"
|
|
486
|
+
|
|
487
|
+
sidc.with({ modifier1: "02" }).toString(); // "14031002161234560209"
|
|
488
|
+
Sidc.tryParse("not-a-sidc"); // undefined
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
Round-tripping is guaranteed: `Sidc.parse(s).toString() === s` for any string
|
|
492
|
+
this library produces, including explicit zero tails (`…000` stays 23
|
|
493
|
+
characters, because tail presence is data). A 20-character SIDC and the same
|
|
494
|
+
code padded with a zero tail render identically in milsymbol but compare as
|
|
495
|
+
unequal builders, mirroring the different strings. Only the 20- and
|
|
496
|
+
23-character numeric forms are supported; letter-based SIDCs, 21/22-character
|
|
497
|
+
input, and positions 24–30 are not.
|
|
498
|
+
|
|
499
|
+
## Catalogs (optional)
|
|
500
|
+
|
|
501
|
+
The `milsymbol-sidc/catalogs` subpath exposes a membership catalog generated from
|
|
502
|
+
milsymbol's numeric symbol data: which entity and modifier codes milsymbol
|
|
503
|
+
registers for each symbol set. It is a separate entry point, so the core builder
|
|
504
|
+
stays data-free unless you import it.
|
|
505
|
+
|
|
506
|
+
```ts
|
|
507
|
+
import { entityCodes, isKnownEntityCode } from "milsymbol-sidc/catalogs";
|
|
508
|
+
|
|
509
|
+
isKnownEntityCode("10", "121100"); // true — a registered land-unit entity
|
|
510
|
+
isKnownEntityCode("10", "999999"); // false
|
|
511
|
+
entityCodes("10").length; // number of registered land-unit codes
|
|
512
|
+
|
|
513
|
+
// Three-digit (extended) modifiers are exposed separately:
|
|
514
|
+
import {
|
|
515
|
+
extendedModifier1Codes,
|
|
516
|
+
isKnownExtendedModifier1Code,
|
|
517
|
+
} from "milsymbol-sidc/catalogs";
|
|
518
|
+
|
|
519
|
+
isKnownExtendedModifier1Code("10", "100"); // true — the common UAV modifier
|
|
520
|
+
isKnownExtendedModifier1Code("10", "199"); // false
|
|
521
|
+
extendedModifier1Codes("10").length; // registered three-digit modifier 1 codes
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
The catalog is **membership only**: it carries no semantic names and is never
|
|
525
|
+
consulted by `toString()`, so raw entity and modifier values still encode
|
|
526
|
+
without recognition warnings. Regenerate it with `npm run generate:catalogs`;
|
|
527
|
+
the milsymbol version it was derived from is exported as `CATALOG_SOURCE`.
|
|
528
|
+
|
|
393
529
|
## Using with milsymbol
|
|
394
530
|
|
|
395
531
|
milsymbol routes any SIDC whose first two characters are digits to its numeric
|
|
@@ -426,9 +562,8 @@ const svg = symbol.asSVG();
|
|
|
426
562
|
const ms = require("milsymbol");
|
|
427
563
|
|
|
428
564
|
async function render() {
|
|
429
|
-
const { Sidc, Standard, StandardIdentity, SymbolSet } =
|
|
430
|
-
"milsymbol-sidc"
|
|
431
|
-
);
|
|
565
|
+
const { Sidc, Standard, StandardIdentity, SymbolSet } =
|
|
566
|
+
await import("milsymbol-sidc");
|
|
432
567
|
|
|
433
568
|
const sidc = new Sidc({ standard: Standard.App6 })
|
|
434
569
|
.identity(StandardIdentity.Friend)
|
|
@@ -447,7 +582,12 @@ Node.js 20.19+ and 22.12+ can also `require("milsymbol-sidc")` directly via
|
|
|
447
582
|
```html
|
|
448
583
|
<script src="https://unpkg.com/milsymbol@3/dist/milsymbol.js"></script>
|
|
449
584
|
<script type="module">
|
|
450
|
-
import {
|
|
585
|
+
import {
|
|
586
|
+
Sidc,
|
|
587
|
+
Standard,
|
|
588
|
+
StandardIdentity,
|
|
589
|
+
SymbolSet,
|
|
590
|
+
} from "https://unpkg.com/milsymbol-sidc/dist/src/index.js";
|
|
451
591
|
|
|
452
592
|
const sidc = new Sidc({ standard: Standard.App6 })
|
|
453
593
|
.identity(StandardIdentity.Neutral)
|
|
@@ -466,6 +606,7 @@ Node.js 20.19+ and 22.12+ can also `require("milsymbol-sidc")` directly via
|
|
|
466
606
|
import {
|
|
467
607
|
Amplifier,
|
|
468
608
|
Context,
|
|
609
|
+
FrameShape,
|
|
469
610
|
HqTaskForceDummy,
|
|
470
611
|
Sidc,
|
|
471
612
|
Standard,
|
|
@@ -512,6 +653,22 @@ new Sidc({ standard: Standard.App6, strict: true })
|
|
|
512
653
|
.modifier2("09")
|
|
513
654
|
.toString(); // "14031000001234560109"
|
|
514
655
|
|
|
656
|
+
// 2525E UAV modifier (extended modifier 1 "100") plus the airborne modifier
|
|
657
|
+
new Sidc({ strict: true })
|
|
658
|
+
.identity(StandardIdentity.Friend)
|
|
659
|
+
.symbolSet(SymbolSet.LandUnit)
|
|
660
|
+
.entity("110000")
|
|
661
|
+
.extendedModifier1("100")
|
|
662
|
+
.extendedModifier2("100")
|
|
663
|
+
.toString(); // "13031000001100000000110"
|
|
664
|
+
|
|
665
|
+
// Frame shape "A" suppresses the frame for E-edition symbols
|
|
666
|
+
new Sidc({ strict: true })
|
|
667
|
+
.identity(StandardIdentity.Friend)
|
|
668
|
+
.symbolSet(SymbolSet.LandUnit)
|
|
669
|
+
.frameShape(FrameShape.NoFrame)
|
|
670
|
+
.toString(); // "1303100000000000000000A"
|
|
671
|
+
|
|
515
672
|
// APP-6 D configuration retains an explicitly selected compatible edition
|
|
516
673
|
new Sidc({ standard: Standard.App6, strict: true })
|
|
517
674
|
.version(Version.App6D)
|
|
@@ -524,10 +681,16 @@ new Sidc({ standard: Standard.App6, strict: true })
|
|
|
524
681
|
|
|
525
682
|
```bash
|
|
526
683
|
npm install
|
|
527
|
-
npm test
|
|
684
|
+
npm test # compiles with tsc, then runs node --test against dist/
|
|
528
685
|
npm run build
|
|
686
|
+
npm run lint # eslint
|
|
687
|
+
npm run format:check # prettier
|
|
688
|
+
npm run generate:catalogs # regenerate src/catalogs.generated.ts from milsymbol
|
|
529
689
|
```
|
|
530
690
|
|
|
691
|
+
CI runs the test suite on Node 18/20/22/24, plus lint, formatting, markdownlint,
|
|
692
|
+
coverage, and a check that the generated catalog is current.
|
|
693
|
+
|
|
531
694
|
Test coverage includes per-field offset encoding for every enum member,
|
|
532
695
|
defaults, immutability, setter validation errors, extended-field offsets,
|
|
533
696
|
all combination rules in both warn and strict modes, raw-code escape hatches,
|
|
@@ -535,10 +698,10 @@ and error class hierarchy.
|
|
|
535
698
|
|
|
536
699
|
## Roadmap
|
|
537
700
|
|
|
538
|
-
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
701
|
+
- Semantic entity and modifier names, layered on the membership catalog.
|
|
702
|
+
- Official positions 24–30 / Set C extension data (country codes and beyond).
|
|
703
|
+
Positions 21–23 shipped: see `extendedModifier1()`, `extendedModifier2()`,
|
|
704
|
+
and `frameShape()`.
|
|
542
705
|
|
|
543
706
|
## License
|
|
544
707
|
|