@orbat-mapper/control-measures 0.2.0-alpha.2 → 0.2.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +9 -3
  2. package/dist/index-COV2WtCq.d.mts +2731 -0
  3. package/dist/index.d.mts +2 -2
  4. package/dist/index.mjs +24 -8
  5. package/dist/preview/index.d.mts +73 -3
  6. package/dist/preview/index.mjs +173 -19
  7. package/dist/{renderControlMeasure-C7pY-TcL.mjs → renderControlMeasure-BG9DzU2W.mjs} +7299 -2392
  8. package/media/airborne-attack.svg +1 -1
  9. package/media/ambush.svg +1 -1
  10. package/media/antitank-ditch-completed.svg +1 -1
  11. package/media/antitank-ditch-under-construction.svg +1 -1
  12. package/media/antitank-wall.svg +1 -1
  13. package/media/area-of-operations.svg +1 -0
  14. package/media/assembly-area.svg +1 -0
  15. package/media/attack-by-fire.svg +1 -1
  16. package/media/attack-helicopter.svg +1 -1
  17. package/media/battle-handover-line.svg +1 -0
  18. package/media/battle-position.svg +1 -1
  19. package/media/block-arrow.svg +1 -1
  20. package/media/block-mission-task.svg +1 -1
  21. package/media/block.svg +1 -1
  22. package/media/boundary.svg +1 -1
  23. package/media/breach.svg +1 -1
  24. package/media/bypass.svg +1 -1
  25. package/media/canalize.svg +1 -1
  26. package/media/circle.svg +1 -0
  27. package/media/classic-arrow.svg +1 -1
  28. package/media/clear.svg +1 -1
  29. package/media/delay.svg +1 -1
  30. package/media/disrupt.svg +1 -1
  31. package/media/encirclement.svg +1 -0
  32. package/media/engineer-work-line.svg +1 -0
  33. package/media/final-protective-fire-left.svg +1 -1
  34. package/media/final-protective-fire-right.svg +1 -1
  35. package/media/fix.svg +1 -1
  36. package/media/flot.svg +1 -1
  37. package/media/fortified-area.svg +1 -1
  38. package/media/fortified-line.svg +1 -1
  39. package/media/generic-c2-line.svg +1 -0
  40. package/media/handover-line.svg +1 -0
  41. package/media/isolate.svg +1 -1
  42. package/media/joint-tactical-action-area.svg +1 -0
  43. package/media/landing-zone.svg +1 -0
  44. package/media/light-line.svg +1 -0
  45. package/media/line.svg +1 -0
  46. package/media/main-attack.svg +1 -1
  47. package/media/obstacle-bypass-difficult.svg +1 -1
  48. package/media/obstacle-bypass-easy.svg +1 -1
  49. package/media/obstacle-bypass-impossible.svg +1 -1
  50. package/media/phase-line.svg +1 -0
  51. package/media/pickup-zone.svg +1 -0
  52. package/media/polygon.svg +1 -0
  53. package/media/principal-direction-of-fire.svg +1 -1
  54. package/media/rectangle.svg +1 -0
  55. package/media/search-area.svg +1 -1
  56. package/media/strong-point.svg +1 -0
  57. package/media/support-by-fire.svg +1 -1
  58. package/media/supporting-attack.svg +1 -1
  59. package/media/turn.svg +1 -1
  60. package/package.json +1 -1
  61. package/dist/index-D7uBPw7l.d.mts +0 -1653
@@ -0,0 +1,2731 @@
1
+ import { Feature, FeatureCollection, Geometry, LineString, MultiLineString, MultiPolygon, Point, Polygon, Position } from "geojson";
2
+
3
+ //#region src/internal/api-utils.d.ts
4
+ type ValidationMode = "silent" | "warn" | "throw";
5
+ //#endregion
6
+ //#region src/draw-rules/types.d.ts
7
+ interface AnchorTransformEvent {
8
+ previous: readonly Position[];
9
+ next: readonly Position[];
10
+ activePointIndex?: number;
11
+ }
12
+ interface ControlMeasureDrawRule {
13
+ readonly id: string;
14
+ readonly minimumUserPoints: number;
15
+ readonly canonicalPointCount?: number;
16
+ /**
17
+ * Number of raw (clicked + rubber-band) points at which `derive` can already
18
+ * produce a renderable canonical shape, so the draw controller renders a live
19
+ * symbol preview instead of the bare vertex-marker outline. Lets a measure
20
+ * show feedback before the full `minimumUserPoints` commit threshold is
21
+ * reached — e.g. Area21 pads two points (first click + cursor) up to its
22
+ * three-point search-area shape. Must be <= `minimumUserPoints`. Defaults to
23
+ * `minimumUserPoints` (no early preview).
24
+ */
25
+ readonly minimumPreviewPoints?: number;
26
+ /**
27
+ * Opt a fixed-length draw into the standard dashed interaction guide. Fixed
28
+ * shapes suppress guides by default because their generator preview is
29
+ * normally sufficient. Use this when the guide communicates an incomplete
30
+ * construction state, such as Rectangle's P1-P2 baseline.
31
+ */
32
+ readonly showGuide?: boolean;
33
+ /**
34
+ * Convert raw draw points into the spine rendered by the interaction guide.
35
+ * Defaults to the raw points. A rule may return the first point again at the
36
+ * end when it needs to provide its own closed guide geometry.
37
+ */
38
+ guidePoints?(points: readonly Position[]): Position[];
39
+ /**
40
+ * Number of trailing slots in the canonical control-point array that are
41
+ * NOT user-clicked spine vertices. For Axis1, this is 1 (the width handle
42
+ * at index N-1). Drives four behaviors in TacticalDraw:
43
+ * 1. New clicks insert at `length - trailingFixedSlots` (not appended).
44
+ * 2. Midpoint handles render only between segments inside
45
+ * [0 .. length - 1 - trailingFixedSlots].
46
+ * 3. The "click the last added point to commit" hit test uses
47
+ * `committed[length - 1 - trailingFixedSlots]`.
48
+ * 4. `canCommit` evaluates `length - trailingFixedSlots >= minimumUserPoints`.
49
+ * Defaults to 0 (the entire array is user-clicked spine). See ADR-0008.
50
+ */
51
+ readonly trailingFixedSlots?: number;
52
+ /**
53
+ * The user-spine points form a closed ring even though the first point is not
54
+ * duplicated at the end. TacticalDraw uses this to treat the last→first edge
55
+ * like every other edge for completion and midpoint insertion.
56
+ */
57
+ readonly closedRing?: boolean;
58
+ derive(points: readonly Position[]): Position[];
59
+ transform(event: AnchorTransformEvent): Position[];
60
+ }
61
+ //#endregion
62
+ //#region src/text-amplifiers.d.ts
63
+ /**
64
+ * MIL-STD-2525E Appendix L Table L-II text amplifier fields.
65
+ *
66
+ * A control measure instance carries free-text amplifier fields (unique
67
+ * designation, country, date-time group, …) keyed by their doctrinal field
68
+ * code. Repeated fields use numbered suffixes per the standard (`T`, `T1`,
69
+ * `AS1`, `W1`, …). Graphic amplifiers (echelon `B`, direction of movement `Q`,
70
+ * offset location `BA`) are deliberately excluded — they are geometry
71
+ * concerns, rendered from generator options rather than free text.
72
+ *
73
+ * This module is a leaf: it imports nothing from `./metadata` or
74
+ * `./registry`, so both can depend on it without a cycle.
75
+ */
76
+ type Suffix = "" | "1" | "2";
77
+ /** Doctrinal text amplifier field codes (Table L-II); graphic amplifier fields excluded. */
78
+ type TextAmplifierField = "C" | "H" | "N" | "T" | "V" | "W" | "X" | "Y" | "AM" | "AN" | "AP" | "AS";
79
+ /** A doctrinal field code with its optional repetition suffix, e.g. `"T1"`. */
80
+ type TextAmplifierKey = `${TextAmplifierField}${Suffix}`;
81
+ /**
82
+ * The vocabulary of text amplifier fields: doctrinal code, milsymbol-style
83
+ * friendly alias, and a human-readable label. The single source of truth for
84
+ * both the runtime catalog and the derived alias→code lookup used by
85
+ * {@link normalizeTextAmplifiers}.
86
+ */
87
+ declare const TEXT_AMPLIFIER_FIELDS: {
88
+ readonly C: {
89
+ readonly alias: "quantity";
90
+ readonly label: "Quantity";
91
+ };
92
+ readonly H: {
93
+ readonly alias: "additionalInformation";
94
+ readonly label: "Additional information";
95
+ };
96
+ readonly N: {
97
+ readonly alias: "hostile";
98
+ readonly label: "Hostile (ENY) marker";
99
+ };
100
+ readonly T: {
101
+ readonly alias: "uniqueDesignation";
102
+ readonly label: "Unique designation";
103
+ };
104
+ readonly V: {
105
+ readonly alias: "type";
106
+ readonly label: "Equipment/type";
107
+ };
108
+ readonly W: {
109
+ readonly alias: "dtg";
110
+ readonly label: "Date-time group / O/O";
111
+ };
112
+ readonly X: {
113
+ readonly alias: "altitudeDepth";
114
+ readonly label: "Altitude/depth";
115
+ };
116
+ readonly Y: {
117
+ readonly alias: "location";
118
+ readonly label: "Location";
119
+ };
120
+ readonly AM: {
121
+ readonly alias: "distance";
122
+ readonly label: "Distance/range/radius";
123
+ };
124
+ readonly AN: {
125
+ readonly alias: "azimuth";
126
+ readonly label: "Azimuth";
127
+ };
128
+ readonly AP: {
129
+ readonly alias: "targetNumber";
130
+ readonly label: "Target number";
131
+ };
132
+ readonly AS: {
133
+ readonly alias: "country";
134
+ readonly label: "Country code";
135
+ };
136
+ };
137
+ /** The milsymbol-style friendly alias for a text amplifier field, e.g. `"uniqueDesignation"`. */
138
+ type FriendlyName = (typeof TEXT_AMPLIFIER_FIELDS)[TextAmplifierField]["alias"];
139
+ /** A friendly alias with its optional repetition suffix, e.g. `"country1"`. */
140
+ type FriendlyKey = `${FriendlyName}${Suffix}`;
141
+ /**
142
+ * User-facing amplifier input: either canonical doctrinal keys (`T`, `AS1`,
143
+ * …) or friendly aliases (`uniqueDesignation`, `country1`, …), optionally
144
+ * mixed. Values are free text; see {@link normalizeTextAmplifiers} for how
145
+ * this is resolved to canonical form.
146
+ */
147
+ type TextAmplifiers = Partial<Record<TextAmplifierKey | FriendlyKey, string>>;
148
+ /**
149
+ * Stable key for a non-amplifier generated label. The renderer assigns these
150
+ * from the label's part and per-part label ordinal when a generator has not
151
+ * supplied a doctrinal field key. Generators that can change a label's order
152
+ * should supply an explicit `labelPlacementKey` instead.
153
+ */
154
+ type GeneratedLabelKey = `label:${string}`;
155
+ /**
156
+ * Object form of a per-label override. `rotation` is in stored radians — the
157
+ * same convention as `FeaturePartProps.rotation` (adapters render the
158
+ * on-screen angle as `π − rotation`).
159
+ */
160
+ interface LabelPlacementOverride {
161
+ position?: Position;
162
+ rotation?: number;
163
+ }
164
+ /** A per-label override: a bare anchor (legacy shorthand) or the object form. */
165
+ type AmplifierPlacement = Position | LabelPlacementOverride;
166
+ /**
167
+ * User-adjusted anchor positions (and, optionally, rotations) for doctrinal
168
+ * and generated text labels, keyed by a canonical `TextAmplifierKey` or a
169
+ * synthesized `GeneratedLabelKey`.
170
+ */
171
+ type AmplifierPlacements = Record<string, AmplifierPlacement | undefined>;
172
+ /**
173
+ * Resolves a raw placement entry to its object form: a bare `Position` is
174
+ * legacy shorthand for `{ position }`; an object form passes through only the
175
+ * fields that are actually valid (`position` must be a finite `[lon, lat]`,
176
+ * `rotation` a finite number); `undefined` resolves to `{}`.
177
+ */
178
+ declare function resolveAmplifierPlacement(value: AmplifierPlacement | undefined): LabelPlacementOverride;
179
+ /** Amplifier values resolved to canonical doctrinal keys, as generators receive them. */
180
+ type CanonicalTextAmplifiers = Readonly<Partial<Record<TextAmplifierKey, string>>>;
181
+ /**
182
+ * Resolves any accepted key (canonical or friendly alias, with an optional
183
+ * `1`/`2` suffix) to its canonical key, or `undefined` if unknown — e.g.
184
+ * `"T"` → `"T"`, `"uniqueDesignation1"` → `"T1"`, `"bogus"` → `undefined`.
185
+ */
186
+ declare function canonicalTextAmplifierKey(key: string): TextAmplifierKey | undefined;
187
+ /**
188
+ * Resolves a `TextAmplifiers` record (canonical keys, friendly aliases, or a
189
+ * mix) to `CanonicalTextAmplifiers` keyed purely by doctrinal field code.
190
+ *
191
+ * - Friendly aliases (with an optional `1`/`2` suffix) map to their canonical
192
+ * code (e.g. `country1` → `AS1`).
193
+ * - Values are trimmed; entries that are empty/whitespace-only after
194
+ * trimming, or not strings, are dropped.
195
+ * - When both a canonical key and its friendly alias are present for the same
196
+ * field + suffix, the **canonical key wins** regardless of insertion order.
197
+ * This holds even for an empty/whitespace canonical value: it suppresses
198
+ * (clears) the alias entry rather than letting the alias survive.
199
+ * - Unknown keys are ignored.
200
+ *
201
+ * `undefined` or an empty input returns a shared frozen empty object.
202
+ */
203
+ declare function normalizeTextAmplifiers(input: TextAmplifiers | undefined): CanonicalTextAmplifiers;
204
+ //#endregion
205
+ //#region src/metadata.d.ts
206
+ type ControlMeasureGeometryType = Geometry["type"];
207
+ type ControlMeasureGeometry = "point" | "line" | "area";
208
+ declare const DRAW_RULE_IDS: readonly ["Area1", "Area7", "Area8", "Area11", "Area12", "Area15", "Area21", "Axis1", "Line1", "Line3", "Line9", "Line10", "Line23", "Line24", "Line26", "Line29", "Point12", "Rectangle"];
209
+ type DrawRuleId = (typeof DRAW_RULE_IDS)[number];
210
+ interface BaseParamDescriptor {
211
+ key: string;
212
+ label: string;
213
+ description?: string;
214
+ visibleWhen?: (opts: Record<string, unknown>) => boolean;
215
+ }
216
+ interface NumberParamDescriptor extends BaseParamDescriptor {
217
+ type: "number";
218
+ min?: number;
219
+ max?: number;
220
+ step?: number;
221
+ unit?: string;
222
+ }
223
+ interface BooleanParamDescriptor extends BaseParamDescriptor {
224
+ type: "boolean";
225
+ }
226
+ interface ColorParamDescriptor extends BaseParamDescriptor {
227
+ type: "color";
228
+ }
229
+ interface EnumParamDescriptor extends BaseParamDescriptor {
230
+ type: "enum";
231
+ options: readonly {
232
+ label: string;
233
+ value: string | number | boolean;
234
+ }[];
235
+ }
236
+ interface TextParamDescriptor extends BaseParamDescriptor {
237
+ type: "text";
238
+ placeholder?: string;
239
+ maxLength?: number;
240
+ /**
241
+ * The doctrinal Table L-II field this free-text option renders (e.g.
242
+ * `phaseLineName` renders field `T`) — lets metadata-driven UIs (e.g. a
243
+ * label-placement preview) substitute a `<T>`-style placeholder for the
244
+ * option, the same way a `TextAmplifierDescriptor` does for a real
245
+ * amplifier field.
246
+ */
247
+ field?: TextAmplifierField;
248
+ }
249
+ type ParamDescriptor = NumberParamDescriptor | BooleanParamDescriptor | ColorParamDescriptor | TextParamDescriptor | EnumParamDescriptor;
250
+ /** Editor-facing description of one text amplifier field a measure accepts. */
251
+ interface TextAmplifierDescriptor {
252
+ key: TextAmplifierKey;
253
+ label: string;
254
+ description?: string;
255
+ placeholder?: string;
256
+ /** Editor hint only — the renderer never truncates the value. */
257
+ maxLength?: number;
258
+ }
259
+ interface ControlMeasureMetadata {
260
+ id: string;
261
+ name: string;
262
+ description: string;
263
+ entity: string;
264
+ entityType: string;
265
+ entitySubtype?: string;
266
+ value: string;
267
+ geometry: ControlMeasureGeometry;
268
+ minCoordinates?: number;
269
+ maxCoordinates?: number;
270
+ geometryTypes?: readonly ControlMeasureGeometryType[];
271
+ drawRule?: DrawRuleId;
272
+ /**
273
+ * Resolved draw rule object (anchor contract) attached by the registry when
274
+ * the kind's `drawRule` id has an implementation. Consumed by the
275
+ * `TacticalDraw` façade to drive click accumulation during draw and
276
+ * vertex-snap during edit — see ADR-0005.
277
+ */
278
+ rule?: ControlMeasureDrawRule;
279
+ params?: readonly ParamDescriptor[];
280
+ /** Text amplifier fields (MIL-STD-2525E Appendix L Table L-II) this measure accepts. */
281
+ textAmplifiers?: readonly TextAmplifierDescriptor[];
282
+ /**
283
+ * Marks a measure that emits a text label whose pixel size should be captured
284
+ * once at draw-commit time (rather than re-resolved on every zoom). Hosts use
285
+ * this to stamp default label sizing onto the committed measure — see
286
+ * `withCommittedAdapterMeasureOptions` in `tactical-draw`. Keeping it on the
287
+ * definition means adding such a measure stays a one-file change (ADR-0013).
288
+ */
289
+ capturesLabelSize?: boolean;
290
+ }
291
+ //#endregion
292
+ //#region src/define.d.ts
293
+ /**
294
+ * The loosest `FeatureCollection` a control-measure generator may emit: any
295
+ * geometry, with per-feature properties that the renderer normalizes.
296
+ */
297
+ type AnyFeatureCollection = FeatureCollection<Geometry, Record<string, unknown> | null>;
298
+ /** Read-only instance state that can affect generated geometry. */
299
+ interface ControlMeasureGeneratorContext {
300
+ amplifierPlacements?: AmplifierPlacements;
301
+ }
302
+ /**
303
+ * A generator's call signature, constrained only by its inputs and output. The
304
+ * options parameter is typed `never` so that a generator with *any* concrete
305
+ * options type satisfies the bound — function parameters are contravariant, so
306
+ * `(o: BlockOptions) => …` is assignable to `(o: never) => …`. The actual
307
+ * options type is recovered covariantly via {@link OptsOf}, never through this
308
+ * bound. See ADR-0013.
309
+ *
310
+ * The optional third parameter carries the instance's normalized text
311
+ * amplifiers (ADR-0027); a generator that ignores text amplifiers just omits
312
+ * the parameter. The optional fourth parameter carries instance state needed
313
+ * while generating geometry derived from an individual label placement.
314
+ * Generators may omit either trailing parameter.
315
+ */
316
+ type ControlMeasureGenerator = (controlPoints: Position[], options: never, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext) => AnyFeatureCollection;
317
+ /**
318
+ * Everything that defines one control measure, co-located with its generator.
319
+ * `registry.ts` collects these into the single `DEFINITIONS` map, from which
320
+ * the `ControlMeasureId` union, `OptionsByKind`, the generator dispatch, the
321
+ * default options, and rule resolution are all derived rather than maintained
322
+ * as parallel tables. See ADR-0013.
323
+ */
324
+ interface ControlMeasureDefinition<Id extends string, G extends ControlMeasureGenerator> {
325
+ /** Catalog metadata; `id` is pinned to the record's literal key. */
326
+ metadata: ControlMeasureMetadata & {
327
+ id: Id;
328
+ };
329
+ /** Pure generator: control points (+ options) → GeoJSON features. */
330
+ generator: G;
331
+ /** Default options, tied to the generator's own options parameter. */
332
+ defaultOptions: NonNullable<Parameters<G>[1]>;
333
+ /**
334
+ * Resolved draw-rule object, merged back onto metadata by the registry. The
335
+ * doctrinal `drawRule` spec id stays on `metadata` (ADR-0005); the registry
336
+ * guards that `rule` agrees with it. See ADR-0013.
337
+ */
338
+ rule?: ControlMeasureDrawRule;
339
+ /**
340
+ * Representative sample used only by the static catalog/thumbnail previews
341
+ * (the `/preview` subpath). Most measures omit it and fall back to a generic
342
+ * layout keyed off `geometry`/`minCoordinates`/`entityType`; a measure whose
343
+ * symbol needs special framing co-locates the override here rather than in a
344
+ * central per-id switch. Points are **unitless** (~`[-1, 1]`); the resolver
345
+ * scales them to the small degree offsets the projected-meter generators
346
+ * expect. `options` is type-checked against this measure's own options. See
347
+ * ADR-0025.
348
+ */
349
+ previewSample?: PreviewSample<NonNullable<Parameters<G>[1]>>;
350
+ /**
351
+ * Pins orientation-derived defaults — options whose default value depends on
352
+ * the shape's current screen orientation (e.g. Battle Position's echelon
353
+ * anchor, which defaults to the bottom edge) — to their current concrete
354
+ * values. Returns an options patch to merge onto the working options, or
355
+ * `undefined` when there is nothing to freeze (already frozen, or nothing
356
+ * visible to pin). Called by edit hosts when a rotate gesture starts, so a
357
+ * subsequent rigid rotation of the control points preserves the rendered
358
+ * appearance instead of an orientation-relative default silently re-deriving
359
+ * against the new orientation. See ADR-0023.
360
+ */
361
+ freezeOrientation?: (controlPoints: Position[], options: NonNullable<Parameters<G>[1]>) => Partial<NonNullable<Parameters<G>[1]>> | undefined;
362
+ }
363
+ /**
364
+ * A measure's representative preview input. Shared between the typed
365
+ * {@link ControlMeasureDefinition} field and the erased
366
+ * {@link AnyControlMeasureDefinition}; `Options` is the measure's own options
367
+ * type (or `unknown` once erased). See ADR-0025.
368
+ */
369
+ interface PreviewSample<Options> {
370
+ controlPoints: readonly (readonly [number, number])[];
371
+ options?: Partial<Options>;
372
+ /**
373
+ * Sample text amplifiers (ADR-0027) rendered onto the representative
374
+ * preview, for measures whose doctrinal appearance is carried by amplifier
375
+ * text (e.g. Boundary-style end/center labels) rather than options alone.
376
+ */
377
+ textAmplifiers?: TextAmplifiers;
378
+ }
379
+ /**
380
+ * Extracts a definition's options type covariantly from its generator's
381
+ * (optional) second parameter — robust where inferring through the
382
+ * contravariant parameter position is not. See ADR-0013.
383
+ */
384
+ type OptsOf<D> = D extends {
385
+ generator: (points: Position[], options?: infer O) => unknown;
386
+ } ? O : never;
387
+ //#endregion
388
+ //#region src/generators/cm11-command-control-lines/boundary.d.ts
389
+ /** Configuration options for the Boundary control measure. */
390
+ interface BoundaryOptions {
391
+ /**
392
+ * Field B echelon. One of the keys in {@link ECHELONS} (e.g. `"battalion"`,
393
+ * `"division"`) or an equivalent symbol form (`"II"`, `"XX"`). `"none"`,
394
+ * empty, or unknown renders no glyph and leaves the line continuous.
395
+ * @default "battalion"
396
+ */
397
+ echelon?: string;
398
+ /**
399
+ * Echelon glyph height in meters (ground-anchored). Ignored when
400
+ * `echelonSizePixels` is supplied together with `metersPerPixel`.
401
+ * @default 750
402
+ */
403
+ echelonSize?: number;
404
+ /**
405
+ * Echelon glyph height in screen pixels (screen-anchored). Resolved to meters
406
+ * against `metersPerPixel`; bakes to a meter size on draw/edit commit
407
+ * (ADR-0020).
408
+ * @default 16
409
+ */
410
+ echelonSizePixels?: number;
411
+ /**
412
+ * Gap left on each side of the echelon glyph, as a ratio of the glyph height.
413
+ * `0` butts the line against the glyph; larger values widen the break.
414
+ * @default 0.3
415
+ */
416
+ echelonPadding?: number;
417
+ /**
418
+ * Meters-per-pixel at the current zoom/latitude. Stamped by the host when the
419
+ * measure is screen-anchored; required to resolve `echelonSizePixels` and to
420
+ * lock the T/AS text size to the glyph height.
421
+ */
422
+ metersPerPixel?: number;
423
+ /**
424
+ * Number of label groups (echelon + designators), spaced evenly by cumulative
425
+ * arc length along the whole boundary. `1` places a single group at
426
+ * `labelPosition`, whose default is the midpoint of the total length.
427
+ * @default 1
428
+ */
429
+ labelRepetitions?: number;
430
+ /**
431
+ * Spacing between label groups when `labelRepetitions > 1`, relative to an even
432
+ * spread across the whole boundary. `1` spreads them evenly end-to-end; `<1`
433
+ * clusters them toward the midpoint; `>1` pushes them toward the ends
434
+ * (clamped to the boundary). No effect for a single group.
435
+ * @default 1
436
+ */
437
+ labelSpacing?: number;
438
+ /**
439
+ * Position of a single label group as a fraction of cumulative arc length
440
+ * from the boundary's first control point (0) to its last (1). Ignored when
441
+ * `labelRepetitions > 1`.
442
+ * @default 0.5
443
+ */
444
+ labelPosition?: number;
445
+ /**
446
+ * Clearance between the line/echelon glyph and the unit labels, as a ratio
447
+ * of the echelon glyph height (like `echelonPadding`). In `"along"` mode
448
+ * (and on `"standard"` east–west segments) it grows the labels'
449
+ * perpendicular offset from the line; in a `"standard"` north–south crossing
450
+ * row it grows each label's gap to the echelon glyph. Negative values clamp
451
+ * to 0.
452
+ * @default 0.4
453
+ */
454
+ labelPadding?: number;
455
+ /**
456
+ * How the T/AS unit labels and the echelon glyph are oriented:
457
+ *
458
+ * - `"along"` — text runs along the line, offset perpendicular to it, and
459
+ * the echelon glyph turns with the segment (the default).
460
+ * - `"standard"` — MIL-STD-2525E Appendix L §L.5.5.2 / Figure L-10
461
+ * placement. On mostly east–west segments this reads exactly like
462
+ * `"along"`. On mostly north–south segments the whole group rotates to run
463
+ * *perpendicular* to the line instead: a single row of
464
+ * `<unit 1> <echelon> <unit 2>` crossing it (unit 1 on its left-of-travel
465
+ * side), each label aligned away from the glyph so long designations never
466
+ * overlap the line.
467
+ * @default "along"
468
+ */
469
+ labelOrientation?: "along" | "standard";
470
+ /**
471
+ * Round the boundary's corners by curving it through the control points
472
+ * (centripetal Catmull-Rom spline). The spline preserves the endpoints, so
473
+ * the line still meets its drawn anchors.
474
+ * @default false
475
+ */
476
+ smooth?: boolean;
477
+ /**
478
+ * Number of samples per segment when `smooth` is enabled. Higher values yield
479
+ * a denser, smoother curve.
480
+ * @default 12
481
+ */
482
+ smoothResolution?: number;
483
+ }
484
+ /** Default options for the Boundary control measure. */
485
+ declare const DEFAULT_BOUNDARY_OPTIONS: BoundaryOptions;
486
+ /**
487
+ * Creates a Boundary control measure: a polyline through `positions` carrying
488
+ * repeated echelon + unit-designator labels.
489
+ *
490
+ * @param positions - Boundary anchor points (≥2); the input contract is
491
+ * enforced at the render seam (ADR-0014).
492
+ * @param options - {@link BoundaryOptions}.
493
+ * @param textAmplifiers - Normalized text amplifiers (ADR-0027): `T`/`AS` label
494
+ * unit 1 (left-of-travel side), `T1`/`AS1` label unit 2 (right-of-travel side).
495
+ */
496
+ declare function createBoundary(positions: Position[], options?: BoundaryOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | MultiPolygon | Point>;
497
+ //#endregion
498
+ //#region src/projection.d.ts
499
+ type Point2D = [number, number];
500
+ /**
501
+ * Project WGS84 (Lon/Lat) to Web Mercator (Meters).
502
+ */
503
+ declare const project: (lon: number, lat: number) => Point2D;
504
+ /**
505
+ * Unproject Web Mercator (Meters) back to WGS84 (Lon/Lat).
506
+ */
507
+ declare const unproject: (x: number, y: number) => Position;
508
+ //#endregion
509
+ //#region src/internal/sketch.d.ts
510
+ /**
511
+ * Shared `smooth`/`smoothResolution` option pair for free n-point polyline
512
+ * measures (draw rule Line1): curves the rendered path through the control
513
+ * points via a centripetal Catmull-Rom spline. The spline preserves the
514
+ * endpoints, so the line still meets its drawn anchors, and is a no-op for
515
+ * fewer than three control points (a single segment cannot be smoothed).
516
+ */
517
+ interface SmoothLineOptions {
518
+ /**
519
+ * Round the line's corners by curving the path through the control points
520
+ * (centripetal Catmull-Rom spline). The spline preserves the endpoints, so
521
+ * the line still meets its drawn anchors.
522
+ * @default false
523
+ */
524
+ smooth?: boolean;
525
+ /**
526
+ * Number of samples per segment when `smooth` is enabled. Higher values
527
+ * yield a denser, smoother curve.
528
+ * @default (varies per measure)
529
+ */
530
+ smoothResolution?: number;
531
+ }
532
+ //#endregion
533
+ //#region src/internal/line-labels.d.ts
534
+ /**
535
+ * Label sizing per the size-anchor model (ADR-0020, ADR-0028): the presence of
536
+ * `labelSizePixels` marks the labels screen-anchored; `labelSize` alone is
537
+ * ground-anchored. Carrying both behaves screen-anchored (pixels win),
538
+ * matching the geometry options' precedence.
539
+ */
540
+ interface LabelSizeOptions {
541
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
542
+ labelSize?: number;
543
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
544
+ labelSizePixels?: number;
545
+ /**
546
+ * Meters-per-pixel at the current view. Stamped by the host when the labels
547
+ * are screen-anchored; resolves `labelSizePixels` to the projected-meter
548
+ * height that meter-denominated placement (offsets, gaps, row pitch) needs.
549
+ */
550
+ metersPerPixel?: number;
551
+ }
552
+ /** Shared placement options for the fixed-end-label line measures. */
553
+ interface LineLabelOptions extends LabelSizeOptions {
554
+ /**
555
+ * Extra clearance between the line and its labels, as a ratio of the
556
+ * label's resolved text height (`labelSize`, or `labelSizePixels ×
557
+ * metersPerPixel`), like Boundary's `labelPadding`. Negative values clamp
558
+ * to 0. Only effective when a label size resolves — the no-size fallback
559
+ * offset is a fixed meter value, unaffected by this ratio.
560
+ * @default 0
561
+ */
562
+ labelPadding?: number;
563
+ }
564
+ //#endregion
565
+ //#region src/generators/cm11-command-control-lines/light-line.d.ts
566
+ /** Configuration options for the Light line control measure. */
567
+ interface LightLineOptions extends LineLabelOptions, SmoothLineOptions {
568
+ /**
569
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
570
+ * the line, additive to the fixed "LL" labels. Empty or whitespace-only
571
+ * renders no label.
572
+ * @default none
573
+ */
574
+ phaseLineName?: string;
575
+ /**
576
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
577
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
578
+ * Phase Line itself, this measure already carries its own fixed "LL"
579
+ * label, so there is no bare "PL" fallback.
580
+ * @default true
581
+ */
582
+ includePrefix?: boolean;
583
+ }
584
+ /** Default options for the Light line control measure. */
585
+ declare const DEFAULT_LIGHT_LINE_OPTIONS: LightLineOptions;
586
+ /**
587
+ * Creates a Light line control measure: a polyline through `positions`
588
+ * labeled "LL" above the line near each end.
589
+ */
590
+ declare function createLightLine(positions: Position[], options?: LightLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
591
+ //#endregion
592
+ //#region src/generators/cm11-command-control-lines/engineer-work-line.d.ts
593
+ /** Configuration options for the Engineer work line control measure. */
594
+ interface EngineerWorkLineOptions extends LineLabelOptions, SmoothLineOptions {
595
+ /**
596
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
597
+ * the line, additive to the fixed "EWL" labels. Empty or whitespace-only
598
+ * renders no label.
599
+ * @default none
600
+ */
601
+ phaseLineName?: string;
602
+ /**
603
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
604
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
605
+ * Phase Line itself, this measure already carries its own fixed "EWL"
606
+ * label, so there is no bare "PL" fallback.
607
+ * @default true
608
+ */
609
+ includePrefix?: boolean;
610
+ }
611
+ /** Default options for the Engineer work line control measure. */
612
+ declare const DEFAULT_ENGINEER_WORK_LINE_OPTIONS: EngineerWorkLineOptions;
613
+ /**
614
+ * Creates an Engineer work line control measure: a polyline through
615
+ * `positions` labeled "EWL" above the line near each end, plus one center
616
+ * label group at the midpoint of the total arc length carrying the
617
+ * responsible units' Field T/AS designator+country (left-of-travel side
618
+ * above the line, T1/AS1 below). No center group is emitted when all four
619
+ * amplifiers are empty.
620
+ */
621
+ declare function createEngineerWorkLine(positions: Position[], options?: EngineerWorkLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
622
+ //#endregion
623
+ //#region src/generators/cm11-command-control-lines/generic-c2-line.d.ts
624
+ /** Configuration options for the Generic command and control line. */
625
+ interface GenericC2LineOptions extends LineLabelOptions, SmoothLineOptions {
626
+ /**
627
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
628
+ * the line, additive to the H/T/W/W1 amplifier labels. Empty or
629
+ * whitespace-only renders no label.
630
+ * @default none
631
+ */
632
+ phaseLineName?: string;
633
+ /**
634
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
635
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — this
636
+ * measure already carries its own H/T/W/W1 amplifier labels, so there is
637
+ * no bare "PL" fallback.
638
+ * @default true
639
+ */
640
+ includePrefix?: boolean;
641
+ }
642
+ /** Default options for the Generic command and control line. */
643
+ declare const DEFAULT_GENERIC_C2_LINE_OPTIONS: GenericC2LineOptions;
644
+ /**
645
+ * Creates a Generic command and control line: a polyline through `positions`
646
+ * with optional near-end text — `H`/`T` joined above the line, `W`/`W1`
647
+ * joined as a "from - to" range below it. Both rows share the per-tip
648
+ * placement from {@link import("../../internal/line-labels").aboveEndFrames}
649
+ * (inset from the tip, anchored toward the line's interior), one at
650
+ * `base + perp·offset` and the other at `base − perp·offset`.
651
+ */
652
+ declare function createGenericC2Line(positions: Position[], options?: GenericC2LineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
653
+ //#endregion
654
+ //#region src/internal/area-labels.d.ts
655
+ /** Shared placement options for the centered-label area measures. */
656
+ interface AreaLabelOptions extends LabelSizeOptions {
657
+ /**
658
+ * Extra row leading (and ENY inset), as a ratio of the label's resolved
659
+ * text height, like the labeled line measures' own `labelPadding`.
660
+ * Negative values clamp to 0.
661
+ * @default 0
662
+ */
663
+ labelPadding?: number;
664
+ }
665
+ /** Options for {@link labeledAreaFeatures}: {@link buildClosedRing}'s
666
+ * smoothing knobs plus the shared {@link AreaLabelOptions} label placement. */
667
+ interface LabeledAreaOptions extends AreaLabelOptions {
668
+ /**
669
+ * Round the area's corners by curving the boundary through the control
670
+ * points (closed centripetal Catmull-Rom spline).
671
+ * @default false
672
+ */
673
+ smooth?: boolean;
674
+ /**
675
+ * Number of samples per segment when `smooth` is enabled.
676
+ * @default 16
677
+ */
678
+ smoothResolution?: number;
679
+ }
680
+ //#endregion
681
+ //#region src/generators/cm15-maneuver-areas/battlePosition.d.ts
682
+ /**
683
+ * Configuration options for the Battle Position control measure. Also
684
+ * carries the shared {@link AreaLabelOptions} placement for its centered
685
+ * Field T (designator) label.
686
+ */
687
+ interface BattlePositionOptions extends AreaLabelOptions {
688
+ /**
689
+ * Field B echelon. One of the keys in the echelon vocabulary (e.g.
690
+ * `"battalion"`, `"division"`) or an equivalent symbol form (`"II"`, `"XX"`).
691
+ * `"none"`, empty, or unknown renders no glyph and leaves the boundary
692
+ * continuous.
693
+ * @default "battalion"
694
+ */
695
+ echelon?: string;
696
+ /**
697
+ * Echelon glyph height in meters (ground-anchored). Ignored when
698
+ * `echelonSizePixels` is supplied together with `metersPerPixel`.
699
+ * @default 750
700
+ */
701
+ echelonSize?: number;
702
+ /**
703
+ * Echelon glyph height in screen pixels (screen-anchored). Resolved to meters
704
+ * against `metersPerPixel`; bakes to a meter size on draw/edit commit
705
+ * (ADR-0020).
706
+ * @default 16
707
+ */
708
+ echelonSizePixels?: number;
709
+ /**
710
+ * Gap left on each side of the echelon glyph, as a ratio of the glyph height.
711
+ * `0` butts the boundary against the glyph; larger values widen the break.
712
+ * @default 0.3
713
+ */
714
+ echelonPadding?: number;
715
+ /**
716
+ * Slides the echelon along the boundary, as a signed fraction of the total
717
+ * perimeter measured from its default anchor on the bottom edge. `0` keeps it
718
+ * centered on the bottom; positive/negative values move it around the ring in
719
+ * either direction (wrapping at the seam).
720
+ * @default 0
721
+ */
722
+ echelonPosition?: number;
723
+ /**
724
+ * Absolute anchor for the echelon glyph, as a fraction of the total
725
+ * perimeter measured from the ring seam (the ring's first vertex), wrapped
726
+ * into `[0, 1)`. When omitted, the anchor is "auto": the bottom edge's
727
+ * midpoint (the side opposite the front), recomputed from the current
728
+ * geometry on every render — the long-standing default behavior.
729
+ * `echelonPosition` still applies on top of this anchor as a signed offset,
730
+ * exactly as it does against the auto anchor.
731
+ *
732
+ * Edit controllers freeze this from "auto" to a concrete fraction the
733
+ * moment a rotate gesture starts (see `freezeEchelonAnchor` /
734
+ * `freezeOrientationOptions`): the transform box rotates only the control
735
+ * points and re-renders, so without a pinned anchor the "bottom edge" would
736
+ * keep re-deriving against the rotated geometry and the glyph would jump to
737
+ * a different edge each time a new edge becomes lowest. Freezing the anchor
738
+ * first makes the rotation rigid — the glyph turns with the shape instead.
739
+ * See ADR-0023.
740
+ */
741
+ echelonAnchor?: number;
742
+ /**
743
+ * Meters-per-pixel at the current zoom/latitude. Stamped by the host when the
744
+ * measure is screen-anchored; required to resolve `echelonSizePixels`.
745
+ */
746
+ metersPerPixel?: number;
747
+ /**
748
+ * Round the area's corners by curving the boundary through the control points
749
+ * (closed centripetal Catmull-Rom spline), matching the rounded shape in the
750
+ * APP-6 template.
751
+ * @default false
752
+ */
753
+ smooth?: boolean;
754
+ /**
755
+ * Number of samples per segment when `smooth` is enabled. Higher values yield
756
+ * a denser, smoother curve.
757
+ * @default 16
758
+ */
759
+ smoothResolution?: number;
760
+ }
761
+ /** Default options for the Battle Position control measure. */
762
+ declare const DEFAULT_BATTLE_POSITION_OPTIONS: BattlePositionOptions;
763
+ /**
764
+ * Creates a Battle Position control measure: a closed area through `positions`
765
+ * carrying a single echelon (Field B) glyph straddling its boundary — anchored
766
+ * to the bottom edge by default, slidable via `echelonPosition`.
767
+ *
768
+ * @param positions - Area anchor points (≥3); the input contract is enforced at
769
+ * the render seam (ADR-0014).
770
+ * @param options - {@link BattlePositionOptions}.
771
+ * @param textAmplifiers - Field T (designation, centered in the area) plus an
772
+ * optional Field N "ENY" hostile marker at the west/east edges (no H/W rows —
773
+ * this measure's template pairs the designation with the Field B glyph, not
774
+ * the plain L-15 boundary template).
775
+ */
776
+ declare function createBattlePosition(positions: Position[], options?: BattlePositionOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<MultiLineString | MultiPolygon | Point>;
777
+ //#endregion
778
+ //#region src/generators/cm15-maneuver-areas/strongPoint.d.ts
779
+ /** Configuration options for the Strong Point control measure. */
780
+ type StrongPointOptions = BattlePositionOptions;
781
+ /** Default options for the Strong Point control measure. */
782
+ declare const DEFAULT_STRONG_POINT_OPTIONS: StrongPointOptions;
783
+ /**
784
+ * Creates a Strong Point control measure: a Battle Position boundary/echelon
785
+ * with outward tics whose length and spacing are the Field B echelon height.
786
+ * Shares the perimeter and echelon placement with Battle Position via the
787
+ * `area-echelon` primitive (single source of truth for ring and gap).
788
+ *
789
+ * @param positions - Area anchor points (>=3); the input contract is enforced
790
+ * at the render seam (ADR-0014).
791
+ * @param options - {@link StrongPointOptions}.
792
+ * @param textAmplifiers - Field T (designation, centered in the area) plus an
793
+ * optional Field N "ENY" hostile marker at the west/east edges, same as
794
+ * Battle Position.
795
+ */
796
+ declare function createStrongPoint(positions: Position[], options?: StrongPointOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<MultiLineString | MultiPolygon | Point>;
797
+ //#endregion
798
+ //#region src/generators/cm14-maneuver-lines/direction-of-attack-aviation.d.ts
799
+ interface DirectionOfAttackAviationOptions extends LabelSizeOptions, SmoothLineOptions {
800
+ /** Arrowhead length as a ratio of the route's total length. @default 0.12 */
801
+ arrowheadLengthRatio?: number;
802
+ /** Arrowhead total width as a ratio of its length. @default 1.15 */
803
+ arrowheadWidthRatio?: number;
804
+ /** Bow-tie length as a ratio of the route's total length. @default 0.1 */
805
+ bowTieLengthRatio?: number;
806
+ /** Bow-tie total width as a ratio of its length. @default 0.5 */
807
+ bowTieWidthRatio?: number;
808
+ /** Bow-tie position as a fraction from tail (0) to tip (1). @default 1/3 */
809
+ bowTiePosition?: number;
810
+ /** Field T/W/W1 group position as a fraction from tail (0) to tip (1). @default 2/3 */
811
+ labelPosition?: number;
812
+ /** Extra spacing between the route and W/W1 rows, in label heights. @default 0 */
813
+ labelPadding?: number;
814
+ }
815
+ declare const DEFAULT_DIRECTION_OF_ATTACK_AVIATION_OPTIONS: DirectionOfAttackAviationOptions;
816
+ /** Builds the route, aviation bow-tie, arrowhead, and optional T/W/W1 labels. */
817
+ declare function createDirectionOfAttackAviation(coordinates: Position[], options?: DirectionOfAttackAviationOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
818
+ //#endregion
819
+ //#region src/generators/cm14-maneuver-lines/direction-of-attack-shared.d.ts
820
+ interface DirectionOfAttackLineOptions extends LabelSizeOptions, SmoothLineOptions {
821
+ arrowheadLengthRatio?: number;
822
+ arrowheadWidthRatio?: number;
823
+ /** Field T/W/W1 group position as a fraction from tail (0) to tip (1). */
824
+ labelPosition?: number;
825
+ labelPadding?: number;
826
+ }
827
+ //#endregion
828
+ //#region src/generators/cm14-maneuver-lines/direction-of-main-attack.d.ts
829
+ interface DirectionOfMainAttackOptions extends DirectionOfAttackLineOptions {
830
+ /** Thickness of the outlined arrowhead as a ratio of its length. @default 0.3 */
831
+ arrowheadOutlineRatio?: number;
832
+ }
833
+ declare const DEFAULT_DIRECTION_OF_MAIN_ATTACK_OPTIONS: DirectionOfMainAttackOptions;
834
+ declare function createDirectionOfMainAttack(coordinates: Position[], options?: DirectionOfMainAttackOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
835
+ //#endregion
836
+ //#region src/generators/cm14-maneuver-lines/direction-of-supporting-attack.d.ts
837
+ type DirectionOfSupportingAttackOptions = DirectionOfAttackLineOptions;
838
+ declare const DEFAULT_DIRECTION_OF_SUPPORTING_ATTACK_OPTIONS: DirectionOfSupportingAttackOptions;
839
+ declare function createDirectionOfSupportingAttack(coordinates: Position[], options?: DirectionOfSupportingAttackOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
840
+ //#endregion
841
+ //#region src/generators/cm14-maneuver-lines/principalDirectionOfFire.d.ts
842
+ /**
843
+ * Configuration options for the Principal Direction of Fire tactical symbol.
844
+ */
845
+ interface PrincipalDirectionOfFireOptions {
846
+ /** Arrowhead length relative to each arm's own length (default: 0.07) */
847
+ arrowheadLengthRatio?: number;
848
+ /** Arrowhead wing spread relative to the arrowhead length (default: 0.67) */
849
+ arrowheadWidthRatio?: number;
850
+ }
851
+ declare const DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS: Required<PrincipalDirectionOfFireOptions>;
852
+ /**
853
+ * Generates a GeoJSON FeatureCollection for a PRINCIPAL DIRECTION OF FIRE
854
+ * tactical symbol: a "V" of arms from the vertex out to the (independent) tips,
855
+ * each ending in an open arrowhead.
856
+ *
857
+ * Renders one arm per tip, so two points (vertex + one tip) draws the single
858
+ * arm being placed — the live feedback after PT 1 — and three points draws the
859
+ * full V. Points beyond the third are ignored (input contract, ADR-0014).
860
+ *
861
+ * @param coordinates - [PT 1 (vertex), PT 2 (tip), PT 3 (tip)]
862
+ * @param options - Arrowhead sizing parameters
863
+ */
864
+ declare function createPrincipalDirectionOfFire(coordinates: Position[], options?: PrincipalDirectionOfFireOptions): FeatureCollection<MultiLineString, Record<string, never>>;
865
+ //#endregion
866
+ //#region src/style.d.ts
867
+ /**
868
+ * Framework-agnostic style hints attached to a `ControlMeasure`.
869
+ *
870
+ * Mirrors the per-feature subset of what map adapters render. The renderer
871
+ * fans these into each emitted feature's `properties.style` ([[StyleHints]]).
872
+ * Adapters merge them over their layer-level style; generator-emitted hints
873
+ * on individual features win over both.
874
+ */
875
+ interface ControlMeasureStyle {
876
+ /**
877
+ * The single symbol color. Control measures are monocolor: one color paints
878
+ * every part, stroked or filled. Input-only — resolved into concrete
879
+ * `strokeColor` / `fillColor` per feature by the renderer and never emitted
880
+ * on output. `strokeColor` / `fillColor` act as optional per-channel
881
+ * overrides. See ADR-0011.
882
+ */
883
+ color?: string;
884
+ strokeColor?: string;
885
+ strokeWidth?: number;
886
+ strokeDash?: number[];
887
+ fillColor?: string;
888
+ /**
889
+ * How a filled part's interior is painted. `"solid"` is explicit so a
890
+ * measure can override a patterned layer default (e.g. a hachure fill set
891
+ * at the façade). Pattern lines are drawn in the resolved fill color —
892
+ * alpha included, there is no separate opacity field. Renderers that
893
+ * cannot draw a pattern degrade to solid.
894
+ */
895
+ fillPattern?: FillPattern;
896
+ }
897
+ /**
898
+ * How a filled part's interior is painted. See `ControlMeasureStyle.fillPattern`.
899
+ */
900
+ type FillPattern = "solid" | "hachure" | "backhachure" | "cross";
901
+ //#endregion
902
+ //#region src/rendered.d.ts
903
+ /**
904
+ * Per-feature style hints carried on `properties.style`.
905
+ *
906
+ * These are *resolved*: `renderControlMeasure` cascades `graphicsStyle` →
907
+ * `cm.style` → any generator pattern hint, then expands the monocolor `color`
908
+ * into concrete `strokeColor` / `fillColor` per feature (see ADR-0011 and
909
+ * `resolveSymbolColor`). Output therefore carries concrete colors, never the
910
+ * input-only `color` key, and a `fillColor` only on parts the generator
911
+ * marked filled.
912
+ *
913
+ * Generators contribute paint *role* and *pattern* (a part is filled; a
914
+ * sub-line is dashed regardless of the user's stroke), never a hue. Adapters
915
+ * merge the resulting `StyleHints` over their layer-level style at draw time.
916
+ */
917
+ interface StyleHints extends ControlMeasureStyle {}
918
+ /**
919
+ * Per-feature properties emitted by `renderControlMeasure`.
920
+ *
921
+ * Stable-id contract — every feature produced by the renderer has:
922
+ * - `feature.id` of the form `${cmId}:${part}:${index}`
923
+ * - `properties.part` matching the `part` segment of the id
924
+ * - `properties.index` matching the `index` segment of the id
925
+ *
926
+ * Adapters rely on this contract to diff renders in place without keeping
927
+ * their own bookkeeping. Use `controlMeasureIdFromFeature` to recover the
928
+ * `cmId` from a picked feature.
929
+ */
930
+ interface FeaturePartProps {
931
+ part: string;
932
+ index: number;
933
+ style?: StyleHints;
934
+ /** Label text emitted by generators (e.g. breach "B"). */
935
+ text?: string;
936
+ /** Label rotation in radians, emitted by generators. */
937
+ rotation?: number;
938
+ /**
939
+ * Horizontal text alignment relative to the label point: `"start"` = the
940
+ * text begins at the point, `"end"` = it ends there. Absent = centered.
941
+ */
942
+ textAnchor?: "start" | "end";
943
+ /** Canonical field key for a text-amplifier label that may be repositioned. */
944
+ amplifierField?: TextAmplifierKey;
945
+ /** Stable key used to persist a user-adjusted anchor for any rendered label. */
946
+ labelPlacementKey?: string;
947
+ /**
948
+ * Screen-anchored label size in CSS pixels — held constant on screen
949
+ * (ADR-0028). Mutually exclusive with `textSizeMeters`; absent both,
950
+ * adapters render their engine default, screen-fixed.
951
+ */
952
+ textSizePixels?: number;
953
+ /**
954
+ * Ground-anchored label text height in projected meters (ADR-0028).
955
+ * Adapters render `clamp(textSizeMeters / resolution, min, max)` px, per
956
+ * their configured clamp band.
957
+ */
958
+ textSizeMeters?: number;
959
+ }
960
+ /**
961
+ * Output of `renderControlMeasure`. A GeoJSON `FeatureCollection` whose
962
+ * features satisfy the `FeaturePartProps` stable-id contract. See ADR-0010.
963
+ */
964
+ type ControlMeasureRender = FeatureCollection<Geometry, FeaturePartProps>;
965
+ /**
966
+ * Recover the originating control measure id (`cmId`) from a feature emitted
967
+ * by `renderControlMeasure`. The feature id must match the stable-id contract
968
+ * `${cmId}:${part}:${index}`; otherwise this throws.
969
+ */
970
+ declare function controlMeasureIdFromFeature(feature: Feature<Geometry, FeaturePartProps> | {
971
+ id?: string | number;
972
+ }): string;
973
+ //#endregion
974
+ //#region src/generators/cm14-maneuver-lines/finalProtectiveFire.d.ts
975
+ /**
976
+ * Configuration options for the Final Protective Fire tactical symbols.
977
+ *
978
+ * Identical to Principal Direction of Fire (arrowhead sizing), plus a filled
979
+ * "blade" running along the inside of one arm.
980
+ */
981
+ interface FinalProtectiveFireOptions {
982
+ /** Arrowhead length relative to each arm's own length (default: 0.07) */
983
+ arrowheadLengthRatio?: number;
984
+ /** Arrowhead wing spread relative to the arrowhead length (default: 0.67) */
985
+ arrowheadWidthRatio?: number;
986
+ /**
987
+ * Blade height (its perpendicular reach into the inside of the V) relative
988
+ * to the bladed arm's own length (default: 0.03).
989
+ */
990
+ bladeHeightRatio?: number;
991
+ }
992
+ declare const DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS: Required<FinalProtectiveFireOptions>;
993
+ type FpfProps = {
994
+ part?: string;
995
+ fill?: true;
996
+ style?: StyleHints;
997
+ };
998
+ declare function createFinalProtectiveFireLeft(coordinates: Position[], options?: FinalProtectiveFireOptions): FeatureCollection<MultiLineString | Polygon, FpfProps>;
999
+ declare function createFinalProtectiveFireRight(coordinates: Position[], options?: FinalProtectiveFireOptions): FeatureCollection<MultiLineString | Polygon, FpfProps>;
1000
+ //#endregion
1001
+ //#region src/generators/cm15-maneuver-areas/encirclement.d.ts
1002
+ /**
1003
+ * Configuration options for the Encirclement control measure. Also carries
1004
+ * the shared {@link AreaLabelOptions} label placement for its Field N (ENY)
1005
+ * marker — the doctrinal example shows only the hostile marker, no name/H/W
1006
+ * rows.
1007
+ */
1008
+ interface EncirclementOptions extends AreaLabelOptions {
1009
+ /**
1010
+ * Spacing between adjacent barbs as a ratio of the symbol's mean radius;
1011
+ * smaller values pack the barbs more densely. The barbs are then distributed
1012
+ * evenly so they close the ring exactly.
1013
+ * @default 0.4
1014
+ */
1015
+ barbSpacingRatio?: number;
1016
+ /**
1017
+ * Barb length (height/amplitude) as a ratio of the symbol's mean radius.
1018
+ * @default 0.16
1019
+ */
1020
+ barbLengthRatio?: number;
1021
+ /**
1022
+ * Round the boundary by curving it through the control points (closed
1023
+ * centripetal Catmull-Rom) before tracing the barbs.
1024
+ * @default true
1025
+ */
1026
+ smooth?: boolean;
1027
+ /**
1028
+ * Number of samples per segment when `smooth` is enabled.
1029
+ * @default 16
1030
+ */
1031
+ smoothResolution?: number;
1032
+ }
1033
+ /**
1034
+ * Default options for the Encirclement control measure. Not `Required<...>`
1035
+ * — the inherited label-size options ({@link AreaLabelOptions}) have no
1036
+ * static default, so this covers only the barb/smoothing options.
1037
+ */
1038
+ declare const DEFAULT_ENCIRCLEMENT_OPTIONS: EncirclementOptions;
1039
+ /**
1040
+ * Creates an Encirclement tactical graphic: a complete smooth boundary ring
1041
+ * with outward arrowhead barbs resting on it. The boundary is an unfilled
1042
+ * Polygon; the barbs are open "V" strokes (a MultiLineString) whose base is the
1043
+ * boundary arc itself. When a Field N (ENY) marker is set, it masks the
1044
+ * boundary with a knockout gap wherever its text box touches the ring
1045
+ * (mirroring Field B's echelon glyph, ADR-0023) — the boundary becomes a
1046
+ * gapped MultiLineString instead of a closed Polygon, and any barb whose
1047
+ * center falls inside the gap is suppressed; the no-`N` case is unaffected.
1048
+ *
1049
+ * @param positions - Area anchor points (>=3); the input contract is enforced
1050
+ * at the render seam (ADR-0014).
1051
+ * @param options - {@link EncirclementOptions}.
1052
+ * @param textAmplifiers - Field N only — rendered as "ENY" markers at the
1053
+ * ring's west and east edges, per the doctrinal hostile example.
1054
+ */
1055
+ declare function createEncirclement(positions: Position[], options?: EncirclementOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1056
+ //#endregion
1057
+ //#region src/generators/cm15-maneuver-areas/area.d.ts
1058
+ /** Configuration options for the Area control measure. */
1059
+ type AreaOptions = LabeledAreaOptions;
1060
+ /**
1061
+ * Creates an Area control measure: a closed area through `positions` labeled
1062
+ * at its center with an un-prefixed `T` (Field T) plus an `N` (Field N) ENY
1063
+ * marker, per {@link labeledAreaFeatures}.
1064
+ */
1065
+ declare function createArea(positions: Position[], options?: AreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1066
+ //#endregion
1067
+ //#region src/generators/cm15-maneuver-areas/area-defense.d.ts
1068
+ interface AreaDefenseOptions extends LabelSizeOptions {
1069
+ /** Angular opening between the two arrow tips, in degrees. */
1070
+ arrowOpeningAngle?: number;
1071
+ /** Angular opening occupied by the AD label, in degrees. */
1072
+ labelOpeningAngle?: number;
1073
+ /** Number of filled outward barbs distributed over both arcs. */
1074
+ barbCount?: number;
1075
+ /** Barb height as a ratio of the radius. */
1076
+ barbLengthRatio?: number;
1077
+ /** Open-arrowhead length as a ratio of the radius. */
1078
+ arrowheadLengthRatio?: number;
1079
+ }
1080
+ declare const DEFAULT_AREA_DEFENSE_OPTIONS: Required<Omit<AreaDefenseOptions, keyof LabelSizeOptions>>;
1081
+ declare function createAreaDefense(coordinates: Position[], options?: AreaDefenseOptions): FeatureCollection<MultiLineString | MultiPolygon | Point>;
1082
+ //#endregion
1083
+ //#region src/generators/cm15-maneuver-areas/assemblyArea.d.ts
1084
+ /** Configuration options for the Assembly area control measure. */
1085
+ type AssemblyAreaOptions = LabeledAreaOptions;
1086
+ /** Default options for the Assembly area control measure. */
1087
+ declare const DEFAULT_ASSEMBLY_AREA_OPTIONS: AssemblyAreaOptions;
1088
+ /**
1089
+ * Creates an Assembly area control measure: a closed area through
1090
+ * `positions` labeled at its center with "AA "-prefixed `T` (Field T) plus
1091
+ * `H`/`W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1092
+ */
1093
+ declare function createAssemblyArea(positions: Position[], options?: AssemblyAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1094
+ //#endregion
1095
+ //#region src/generators/cm15-maneuver-areas/jointTacticalActionArea.d.ts
1096
+ /** Configuration options for the Joint tactical action area control measure. */
1097
+ type JointTacticalActionAreaOptions = LabeledAreaOptions;
1098
+ /** Default options for the Joint tactical action area control measure. */
1099
+ declare const DEFAULT_JOINT_TACTICAL_ACTION_AREA_OPTIONS: JointTacticalActionAreaOptions;
1100
+ /**
1101
+ * Creates a Joint tactical action area control measure: a closed area
1102
+ * through `positions` labeled at its center with "JTAA -"-prefixed `T`
1103
+ * (Field T) plus `H`/`W`/`W1`/`N` amplifier rows, per
1104
+ * {@link labeledAreaFeatures}.
1105
+ */
1106
+ declare function createJointTacticalActionArea(positions: Position[], options?: JointTacticalActionAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1107
+ //#endregion
1108
+ //#region src/generators/cm15-maneuver-areas/submarineActionArea.d.ts
1109
+ /** Configuration options for the Submarine action area control measure. */
1110
+ type SubmarineActionAreaOptions = LabeledAreaOptions;
1111
+ /**
1112
+ * Creates a Submarine action area control measure: a closed area through
1113
+ * `positions` labeled at its center with "SAA -"-prefixed `T` (Field T) plus
1114
+ * `W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1115
+ */
1116
+ declare function createSubmarineActionArea(positions: Position[], options?: SubmarineActionAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1117
+ //#endregion
1118
+ //#region src/generators/cm15-maneuver-areas/submarineGeneratedActionArea.d.ts
1119
+ /** Configuration options for the Submarine-generated action area control measure. */
1120
+ type SubmarineGeneratedActionAreaOptions = LabeledAreaOptions;
1121
+ /**
1122
+ * Creates a Submarine-generated action area control measure: a closed area
1123
+ * through `positions` labeled at its center with "SGSA -"-prefixed `T`
1124
+ * (Field T) plus `W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1125
+ */
1126
+ declare function createSubmarineGeneratedActionArea(positions: Position[], options?: SubmarineGeneratedActionAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1127
+ //#endregion
1128
+ //#region src/generators/cm15-maneuver-areas/dropZone.d.ts
1129
+ /** Configuration options for the Drop zone control measure. */
1130
+ type DropZoneOptions = LabeledAreaOptions;
1131
+ /**
1132
+ * Creates a Drop zone control measure: a closed area through `positions`
1133
+ * labeled at its center with "DZ "-prefixed `T` (Field T) plus an `N`
1134
+ * (Field N) ENY marker, per {@link labeledAreaFeatures}.
1135
+ */
1136
+ declare function createDropZone(positions: Position[], options?: DropZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1137
+ //#endregion
1138
+ //#region src/generators/cm15-maneuver-areas/extractionZone.d.ts
1139
+ /** Configuration options for the Extraction zone control measure. */
1140
+ type ExtractionZoneOptions = LabeledAreaOptions;
1141
+ /**
1142
+ * Creates an Extraction zone control measure: a closed area through
1143
+ * `positions` labeled at its center with "EZ "-prefixed `T` (Field T) plus
1144
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1145
+ */
1146
+ declare function createExtractionZone(positions: Position[], options?: ExtractionZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1147
+ //#endregion
1148
+ //#region src/generators/cm15-maneuver-areas/landingZone.d.ts
1149
+ /** Configuration options for the Landing zone control measure. */
1150
+ type LandingZoneOptions = LabeledAreaOptions;
1151
+ /** Default options for the Landing zone control measure. */
1152
+ declare const DEFAULT_LANDING_ZONE_OPTIONS: LandingZoneOptions;
1153
+ /**
1154
+ * Creates a Landing zone control measure: a closed area through `positions`
1155
+ * labeled at its center with "LZ "-prefixed `T` (Field T) plus `H`/`W`/`W1`/`N`
1156
+ * amplifier rows, per {@link labeledAreaFeatures}.
1157
+ */
1158
+ declare function createLandingZone(positions: Position[], options?: LandingZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1159
+ //#endregion
1160
+ //#region src/generators/cm15-maneuver-areas/pickupZone.d.ts
1161
+ /** Configuration options for the Pickup zone control measure. */
1162
+ type PickupZoneOptions = LabeledAreaOptions;
1163
+ /** Default options for the Pickup zone control measure. */
1164
+ declare const DEFAULT_PICKUP_ZONE_OPTIONS: PickupZoneOptions;
1165
+ /**
1166
+ * Creates a Pickup zone control measure: a closed area through `positions`
1167
+ * labeled at its center with "PZ "-prefixed `T` (Field T) plus `H`/`W`/`W1`/`N`
1168
+ * amplifier rows, per {@link labeledAreaFeatures}.
1169
+ */
1170
+ declare function createPickupZone(positions: Position[], options?: PickupZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1171
+ //#endregion
1172
+ //#region src/generators/cm15-maneuver-areas/assaultPosition.d.ts
1173
+ /** Configuration options for the Assault position control measure. */
1174
+ type AssaultPositionOptions = LabeledAreaOptions;
1175
+ /**
1176
+ * Creates an Assault position control measure: a closed area through
1177
+ * `positions` labeled at its center with "ASLT "-prefixed `T` (Field T) plus
1178
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1179
+ */
1180
+ declare function createAssaultPosition(positions: Position[], options?: AssaultPositionOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1181
+ //#endregion
1182
+ //#region src/generators/cm15-maneuver-areas/attackPosition.d.ts
1183
+ /** Configuration options for the Attack position control measure. */
1184
+ type AttackPositionOptions = LabeledAreaOptions;
1185
+ /**
1186
+ * Creates an Attack position control measure: a closed area through
1187
+ * `positions` labeled at its center with "ATK "-prefixed `T` (Field T) plus
1188
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1189
+ */
1190
+ declare function createAttackPosition(positions: Position[], options?: AttackPositionOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1191
+ //#endregion
1192
+ //#region src/generators/cm15-maneuver-areas/objectiveArea.d.ts
1193
+ /** Configuration options for the Objective area control measure. */
1194
+ type ObjectiveAreaOptions = LabeledAreaOptions;
1195
+ /**
1196
+ * Creates an Objective area control measure: a closed area through
1197
+ * `positions` labeled at its center with "OBJ "-prefixed `T` (Field T) plus
1198
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1199
+ */
1200
+ declare function createObjectiveArea(positions: Position[], options?: ObjectiveAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1201
+ //#endregion
1202
+ //#region src/generators/cm12-command-control-areas/area-of-operations.d.ts
1203
+ /** Configuration options for the Area of operations control measure. */
1204
+ type AreaOfOperationsOptions = LabeledAreaOptions;
1205
+ /** Default options for the Area of operations control measure. */
1206
+ declare const DEFAULT_AREA_OF_OPERATIONS_OPTIONS: AreaOfOperationsOptions;
1207
+ /**
1208
+ * Creates an Area of operations control measure: a closed area through
1209
+ * `positions` labeled at its center with "AO "-prefixed `T` (Field T) plus
1210
+ * `H`/`W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1211
+ */
1212
+ declare function createAreaOfOperations(positions: Position[], options?: AreaOfOperationsOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1213
+ //#endregion
1214
+ //#region src/generators/cm12-command-control-areas/named-area-of-interest.d.ts
1215
+ /** Configuration options for the Named area of interest control measure. */
1216
+ type NamedAreaOfInterestOptions = LabeledAreaOptions;
1217
+ /**
1218
+ * Creates a Named area of interest control measure: a closed area through
1219
+ * `positions` labeled at its center with "NAI "-prefixed `T` (Field T) plus
1220
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1221
+ */
1222
+ declare function createNamedAreaOfInterest(positions: Position[], options?: NamedAreaOfInterestOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1223
+ //#endregion
1224
+ //#region src/generators/cm12-command-control-areas/target-area-of-interest.d.ts
1225
+ /** Configuration options for the Target area of interest control measure. */
1226
+ type TargetAreaOfInterestOptions = LabeledAreaOptions;
1227
+ /**
1228
+ * Creates a Target area of interest control measure: a closed area through
1229
+ * `positions` labeled at its center with "TAI "-prefixed `T` (Field T) plus
1230
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1231
+ */
1232
+ declare function createTargetAreaOfInterest(positions: Position[], options?: TargetAreaOfInterestOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1233
+ //#endregion
1234
+ //#region src/generators/cm12-command-control-areas/airfield-zone.d.ts
1235
+ /** Configuration options for the Airfield zone control measure. */
1236
+ interface AirfieldZoneOptions extends LabeledAreaOptions {
1237
+ /**
1238
+ * The runway glyph's long line, as a ratio of the ring's projected
1239
+ * bounding-box width (full length, not half).
1240
+ * @default 0.55
1241
+ */
1242
+ glyphSizeRatio?: number;
1243
+ }
1244
+ /**
1245
+ * Creates an Airfield zone control measure: a closed area through
1246
+ * `positions` with a runway glyph (two crossed lines forming a shallow
1247
+ * asymmetric X) centered on the ring, and Field H placed outside the area to
1248
+ * the east when set.
1249
+ *
1250
+ * @param positions - Area anchor points (≥3); the input contract is enforced
1251
+ * at the render seam (ADR-0014).
1252
+ * @param options - {@link AirfieldZoneOptions}.
1253
+ * @param textAmplifiers - Field H (placed east of the area) plus an optional
1254
+ * Field N "ENY" hostile marker on the west/east edges.
1255
+ */
1256
+ declare function createAirfieldZone(positions: Position[], options?: AirfieldZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1257
+ //#endregion
1258
+ //#region src/generators/cm12-command-control-areas/echelon-labeled-area.d.ts
1259
+ /**
1260
+ * Configuration options shared by Base Camp and Guerrilla Base: the full L-15
1261
+ * label placement ({@link LabeledAreaOptions}) plus Battle Position's Field B
1262
+ * echelon knobs.
1263
+ */
1264
+ interface EchelonLabeledAreaOptions extends LabeledAreaOptions {
1265
+ /**
1266
+ * Field B echelon straddling the boundary. `"none"` (the default — the
1267
+ * standard's examples show no echelon glyph), empty, or unknown renders no
1268
+ * glyph and leaves the boundary unaffected by echelon masking.
1269
+ * @default "none"
1270
+ */
1271
+ echelon?: string;
1272
+ /**
1273
+ * Echelon glyph height in meters (ground-anchored). Ignored when
1274
+ * `echelonSizePixels` is supplied together with `metersPerPixel`.
1275
+ * @default 750
1276
+ */
1277
+ echelonSize?: number;
1278
+ /**
1279
+ * Echelon glyph height in screen pixels (screen-anchored). Resolved to
1280
+ * meters against `metersPerPixel`; bakes to a meter size on draw/edit
1281
+ * commit (ADR-0020).
1282
+ * @default 16
1283
+ */
1284
+ echelonSizePixels?: number;
1285
+ /**
1286
+ * Gap left on each side of the echelon glyph, as a ratio of the glyph
1287
+ * height. `0` butts the boundary against the glyph; larger values widen
1288
+ * the break.
1289
+ * @default 0.3
1290
+ */
1291
+ echelonPadding?: number;
1292
+ /**
1293
+ * Slides the echelon along the boundary, as a signed fraction of the total
1294
+ * perimeter measured from its default anchor on the bottom edge.
1295
+ * @default 0
1296
+ */
1297
+ echelonPosition?: number;
1298
+ /**
1299
+ * Absolute anchor for the echelon glyph, as a fraction of the total
1300
+ * perimeter measured from the ring seam, wrapped into `[0, 1)`. See Battle
1301
+ * Position's `echelonAnchor` (ADR-0023) — edit controllers freeze this via
1302
+ * the `freezeOrientation` hook the moment a rotate gesture starts.
1303
+ */
1304
+ echelonAnchor?: number;
1305
+ /**
1306
+ * Meters-per-pixel at the current zoom/latitude. Stamped by the host when
1307
+ * the measure is screen-anchored; required to resolve `echelonSizePixels`.
1308
+ */
1309
+ metersPerPixel?: number;
1310
+ }
1311
+ //#endregion
1312
+ //#region src/generators/cm12-command-control-areas/base-camp.d.ts
1313
+ /** Configuration options for the Base camp control measure. */
1314
+ type BaseCampOptions = EchelonLabeledAreaOptions;
1315
+ /**
1316
+ * Creates a Base camp control measure: a closed area through `positions`
1317
+ * labeled at its center with "BC "-prefixed `T` (Field T) plus `H`/`W`/`W1`/`N`
1318
+ * amplifier rows, and an optional Field B echelon glyph straddling the
1319
+ * boundary, per {@link echelonLabeledAreaFeatures}.
1320
+ */
1321
+ declare function createBaseCamp(positions: Position[], options?: BaseCampOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | MultiPolygon | Point>;
1322
+ //#endregion
1323
+ //#region src/generators/cm12-command-control-areas/guerrilla-base.d.ts
1324
+ /** Configuration options for the Guerrilla base control measure. */
1325
+ type GuerrillaBaseOptions = EchelonLabeledAreaOptions;
1326
+ /**
1327
+ * Creates a Guerrilla base control measure: a closed area through
1328
+ * `positions` labeled at its center with "GB "-prefixed `T` (Field T) plus
1329
+ * `H`/`W`/`W1`/`N` amplifier rows, and an optional Field B echelon glyph
1330
+ * straddling the boundary, per {@link echelonLabeledAreaFeatures}.
1331
+ */
1332
+ declare function createGuerrillaBase(positions: Position[], options?: GuerrillaBaseOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | MultiPolygon | Point>;
1333
+ //#endregion
1334
+ //#region src/generators/cm12-command-control-areas/generic-c2-area.d.ts
1335
+ /** Configuration options for the Generic command and control area control measure. */
1336
+ type GenericC2AreaOptions = LabeledAreaOptions;
1337
+ /**
1338
+ * Creates a Generic command and control area control measure: a closed area
1339
+ * through `positions` labeled at its center with the bare `T` (Field T) plus
1340
+ * `H`/`W`/`W1`/`N` amplifier rows — no prefix, per {@link labeledAreaFeatures}.
1341
+ */
1342
+ declare function createGenericC2Area(positions: Position[], options?: GenericC2AreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1343
+ //#endregion
1344
+ //#region src/attack-utils.d.ts
1345
+ interface AttackOptions {
1346
+ shaftWidthRatio?: number;
1347
+ smooth?: boolean;
1348
+ smoothResolution?: number;
1349
+ }
1350
+ /**
1351
+ * Calculates the relative metrics (longitudinal and lateral) of the width point
1352
+ * relative to the Tip-Neck axis.
1353
+ *
1354
+ * @param pts - Array of positions [Tip, Neck, ..., WidthPoint]
1355
+ * @returns { longitudinal: number, lateral: number } | null
1356
+ */
1357
+ declare function calculateMetrics(pts: Position[]): {
1358
+ longitudinal: number;
1359
+ lateral: number;
1360
+ } | null;
1361
+ /**
1362
+ * Computes an initial Width Point based on the Tip and Neck positions.
1363
+ * It places the point perpendicular to the neck at a default distance relative to the length.
1364
+ *
1365
+ * @param tip - Tip position (Lon/Lat)
1366
+ * @param neck - Neck position (Lon/Lat)
1367
+ * @returns Width Point position (Lon/Lat)
1368
+ */
1369
+ declare function computeInitialWidthPoint(tip: Position, neck: Position): Position;
1370
+ //#endregion
1371
+ //#region src/generators/cm15-maneuver-areas/mainAttack.d.ts
1372
+ declare const DEFAULT_MAIN_ATTACK_OPTIONS: Required<AttackOptions>;
1373
+ type MainAttackOptions = AttackOptions;
1374
+ /**
1375
+ * Generates a GeoJSON FeatureCollection for a Main Attack tactical symbol.
1376
+ *
1377
+ * The symbol consists of a single MultiLineString feature containing:
1378
+ * 1. **Arrowhead**: A line forming a "chevron" or "roof" shape.
1379
+ * 2. **Shaft**: Two parallel lines behind the arrow.
1380
+ *
1381
+ * The shaft is calculated to terminate exactly where it touches the inner walls
1382
+ * of the arrowhead, creating a seamless connection.
1383
+ *
1384
+ * @param coordinates - An array of GeoJSON Positions (Lon/Lat).
1385
+ * Minimum 3 points required.
1386
+ * **Order matters:** * - Index 0: **Tip** (The sharp point of the arrow)
1387
+ * - Index 1 to N-2: **Spine** (The path the shaft follows)
1388
+ * - Index N-1: **Width Control** (Determines the width of the arrowhead)
1389
+ * @param options - Configuration for ratios and properties.
1390
+ * @returns A GeoJSON FeatureCollection containing a single MultiLineString.
1391
+ */
1392
+ declare function createMainAttack(coordinates: Position[], options?: MainAttackOptions): FeatureCollection<MultiLineString>;
1393
+ //#endregion
1394
+ //#region src/generators/cm15-maneuver-areas/supportingAttack.d.ts
1395
+ type SupportingAttackOptions = AttackOptions;
1396
+ declare const DEFAULT_SUPPORTING_ATTACK_OPTIONS: Required<SupportingAttackOptions>;
1397
+ /**
1398
+ * Generates a GeoJSON FeatureCollection for a Supporting Attack tactical symbol.
1399
+ *
1400
+ * The symbol differs from Main Attack in that it is a single LineString
1401
+ * outlining the arrow shape, rather than a filled Polygon header + Shaft lines.
1402
+ *
1403
+ * @param coordinates - An array of GeoJSON Positions.
1404
+ * @param options - Configuration options.
1405
+ * @returns A GeoJSON FeatureCollection<LineString>.
1406
+ */
1407
+ declare function createSupportingAttack(coordinates: Position[], options?: SupportingAttackOptions): FeatureCollection<LineString>;
1408
+ //#endregion
1409
+ //#region src/generators/cm99-generic-arrows/classicArrow.d.ts
1410
+ /**
1411
+ * A plain, clean arrow for illustrations — not a doctrinal symbol. The shaft is
1412
+ * a straight polyline through the drawn control points (Line1 contract) and the
1413
+ * tip carries a solid triangular arrowhead. No wobble, no curve: the canonical
1414
+ * "draw an arrow" graphic.
1415
+ */
1416
+ /**
1417
+ * Arrowhead silhouette:
1418
+ * - `triangle` — solid triangle with a flat back (the default).
1419
+ * - `barbed` — swept-back barbs with a forward notch (classic arrowhead).
1420
+ * - `concave` — a sharper barbed head with a deep forward notch.
1421
+ * - `diamond` — a rhombus, widest at its middle.
1422
+ * - `harpoon` — an asymmetric single-sided barb.
1423
+ * - `swallowtail` — barbs that sweep back into two trailing tails.
1424
+ * - `chevron` — a thick hollow "V".
1425
+ * - `circle` — a round dot terminator.
1426
+ * - `tee` — a flat crossbar terminator (no point).
1427
+ * - `open` — an unfilled "V", drawn as two strokes meeting at the tip.
1428
+ */
1429
+ type ClassicArrowHeadStyle = "triangle" | "barbed" | "concave" | "diamond" | "harpoon" | "swallowtail" | "chevron" | "circle" | "tee" | "open";
1430
+ interface ClassicArrowOptions {
1431
+ /** Arrowhead silhouette. */
1432
+ arrowheadStyle?: ClassicArrowHeadStyle;
1433
+ /** Round the shaft's corners by curving it through the control points. */
1434
+ smooth?: boolean;
1435
+ /** Number of samples per segment when smooth mode is enabled. */
1436
+ smoothResolution?: number;
1437
+ /** Arrowhead length as a fraction of the total path length. */
1438
+ arrowheadLengthRatio?: number;
1439
+ /** Arrowhead base width as a fraction of the total path length. */
1440
+ arrowheadWidthRatio?: number;
1441
+ }
1442
+ declare const DEFAULT_CLASSIC_ARROW_OPTIONS: Required<ClassicArrowOptions>;
1443
+ /**
1444
+ * Generates a GeoJSON FeatureCollection for the Classic Arrow: a shaft
1445
+ * LineString (trimmed so it doesn't poke through the head) plus a head feature
1446
+ * whose silhouette follows `arrowheadStyle` — a filled Polygon for the solid heads,
1447
+ * or an open "V" LineString for `open`.
1448
+ */
1449
+ declare function createClassicArrow(coordinates: Position[], options?: ClassicArrowOptions): FeatureCollection<LineString | Polygon, {
1450
+ part: "shaft" | "head";
1451
+ fill?: boolean;
1452
+ style?: StyleHints;
1453
+ }>;
1454
+ //#endregion
1455
+ //#region src/generators/cm99-generic-arrows/blockArrow.d.ts
1456
+ /**
1457
+ * A solid "block" arrow for illustrations — not a doctrinal symbol. The whole
1458
+ * arrow is one filled polygon: a shaft band of controllable width that runs
1459
+ * through the drawn Axis1 spine and flares into a wider triangular head at the
1460
+ * tip. Axis1 control points are ordered `[tip, neck, ...spine, width]`.
1461
+ */
1462
+ /**
1463
+ * Arrowhead silhouette (all carved from the one filled body):
1464
+ * - `triangle` — a flat-backed triangular head (the default).
1465
+ * - `barbed` — swept-back barbs with the shaft entering at a forward notch.
1466
+ * - `concave` — a sharper barbed head with a deeper notch.
1467
+ * - `diamond` — a kite that flares to its widest mid-head.
1468
+ * - `harpoon` — an asymmetric single-sided barb.
1469
+ * - `swallowtail` — barbs that sweep back into two trailing tails.
1470
+ * - `tee` — a flat crossbar terminator (no point).
1471
+ */
1472
+ type BlockArrowHeadStyle = "triangle" | "barbed" | "concave" | "diamond" | "harpoon" | "swallowtail" | "tee";
1473
+ interface BlockArrowOptions {
1474
+ /** Shaft band width as a fraction of the total path length. */
1475
+ shaftWidthRatio?: number;
1476
+ /** Arrowhead silhouette. */
1477
+ arrowheadStyle?: BlockArrowHeadStyle;
1478
+ /** Arrowhead base width as a fraction of the total path length. */
1479
+ arrowheadWidthRatio?: number;
1480
+ /** Arrowhead length as a fraction of the total path length. */
1481
+ arrowheadLengthRatio?: number;
1482
+ /** Round the shaft's corners by curving it through the control points. */
1483
+ smooth?: boolean;
1484
+ /** Number of samples per segment when smooth mode is enabled. */
1485
+ smoothResolution?: number;
1486
+ /** Fill the body solid; when false the arrow is drawn as an outline only. */
1487
+ filled?: boolean;
1488
+ }
1489
+ declare const DEFAULT_BLOCK_ARROW_OPTIONS: Required<BlockArrowOptions>;
1490
+ /**
1491
+ * Generates a GeoJSON FeatureCollection for the Block Arrow: a single filled
1492
+ * Polygon whose outline runs up the left side of the shaft, around the head
1493
+ * (whose silhouette follows `arrowheadStyle`) to the tip and back, then down the
1494
+ * right side of the shaft.
1495
+ */
1496
+ declare function createBlockArrow(coordinates: Position[], options?: BlockArrowOptions): FeatureCollection<Polygon, {
1497
+ part: "body";
1498
+ fill: boolean;
1499
+ }>;
1500
+ //#endregion
1501
+ //#region src/generators/cm99-generic-graphics/params.d.ts
1502
+ interface SmoothPathOptions {
1503
+ /** Curve the rendered path through the unchanged control points. */
1504
+ smooth?: boolean;
1505
+ /** Number of samples per segment when smoothing is enabled. */
1506
+ smoothResolution?: number;
1507
+ }
1508
+ interface FilledAreaOptions {
1509
+ /** Fill the polygon interior; false renders only its outline. */
1510
+ filled?: boolean;
1511
+ }
1512
+ //#endregion
1513
+ //#region src/generators/cm99-generic-graphics/line.d.ts
1514
+ type GenericLineOptions = SmoothPathOptions;
1515
+ declare const DEFAULT_GENERIC_LINE_OPTIONS: Required<GenericLineOptions>;
1516
+ declare function createGenericLine(coordinates: Position[], options?: GenericLineOptions): FeatureCollection<LineString>;
1517
+ //#endregion
1518
+ //#region src/generators/cm99-generic-graphics/polygon.d.ts
1519
+ interface GenericPolygonOptions extends SmoothPathOptions, FilledAreaOptions {}
1520
+ declare const DEFAULT_GENERIC_POLYGON_OPTIONS: Required<GenericPolygonOptions>;
1521
+ declare function createGenericPolygon(coordinates: Position[], options?: GenericPolygonOptions): FeatureCollection<Polygon, {
1522
+ part: string;
1523
+ fill: boolean;
1524
+ }>;
1525
+ //#endregion
1526
+ //#region src/generators/cm99-generic-graphics/rectangle.d.ts
1527
+ type GenericRectangleOptions = FilledAreaOptions;
1528
+ declare const DEFAULT_GENERIC_RECTANGLE_OPTIONS: Required<GenericRectangleOptions>;
1529
+ declare function createGenericRectangle(coordinates: Position[], options?: GenericRectangleOptions): FeatureCollection<Polygon, {
1530
+ part: string;
1531
+ fill: boolean;
1532
+ }>;
1533
+ //#endregion
1534
+ //#region src/generators/cm99-generic-graphics/circle.d.ts
1535
+ type GenericCircleOptions = FilledAreaOptions;
1536
+ declare const DEFAULT_GENERIC_CIRCLE_OPTIONS: Required<GenericCircleOptions>;
1537
+ declare function createGenericCircle(coordinates: Position[], options?: GenericCircleOptions): FeatureCollection<Polygon, {
1538
+ part: string;
1539
+ fill: boolean;
1540
+ }>;
1541
+ //#endregion
1542
+ //#region src/generators/cm15-maneuver-areas/airborneAttack.d.ts
1543
+ type AirborneAttackOptions = AttackOptions;
1544
+ declare const DEFAULT_AIRBORNE_ATTACK_OPTIONS: Required<AirborneAttackOptions>;
1545
+ /**
1546
+ * Generates a GeoJSON FeatureCollection for an Airborne Attack tactical symbol.
1547
+ *
1548
+ * The symbol is similar to Supporting Attack but features a crossover point
1549
+ * between the shaft and the head (Points 1 and 2/Neck).
1550
+ *
1551
+ * @param coordinates - An array of GeoJSON Positions.
1552
+ * @param options - Configuration options.
1553
+ * @returns A GeoJSON FeatureCollection<LineString>.
1554
+ */
1555
+ declare function createAirborneAttack(coordinates: Position[], options?: AirborneAttackOptions): FeatureCollection<LineString>;
1556
+ //#endregion
1557
+ //#region src/generators/cm15-maneuver-areas/attackHelicopter.d.ts
1558
+ interface AttackHelicopterOptions extends AttackOptions {
1559
+ symbolHeightRatio?: number;
1560
+ triangleSizeRatio?: number;
1561
+ bottomBarWidthRatio?: number;
1562
+ bowtieWidthRatio?: number;
1563
+ }
1564
+ declare const DEFAULT_ATTACK_HELICOPTER_OPTIONS: Required<AttackHelicopterOptions>;
1565
+ /**
1566
+ * Generates a GeoJSON FeatureCollection for an Attack Helicopter tactical symbol.
1567
+ *
1568
+ * The symbol is based on the Airborne Attack (bow tie) geometry but features
1569
+ * an additional symbol (vertical line + triangle) at the crossover point.
1570
+ *
1571
+ * @param coordinates - An array of GeoJSON Positions.
1572
+ * @param options - Configuration options.
1573
+ * @returns A GeoJSON FeatureCollection containing the main graphic and the symbol.
1574
+ */
1575
+ declare function createAttackHelicopter(coordinates: Position[], options?: AttackHelicopterOptions): FeatureCollection<LineString | Polygon>;
1576
+ //#endregion
1577
+ //#region src/generators/cm15-maneuver-areas/supportByFire.d.ts
1578
+ interface SupportByFireOptions {
1579
+ arrowheadWidthRatio?: number;
1580
+ rearLineLengthRatio?: number;
1581
+ rearLineAngle?: number;
1582
+ }
1583
+ declare const DEFAULT_SUPPORT_BY_FIRE_OPTIONS: Required<SupportByFireOptions>;
1584
+ /**
1585
+ * Generates a GeoJSON FeatureCollection for a Support By Fire tactical graphic.
1586
+ *
1587
+ * Input:
1588
+ * - PT1: Left Base
1589
+ * - PT2: Right Base
1590
+ * - PT3: Left Tip
1591
+ * - PT4: Right Tip
1592
+ */
1593
+ declare function createSupportByFire(coordinates: Position[], options?: SupportByFireOptions): FeatureCollection<LineString>;
1594
+ //#endregion
1595
+ //#region src/generators/cm15-maneuver-areas/attackByFire.d.ts
1596
+ interface AttackByFireOptions {
1597
+ arrowheadWidthRatio?: number;
1598
+ rearLineLengthRatio?: number;
1599
+ rearLineAngle?: number;
1600
+ }
1601
+ declare const DEFAULT_ATTACK_BY_FIRE_OPTIONS: Required<AttackByFireOptions>;
1602
+ /**
1603
+ * Generates a GeoJSON FeatureCollection for an Attack By Fire tactical graphic.
1604
+ *
1605
+ * Input:
1606
+ * - PT1: Arrow Tip (Target)
1607
+ * - PT2: Left Base
1608
+ * - PT3: Right Base
1609
+ *
1610
+ * Logic:
1611
+ * - Shaft: Midpoint(PT2, PT3) -> PT1
1612
+ * - Base Line: PT2 -> PT3
1613
+ * - Wings: Splayed out from PT2 and PT3
1614
+ */
1615
+ declare function createAttackByFire(coordinates: Position[], options?: AttackByFireOptions): FeatureCollection<LineString>;
1616
+ //#endregion
1617
+ //#region src/generators/cm14-maneuver-lines/flot.d.ts
1618
+ /**
1619
+ * Configuration options for the FLOT (Forward Line of Own Troops) geometry.
1620
+ */
1621
+ interface FLOTOptions extends SmoothLineOptions, LineLabelOptions {
1622
+ /**
1623
+ * The radius of the semicircular arcs in meters.
1624
+ * Semicircles are placed tangent to each other (diameter = 2 * radius).
1625
+ * This is ignored if radiusPixels is provided along with metersPerPixel.
1626
+ * @default 50
1627
+ */
1628
+ radius?: number;
1629
+ /**
1630
+ * The radius of the semi-circular arcs in pixels.
1631
+ * When provided along with metersPerPixel, the actual meter radius is calculated
1632
+ * dynamically to maintain consistent visual size on screen.
1633
+ * Takes precedence over radius when metersPerPixel is also provided.
1634
+ * @default 10
1635
+ */
1636
+ radiusPixels?: number;
1637
+ /**
1638
+ * The meters-per-pixel ratio at the current zoom level and latitude.
1639
+ * Required when using radiusPixels for zoom-aware sizing.
1640
+ * Can be obtained from the map view's resolution or calculated using getMetersPerPixel().
1641
+ */
1642
+ metersPerPixel?: number;
1643
+ /**
1644
+ * The number of points used to render each individual semi-circle.
1645
+ * Higher values create smoother arcs.
1646
+ * @default 16
1647
+ */
1648
+ arcSegments?: number;
1649
+ }
1650
+ /**
1651
+ * Default options for the FLOT graphic.
1652
+ */
1653
+ declare const DEFAULT_FLOT_OPTIONS: Required<Omit<FLOTOptions, keyof LineLabelOptions>>;
1654
+ /**
1655
+ * Creates a FLOT (Forward Line of Own Troops) tactical graphic.
1656
+ *
1657
+ * Generates a scalloped/arc line representing the forward edge of friendly forces.
1658
+ * The line consists of semi-circular arcs that bulge perpendicular to the base path,
1659
+ * creating a distinctive visual pattern used in military tactical graphics.
1660
+ *
1661
+ * @param positions - Array of GeoJSON positions defining the base path
1662
+ * @param options - Configuration options for the graphic
1663
+ * @returns A GeoJSON FeatureCollection containing the scalloped LineString
1664
+ *
1665
+ * @example
1666
+ * ```typescript
1667
+ * const flot = createFLOT(
1668
+ * [[-122.4194, 37.7749], [-122.4100, 37.7800], [-122.4000, 37.7750]],
1669
+ * { radius: 100, arcSegments: 20 }
1670
+ * );
1671
+ * ```
1672
+ */
1673
+ declare function createFLOT(positions: Position[], options?: FLOTOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1674
+ //#endregion
1675
+ //#region src/generators/cm14-maneuver-lines/phase-line.d.ts
1676
+ /** Configuration options for the Phase line control measure. */
1677
+ interface PhaseLineOptions extends LineLabelOptions, SmoothLineOptions {
1678
+ /**
1679
+ * Prefix the end labels with "PL" (`"PL ECHO"`, or a bare `"PL"` when no
1680
+ * designation is set). When `false`, the label is the bare designation
1681
+ * (`Field T`) alone, and the line carries no label at all when `T` is empty.
1682
+ * @default true
1683
+ */
1684
+ includePrefix?: boolean;
1685
+ }
1686
+ /** Default options for the Phase line control measure. */
1687
+ declare const DEFAULT_PHASE_LINE_OPTIONS: PhaseLineOptions;
1688
+ /**
1689
+ * Creates a Phase line control measure: a polyline through `positions`
1690
+ * labeled at each end with `T` (optionally "PL"-prefixed).
1691
+ */
1692
+ declare function createPhaseLine(positions: Position[], options?: PhaseLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1693
+ //#endregion
1694
+ //#region src/generators/cm14-maneuver-lines/handover-line.d.ts
1695
+ /** Configuration options for the Handover line control measure. */
1696
+ interface HandoverLineOptions extends LineLabelOptions, SmoothLineOptions {
1697
+ /**
1698
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
1699
+ * the line, additive to the fixed "HOL" labels. Empty or whitespace-only
1700
+ * renders no label.
1701
+ * @default none
1702
+ */
1703
+ phaseLineName?: string;
1704
+ /**
1705
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
1706
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
1707
+ * Phase Line itself, this measure already carries its own fixed "HOL"
1708
+ * label, so there is no bare "PL" fallback.
1709
+ * @default true
1710
+ */
1711
+ includePrefix?: boolean;
1712
+ }
1713
+ /** Default options for the Handover line control measure. */
1714
+ declare const DEFAULT_HANDOVER_LINE_OPTIONS: HandoverLineOptions;
1715
+ /**
1716
+ * Creates a Handover line control measure: a polyline through `positions`
1717
+ * labeled "HOL" above the line near each end.
1718
+ */
1719
+ declare function createHandoverLine(positions: Position[], options?: HandoverLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1720
+ //#endregion
1721
+ //#region src/generators/cm14-maneuver-lines/battle-handover-line.d.ts
1722
+ /** Configuration options for the Battle handover line control measure. */
1723
+ interface BattleHandoverLineOptions extends LineLabelOptions, SmoothLineOptions {
1724
+ /**
1725
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
1726
+ * the line, additive to the fixed "BHL" labels. Empty or whitespace-only
1727
+ * renders no label.
1728
+ * @default none
1729
+ */
1730
+ phaseLineName?: string;
1731
+ /**
1732
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
1733
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
1734
+ * Phase Line itself, this measure already carries its own fixed "BHL"
1735
+ * label, so there is no bare "PL" fallback.
1736
+ * @default true
1737
+ */
1738
+ includePrefix?: boolean;
1739
+ }
1740
+ /** Default options for the Battle handover line control measure. */
1741
+ declare const DEFAULT_BATTLE_HANDOVER_LINE_OPTIONS: BattleHandoverLineOptions;
1742
+ /**
1743
+ * Creates a Battle handover line control measure: a polyline through
1744
+ * `positions` labeled "BHL" above the line near each end.
1745
+ */
1746
+ declare function createBattleHandoverLine(positions: Position[], options?: BattleHandoverLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1747
+ //#endregion
1748
+ //#region src/generators/cm34-mission-tasks/block.d.ts
1749
+ interface BlockMissionTaskOptions {
1750
+ /** Gap for the 'B' label as a ratio of the front length (default: 0.2) */
1751
+ labelGapRatio?: number;
1752
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
1753
+ labelSize?: number;
1754
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1755
+ labelSizePixels?: number;
1756
+ }
1757
+ declare const DEFAULT_BLOCK_MISSION_TASK_OPTIONS: Required<Omit<BlockMissionTaskOptions, "labelSize" | "labelSizePixels">>;
1758
+ /**
1759
+ * Generates a GeoJSON FeatureCollection for a BLOCK mission task symbol (340100).
1760
+ *
1761
+ * Uses the same T-shape geometry as the protection-area Block symbol, with a
1762
+ * "B" label centered on the shaft.
1763
+ *
1764
+ * @param coordinates - [PT. 1, PT. 2, optional PT. 3] as Position arrays
1765
+ * @param options - Configuration options
1766
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
1767
+ */
1768
+ declare function createBlockMissionTaskSymbol(coordinates: Position[], options?: BlockMissionTaskOptions): FeatureCollection<MultiLineString | Point>;
1769
+ //#endregion
1770
+ //#region src/generators/cm34-mission-tasks/breach.d.ts
1771
+ /**
1772
+ * Configuration options for the BREACH tactical symbol.
1773
+ */
1774
+ interface BreachOptions {
1775
+ /** Tick mark length ratio relative to front opening (default: 0.15) */
1776
+ tickLengthRatio?: number;
1777
+ /** Tick mark angle in degrees from perpendicular (default: 45) */
1778
+ tickAngle?: number;
1779
+ /** Gap for the 'B' label as a ratio of the front length (default: 0.2) */
1780
+ labelGapRatio?: number;
1781
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
1782
+ labelSize?: number;
1783
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1784
+ labelSizePixels?: number;
1785
+ }
1786
+ /**
1787
+ * Default options for the BREACH symbol.
1788
+ */
1789
+ declare const DEFAULT_BREACH_OPTIONS: Required<Omit<BreachOptions, "labelSize" | "labelSizePixels">>;
1790
+ /**
1791
+ * Generates a GeoJSON FeatureCollection for a BREACH mission task symbol (340200).
1792
+ *
1793
+ * A three-sided bracket (see {@link createBracketSymbol}) whose front opening
1794
+ * endpoints terminate in tick marks pointing **outward** (away from the rear
1795
+ * "B" line).
1796
+ *
1797
+ * @param coordinates - [PT. 1, PT. 2, PT. 3] as Position arrays
1798
+ * @param options - Configuration options
1799
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
1800
+ */
1801
+ declare function createBreachSymbol(coordinates: Position[], options?: BreachOptions): FeatureCollection<MultiLineString | Point>;
1802
+ //#endregion
1803
+ //#region src/generators/cm34-mission-tasks/bypass.d.ts
1804
+ /**
1805
+ * Configuration options for the BYPASS tactical symbol.
1806
+ */
1807
+ interface BypassOptions {
1808
+ /** Arrowhead length ratio relative to front opening (default: 0.2) */
1809
+ arrowheadLengthRatio?: number;
1810
+ /** Gap for the 'B' label as a ratio of the front length (default: 0.2) */
1811
+ labelGapRatio?: number;
1812
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
1813
+ labelSize?: number;
1814
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1815
+ labelSizePixels?: number;
1816
+ }
1817
+ /**
1818
+ * Default options for the BYPASS symbol.
1819
+ */
1820
+ declare const DEFAULT_BYPASS_OPTIONS: Required<Omit<BypassOptions, "labelSize" | "labelSizePixels">>;
1821
+ /**
1822
+ * Generates a GeoJSON FeatureCollection for a BYPASS mission task symbol (340300).
1823
+ *
1824
+ * A three-sided bracket (see {@link createBracketSymbol}) with a "B" label on
1825
+ * the rear line, whose front opening endpoints terminate in outward-flaring
1826
+ * chevron arrowheads instead of tick marks.
1827
+ *
1828
+ * @param coordinates - [PT. 1, PT. 2, PT. 3] as Position arrays
1829
+ * @param options - Configuration options
1830
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
1831
+ */
1832
+ declare function createBypassSymbol(coordinates: Position[], options?: BypassOptions): FeatureCollection<MultiLineString | Point>;
1833
+ //#endregion
1834
+ //#region src/generators/cm34-mission-tasks/canalize.d.ts
1835
+ /**
1836
+ * Configuration options for the CANALIZE tactical symbol.
1837
+ */
1838
+ interface CanalizeOptions {
1839
+ /** Tick mark length ratio relative to front opening (default: 0.15) */
1840
+ tickLengthRatio?: number;
1841
+ /** Tick mark angle in degrees from perpendicular (default: 45) */
1842
+ tickAngle?: number;
1843
+ /** Gap for the 'C' label as a ratio of the front length (default: 0.2) */
1844
+ labelGapRatio?: number;
1845
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
1846
+ labelSize?: number;
1847
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1848
+ labelSizePixels?: number;
1849
+ }
1850
+ /**
1851
+ * Default options for the CANALIZE symbol.
1852
+ */
1853
+ declare const DEFAULT_CANALIZE_OPTIONS: Required<Omit<CanalizeOptions, "labelSize" | "labelSizePixels">>;
1854
+ /**
1855
+ * Generates a GeoJSON FeatureCollection for a CANALIZE mission task symbol (340400).
1856
+ *
1857
+ * A three-sided bracket (see {@link createBracketSymbol}) whose front opening
1858
+ * endpoints terminate in tick marks pointing **inward** (toward the rear "C"
1859
+ * line), opposite BREACH's outward-facing ticks.
1860
+ *
1861
+ * @param coordinates - [PT. 1, PT. 2, PT. 3] as Position arrays
1862
+ * @param options - Configuration options
1863
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
1864
+ */
1865
+ declare function createCanalizeSymbol(coordinates: Position[], options?: CanalizeOptions): FeatureCollection<MultiLineString | Point>;
1866
+ //#endregion
1867
+ //#region src/generators/cm34-mission-tasks/clear.d.ts
1868
+ /**
1869
+ * Configuration options for the CLEAR tactical mission task symbol.
1870
+ */
1871
+ interface ClearOptions {
1872
+ /**
1873
+ * Padding between the vertical line's endpoints and the outer arrows, as a
1874
+ * ratio of the symbol height. Insets the top and bottom arrows so they sit
1875
+ * clear of PT. 1 / PT. 2 (default: 0.15).
1876
+ */
1877
+ arrowInsetRatio?: number;
1878
+ /** Arrowhead depth (toward the rear) as a ratio of the symbol height (default: 0.15). */
1879
+ arrowheadLengthRatio?: number;
1880
+ /** Arrowhead width (along the vertical line) as a ratio of the symbol height (default: 0.2). */
1881
+ arrowheadWidthRatio?: number;
1882
+ /** Gap for the 'C' label as a ratio of the shaft length (default: 0.2). */
1883
+ labelGapRatio?: number;
1884
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
1885
+ labelSize?: number;
1886
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1887
+ labelSizePixels?: number;
1888
+ }
1889
+ /**
1890
+ * Default options for the CLEAR symbol.
1891
+ */
1892
+ declare const DEFAULT_CLEAR_OPTIONS: Required<Omit<ClearOptions, "labelSize" | "labelSizePixels">>;
1893
+ /**
1894
+ * Generates a GeoJSON FeatureCollection for a CLEAR mission task symbol (340500).
1895
+ *
1896
+ * A vertical line (PT. 1 → PT. 2) with three arrows pointing at it,
1897
+ * perpendicular to the line. The arrows come from the rear — the side PT. 3
1898
+ * sits on — and their tips touch the vertical line; each carries a shaft
1899
+ * reaching back to the rear. The arrows are evenly spaced along the line, so
1900
+ * the middle arrow's tip sits at the midpoint of the vertical line and its
1901
+ * shaft carries the 'C' glyph. The arrows stay perpendicular to the vertical
1902
+ * line at any rotation.
1903
+ *
1904
+ * Input Points:
1905
+ * - PT. 1: Top endpoint of the vertical line
1906
+ * - PT. 2: Bottom endpoint of the vertical line — defines height with PT. 1
1907
+ * - PT. 3: Rear point — defines the shaft length (and which side the arrows
1908
+ * come from)
1909
+ *
1910
+ * @param coordinates - [PT. 1, PT. 2, PT. 3] as Position arrays
1911
+ * @param options - Configuration options
1912
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
1913
+ */
1914
+ declare function createClearSymbol(coordinates: Position[], options?: ClearOptions): FeatureCollection<MultiLineString | Point>;
1915
+ //#endregion
1916
+ //#region src/generators/cm15-maneuver-areas/searchArea.d.ts
1917
+ /**
1918
+ * Configuration options to tweak the tactical arrow's geometry.
1919
+ */
1920
+ interface TacticalArrowOptions {
1921
+ /** Ratio of arrowhead length to total leg length (default: 0.12) */
1922
+ arrowheadLengthRatio?: number;
1923
+ /** Width multiplier for the arrowhead wings (default: 0.5) */
1924
+ arrowheadWidthRatio?: number;
1925
+ /** Percentage along the leg where the zigzag begins, 0.0-1.0 (default: 0.55) */
1926
+ zigzagStart?: number;
1927
+ /** Percentage along the leg where the zigzag returns, 0.0-1.0 (default: 0.45) */
1928
+ zigzagEnd?: number;
1929
+ /** Perpendicular offset for the lightning "kink", relative to leg length (default: 0.07) */
1930
+ zigzagAmplitudeRatio?: number;
1931
+ }
1932
+ /**
1933
+ * Default options for the tactical arrow.
1934
+ */
1935
+ declare const DEFAULT_TACTICAL_ARROW_OPTIONS: Required<TacticalArrowOptions>;
1936
+ //#endregion
1937
+ //#region src/generators/cm34-mission-tasks/security-task-shared.d.ts
1938
+ interface SecurityTaskOptions extends TacticalArrowOptions {
1939
+ /** Position of each task letter inward from PT. 2/PT. 3 as a ratio of the opening. */
1940
+ labelInsetRatio?: number;
1941
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
1942
+ labelSize?: number;
1943
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1944
+ labelSizePixels?: number;
1945
+ }
1946
+ //#endregion
1947
+ //#region src/generators/cm34-mission-tasks/cover.d.ts
1948
+ type CoverOptions = SecurityTaskOptions;
1949
+ declare const DEFAULT_COVER_OPTIONS: Required<Omit<SecurityTaskOptions, "labelSize" | "labelSizePixels">>;
1950
+ declare function createCoverSymbol(coordinates: Position[], options?: CoverOptions): FeatureCollection<MultiLineString | Point>;
1951
+ //#endregion
1952
+ //#region src/generators/cm34-mission-tasks/delay.d.ts
1953
+ interface DelayOptions {
1954
+ /** Arrowhead depth as a ratio of the straight-line length (default: 0.12). */
1955
+ arrowheadLengthRatio?: number;
1956
+ /** Arrowhead width as a ratio of the straight-line length (default: 0.12). */
1957
+ arrowheadWidthRatio?: number;
1958
+ /** Gap for the 'D' label as a ratio of the straight-line length (default: 0.18). */
1959
+ labelGapRatio?: number;
1960
+ /** Number of segments used to approximate the 180-degree arc (default: 32). */
1961
+ arcSegments?: number;
1962
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
1963
+ labelSize?: number;
1964
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1965
+ labelSizePixels?: number;
1966
+ }
1967
+ declare const DEFAULT_DELAY_OPTIONS: Required<Omit<DelayOptions, "labelSize" | "labelSizePixels">>;
1968
+ declare function createDelaySymbol(coordinates: Position[], options?: DelayOptions): FeatureCollection<MultiLineString | Point>;
1969
+ //#endregion
1970
+ //#region src/generators/cm34-mission-tasks/guard.d.ts
1971
+ type GuardOptions = SecurityTaskOptions;
1972
+ declare const DEFAULT_GUARD_OPTIONS: Required<Omit<SecurityTaskOptions, "labelSize" | "labelSizePixels">>;
1973
+ declare function createGuardSymbol(coordinates: Position[], options?: GuardOptions): FeatureCollection<MultiLineString | Point>;
1974
+ //#endregion
1975
+ //#region src/generators/cm34-mission-tasks/isolate.d.ts
1976
+ /**
1977
+ * Configuration options for the ISOLATE tactical mission task symbol.
1978
+ */
1979
+ interface IsolateOptions {
1980
+ /** Angular size of the opening on the friendly side, in degrees (default: 30). */
1981
+ openingAngle?: number;
1982
+ /** Number of inward-pointing arrowhead barbs spaced around the closed arc (default: 9). */
1983
+ barbCount?: number;
1984
+ /** Barb length as a ratio of the symbol radius (default: 0.18). */
1985
+ barbLengthRatio?: number;
1986
+ }
1987
+ /**
1988
+ * Generates a GeoJSON FeatureCollection for an ISOLATE mission task symbol (341500).
1989
+ *
1990
+ * A near-complete circle centered on PT. 1 whose radius reaches PT. 2. The arc
1991
+ * starts (bare) at PT. 2's bearing and sweeps clockwise around the closed
1992
+ * portion to a single arrow tip at the far end; the wedge-shaped gap (default
1993
+ * 30°) between that arrow tip and PT. 2 is the opening — the "friendly side".
1994
+ * Inward-pointing arrowhead barbs are spaced along the closed arc, set in from
1995
+ * both ends so they never touch PT. 2 or the arrow tip, conveying the
1996
+ * sealing-off of the enclosed force. Unlike the bracket mission tasks, isolate
1997
+ * carries no glyph label.
1998
+ *
1999
+ * Input Points:
2000
+ * - PT. 1: Center point
2001
+ * - PT. 2: Start point — fixes the radius and the bearing of the opening
2002
+ *
2003
+ * @param coordinates - [PT. 1, PT. 2] as Position arrays
2004
+ * @param options - Configuration options
2005
+ * @returns GeoJSON FeatureCollection containing a single MultiLineString feature
2006
+ */
2007
+ declare function createIsolateSymbol(coordinates: Position[], options?: IsolateOptions): FeatureCollection<MultiLineString>;
2008
+ //#endregion
2009
+ //#region src/generators/cm34-mission-tasks/screen.d.ts
2010
+ type ScreenOptions = SecurityTaskOptions;
2011
+ declare const DEFAULT_SCREEN_OPTIONS: Required<Omit<SecurityTaskOptions, "labelSize" | "labelSizePixels">>;
2012
+ declare function createScreenSymbol(coordinates: Position[], options?: ScreenOptions): FeatureCollection<MultiLineString | Point>;
2013
+ //#endregion
2014
+ //#region src/generators/cm29-protection-lines/antitankDitch.d.ts
2015
+ interface AntitankDitchOptions extends SmoothLineOptions, LineLabelOptions {
2016
+ /**
2017
+ * The tooth depth in meters. Target tooth spacing is roughly 1.15x this depth.
2018
+ * Ignored when toothHeightPixels is provided with metersPerPixel.
2019
+ * @default 50
2020
+ */
2021
+ toothHeight?: number;
2022
+ /**
2023
+ * The tooth depth in pixels. When provided with metersPerPixel, the meter
2024
+ * size is calculated dynamically to maintain a consistent visual size.
2025
+ * @default 10
2026
+ */
2027
+ toothHeightPixels?: number;
2028
+ /**
2029
+ * The target base span of each triangular tooth as a multiple of tooth depth.
2030
+ * Lower values make sharper, denser teeth; higher values make flatter teeth.
2031
+ * @default 1.15
2032
+ */
2033
+ toothWidthRatio?: number;
2034
+ /**
2035
+ * The meters-per-pixel ratio at the current zoom level and latitude. Required
2036
+ * when using toothHeightPixels for zoom-aware sizing.
2037
+ */
2038
+ metersPerPixel?: number;
2039
+ }
2040
+ declare const DEFAULT_ANTITANK_DITCH_OPTIONS: Required<Omit<AntitankDitchOptions, keyof LineLabelOptions>>;
2041
+ declare function createAntitankDitchUnderConstruction(positions: Position[], options?: AntitankDitchOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2042
+ declare function createAntitankDitchCompleted(positions: Position[], options?: AntitankDitchOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiPolygon | Point>;
2043
+ //#endregion
2044
+ //#region src/generators/cm29-protection-lines/antitankWall.d.ts
2045
+ interface AntitankWallOptions extends AntitankDitchOptions {
2046
+ /**
2047
+ * The total gap between consecutive tooth bases as a multiple of tooth base
2048
+ * width. Use 0 for touching teeth; higher values create wider gaps.
2049
+ * @default 1.35
2050
+ */
2051
+ toothSpacingRatio?: number;
2052
+ }
2053
+ declare const DEFAULT_ANTITANK_WALL_OPTIONS: Required<Omit<AntitankWallOptions, keyof LineLabelOptions>>;
2054
+ declare function createAntitankWall(positions: Position[], options?: AntitankWallOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2055
+ //#endregion
2056
+ //#region src/generators/cm29-protection-lines/fortifiedLine.d.ts
2057
+ /**
2058
+ * Configuration options for the Fortified Line geometry.
2059
+ */
2060
+ interface FortifiedLineOptions extends LineLabelOptions {
2061
+ /**
2062
+ * The size of the square teeth in meters.
2063
+ * This controls both the width and height of the castellated pattern.
2064
+ * This is ignored if toothSizePixels is provided along with metersPerPixel.
2065
+ * @default 50
2066
+ */
2067
+ toothSize?: number;
2068
+ /**
2069
+ * The size of the square teeth in pixels.
2070
+ * When provided along with metersPerPixel, the actual meter size is calculated
2071
+ * dynamically to maintain consistent visual size on screen.
2072
+ * Takes precedence over toothSize when metersPerPixel is also provided.
2073
+ * @default 10
2074
+ */
2075
+ toothSizePixels?: number;
2076
+ /**
2077
+ * The meters-per-pixel ratio at the current zoom level and latitude.
2078
+ * Required when using toothSizePixels for zoom-aware sizing.
2079
+ */
2080
+ metersPerPixel?: number;
2081
+ /**
2082
+ * Round the line's corners by curving the base path through the control
2083
+ * points (centripetal Catmull-Rom spline) before generating the castellated
2084
+ * teeth, matching the rounded shape option on the Fortified Area and Battle
2085
+ * Position measures. With fewer than three control points the path is left
2086
+ * unchanged (a single segment cannot be smoothed).
2087
+ * @default false
2088
+ */
2089
+ smooth?: boolean;
2090
+ /**
2091
+ * Number of samples per segment when `smooth` is enabled. Higher values yield
2092
+ * a denser, smoother curve.
2093
+ * @default 16
2094
+ */
2095
+ smoothResolution?: number;
2096
+ }
2097
+ /**
2098
+ * Default options for the Fortified Line graphic.
2099
+ */
2100
+ declare const DEFAULT_FORTIFIED_LINE_OPTIONS: Required<Omit<FortifiedLineOptions, keyof LineLabelOptions>>;
2101
+ /**
2102
+ * Creates a Fortified Line tactical graphic.
2103
+ *
2104
+ * Generates a castellated/square-wave line representing a fortified line.
2105
+ * The line consists of square "teeth" that project perpendicular to the base path.
2106
+ *
2107
+ * @param positions - Array of GeoJSON positions defining the base path
2108
+ * @param options - Configuration options for the graphic
2109
+ * @returns A GeoJSON FeatureCollection containing the castellated LineString
2110
+ */
2111
+ declare function createFortifiedLine(positions: Position[], options?: FortifiedLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
2112
+ //#endregion
2113
+ //#region src/generators/cm15-maneuver-areas/fortifiedArea.d.ts
2114
+ /**
2115
+ * Configuration options for the Fortified Area. Inherits the Fortified Line
2116
+ * options (including `smooth`/`smoothResolution`) unchanged; the area applies
2117
+ * the smoothing as a closed Catmull-Rom ring rather than an open spline. Also
2118
+ * carries the shared {@link AreaLabelOptions} label placement (a plain
2119
+ * intersection, not a re-derivation, so the aliased
2120
+ * {@link DEFAULT_FORTIFIED_AREA_OPTIONS} default still typechecks unchanged —
2121
+ * `AreaLabelOptions`'s fields are all optional).
2122
+ */
2123
+ type FortifiedAreaOptions = FortifiedLineOptions & AreaLabelOptions;
2124
+ declare const DEFAULT_FORTIFIED_AREA_OPTIONS: FortifiedAreaOptions;
2125
+ /**
2126
+ * Creates a Fortified Area tactical graphic.
2127
+ *
2128
+ * Generates a polygon with a castellated/square-wave boundary representing a fortified area.
2129
+ * The boundary consists of square "teeth" that project perpendicular to the path.
2130
+ *
2131
+ * @param positions - Array of GeoJSON positions defining the area boundary.
2132
+ * The first and last positions should match to close the polygon,
2133
+ * or it will be closed automatically.
2134
+ * @param options - Configuration options for the graphic
2135
+ * @param textAmplifiers - Field T (bare, no prefix — "TANGO", not "FA TANGO")
2136
+ * plus Field H/W/W1, centered on the pre-teeth boundary ring (see
2137
+ * `boundaryInput` below), and an optional Field N "ENY" hostile marker on
2138
+ * that ring's west/east edges, masking the castellated boundary beneath it.
2139
+ * @param context - Persisted amplifier placements used to move or restore each
2140
+ * ENY cutout with its independently dragged label.
2141
+ * @returns A GeoJSON FeatureCollection containing the castellated boundary
2142
+ * (a Polygon normally, or a gapped MultiLineString with Field N) plus any
2143
+ * label Points
2144
+ */
2145
+ declare function createFortifiedArea(positions: Position[], options?: FortifiedAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
2146
+ //#endregion
2147
+ //#region src/generators/cm15-maneuver-areas/maneuver-arrow-task-shared.d.ts
2148
+ interface ManeuverArrowTaskOptions extends AttackOptions, LabelSizeOptions {
2149
+ /** Straight crossbar length as a multiple of the arrowhead base width. */
2150
+ crossbarLengthRatio?: number;
2151
+ /** Field T position along the shaft, from tail (0) to head (1). */
2152
+ labelPosition?: number;
2153
+ /** W/W1 position along the shaft, from tail (0) to head (1). */
2154
+ dtgPosition?: number;
2155
+ /** Extra W/W1 row spacing, in label heights. */
2156
+ labelPadding?: number;
2157
+ }
2158
+ //#endregion
2159
+ //#region src/generators/cm15-maneuver-areas/frontal-attack.d.ts
2160
+ type FrontalAttackOptions = ManeuverArrowTaskOptions;
2161
+ declare const DEFAULT_FRONTAL_ATTACK_OPTIONS: FrontalAttackOptions;
2162
+ declare function createFrontalAttack(coordinates: Position[], options?: FrontalAttackOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2163
+ //#endregion
2164
+ //#region src/generators/cm15-maneuver-areas/turning-movement.d.ts
2165
+ type TurningMovementOptions = ManeuverArrowTaskOptions;
2166
+ declare const DEFAULT_TURNING_MOVEMENT_OPTIONS: TurningMovementOptions;
2167
+ declare function createTurningMovement(coordinates: Position[], options?: TurningMovementOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2168
+ //#endregion
2169
+ //#region src/generators/cm27-protection-areas/block.d.ts
2170
+ type BlockOptions = Record<never, never>;
2171
+ declare const DEFAULT_BLOCK_OPTIONS: BlockOptions;
2172
+ /**
2173
+ * Generates a GeoJSON FeatureCollection for a "Block" tactical symbol (T-shape).
2174
+ *
2175
+ * @param coordinates - An array of GeoJSON Positions (Lon/Lat).
2176
+ * Expects exactly 3 points:
2177
+ * - PT1 & PT2: Endpoints of the vertical line.
2178
+ * - PT3: Defines the endpoint of the horizontal line (stem).
2179
+ * @param options - Configuration options.
2180
+ * @returns A GeoJSON FeatureCollection containing a LineString.
2181
+ */
2182
+ declare function createBlock(coordinates: Position[], _options?: BlockOptions): FeatureCollection<LineString>;
2183
+ //#endregion
2184
+ //#region src/generators/cm27-protection-areas/disrupt.d.ts
2185
+ interface DisruptOptions {
2186
+ middleArrowLengthRatio?: number;
2187
+ bottomArrowLengthRatio?: number;
2188
+ shaftLengthRatio?: number;
2189
+ arrowheadLengthRatio?: number;
2190
+ arrowheadWidthRatio?: number;
2191
+ }
2192
+ declare const DEFAULT_DISRUPT_OPTIONS: Required<DisruptOptions>;
2193
+ /**
2194
+ * Generates a GeoJSON FeatureCollection for a DISRUPT tactical symbol.
2195
+ *
2196
+ * Input:
2197
+ * - PT1: Top endpoint of the vertical spine
2198
+ * - PT2: Bottom endpoint of the vertical spine
2199
+ * - PT3: Reference point used to determine the longest-arrow offset
2200
+ *
2201
+ * Geometry:
2202
+ * - Spine: PT1 -> PT2
2203
+ * - PT2 -> PT1 defines the baseline orientation; arrow direction is constrained to its perpendicular axis
2204
+ * - PT3 is decomposed and projected onto the perpendicular axis through PT1 to derive a valid longest-arrow tip
2205
+ * - Three arrows placed at PT1, midpoint(PT1, PT2), and PT2
2206
+ * - Center shaft extends opposite arrow direction from midpoint with the same length as the middle arrow
2207
+ * - Top arrow is longest
2208
+ * - Middle and bottom arrows are proportional to the longest arrow
2209
+ * - Arrow heads are returned as filled triangle polygons
2210
+ */
2211
+ declare function createDisrupt(coordinates: Position[], options?: DisruptOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2212
+ //#endregion
2213
+ //#region src/generators/cm27-protection-areas/fix.d.ts
2214
+ interface FixOptions {
2215
+ arrowheadAngle?: number;
2216
+ arrowheadLengthRatio?: number;
2217
+ endSegmentRatio?: number;
2218
+ }
2219
+ declare const DEFAULT_FIX_OPTIONS: Required<FixOptions>;
2220
+ /**
2221
+ * Generates a GeoJSON FeatureCollection for a FIX tactical symbol.
2222
+ *
2223
+ * Input:
2224
+ * - PT1: Arrow tip end
2225
+ * - PT2: Opposite end
2226
+ *
2227
+ * Notes:
2228
+ * - Requires exactly two points.
2229
+ * - Produces one MultiLineString feature containing the zigzag body and open arrowhead wings.
2230
+ */
2231
+ declare function createFix(coordinates: Position[], options?: FixOptions): FeatureCollection<MultiLineString>;
2232
+ //#endregion
2233
+ //#region src/generators/cm27-protection-areas/turn.d.ts
2234
+ interface TurnOptions {
2235
+ arrowheadLengthRatio?: number;
2236
+ arrowheadWidthRatio?: number;
2237
+ arcSegments?: number;
2238
+ }
2239
+ declare const DEFAULT_TURN_OPTIONS: Required<TurnOptions>;
2240
+ /**
2241
+ * Generates a quarter-circle shaft from PT2 (rear) to the arrowhead base.
2242
+ * The arrowhead continues tangent to the arc and places its tip at PT1.
2243
+ * PT3 selects which side of the PT2 -> PT1 chord contains the arc.
2244
+ */
2245
+ declare function createTurn(coordinates: Position[], options?: TurnOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2246
+ //#endregion
2247
+ //#region src/generators/cm27-protection-areas/obstacleBypassEasy.d.ts
2248
+ interface ObstacleBypassEasyOptions {
2249
+ arrowheadLengthRatio?: number;
2250
+ arrowheadWidthRatio?: number;
2251
+ defaultLengthRatio?: number;
2252
+ }
2253
+ declare const DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS: Required<ObstacleBypassEasyOptions>;
2254
+ /**
2255
+ * Generates a GeoJSON FeatureCollection for an "Obstacle Bypass Easy" symbol.
2256
+ *
2257
+ * Input:
2258
+ * - PT1 and PT2 define the tips of the two arrowheads (opening and symbol height)
2259
+ * - PT3 defines signed symbol length along the perpendicular axis through midpoint(PT1, PT2)
2260
+ *
2261
+ * Geometry:
2262
+ * - Rear line is parallel to opening(PT1-PT2) and has equal length
2263
+ * - Two side rails run from rear endpoints to the arrowheads and are parallel to each other
2264
+ * - Rear line is perpendicular to both side rails
2265
+ * - Arrow heads are filled triangle polygons at PT1 and PT2
2266
+ */
2267
+ declare function createObstacleBypassEasy(coordinates: Position[], options?: ObstacleBypassEasyOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2268
+ //#endregion
2269
+ //#region src/generators/cm27-protection-areas/obstacleBypassDifficult.d.ts
2270
+ interface ObstacleBypassDifficultOptions {
2271
+ arrowheadLengthRatio?: number;
2272
+ arrowheadWidthRatio?: number;
2273
+ defaultLengthRatio?: number;
2274
+ zigzagAmplitudeRatio?: number;
2275
+ zigzagSpacingRatio?: number;
2276
+ }
2277
+ declare const DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS: Required<ObstacleBypassDifficultOptions>;
2278
+ declare function createObstacleBypassDifficult(coordinates: Position[], options?: ObstacleBypassDifficultOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2279
+ //#endregion
2280
+ //#region src/generators/cm27-protection-areas/obstacleBypassImpossible.d.ts
2281
+ interface ObstacleBypassImpossibleOptions {
2282
+ arrowheadLengthRatio?: number;
2283
+ arrowheadWidthRatio?: number;
2284
+ defaultLengthRatio?: number;
2285
+ rearBarLengthRatio?: number;
2286
+ rearGapRatio?: number;
2287
+ }
2288
+ declare const DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS: Required<ObstacleBypassImpossibleOptions>;
2289
+ /**
2290
+ * Generates a GeoJSON FeatureCollection for an "Obstacle Bypass Impossible" symbol.
2291
+ *
2292
+ * Input:
2293
+ * - PT1 and PT2 define the tips of the two arrowheads (opening and symbol height)
2294
+ * - PT3 defines signed symbol length along the perpendicular axis through midpoint(PT1, PT2)
2295
+ *
2296
+ * Geometry:
2297
+ * - Same base as obstacle bypass easy
2298
+ * - Rear line has two short perpendicular bars on the rear side
2299
+ */
2300
+ declare function createObstacleBypassImpossible(coordinates: Position[], options?: ObstacleBypassImpossibleOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2301
+ //#endregion
2302
+ //#region src/registry.d.ts
2303
+ /**
2304
+ * The single source of truth for the catalog: one **control measure
2305
+ * definition** record per measure, co-located with its generator and collected
2306
+ * here. The `ControlMeasureId` union, `OptionsByKind`, the generator dispatch,
2307
+ * the default options, and rule resolution are all *derived* from this map
2308
+ * rather than maintained as parallel tables. Adding a measure is a one-file
2309
+ * change plus one line here. See ADR-0013.
2310
+ */
2311
+ declare const DEFINITIONS: {
2312
+ boundary: ControlMeasureDefinition<"boundary", typeof createBoundary>;
2313
+ "light-line": ControlMeasureDefinition<"light-line", typeof createLightLine>;
2314
+ "engineer-work-line": ControlMeasureDefinition<"engineer-work-line", typeof createEngineerWorkLine>;
2315
+ "generic-c2-line": ControlMeasureDefinition<"generic-c2-line", typeof createGenericC2Line>;
2316
+ "battle-position": ControlMeasureDefinition<"battle-position", typeof createBattlePosition>;
2317
+ "strong-point": ControlMeasureDefinition<"strong-point", typeof createStrongPoint>;
2318
+ ambush: ControlMeasureDefinition<"ambush", (controlPoints: import("geojson").Position[], options?: AmbushOptions) => import("geojson").FeatureCollection<import("geojson").MultiLineString, Record<string, never>>>;
2319
+ "direction-of-attack-aviation": ControlMeasureDefinition<"direction-of-attack-aviation", typeof createDirectionOfAttackAviation>;
2320
+ "direction-of-main-attack": ControlMeasureDefinition<"direction-of-main-attack", typeof createDirectionOfMainAttack>;
2321
+ "direction-of-supporting-attack": ControlMeasureDefinition<"direction-of-supporting-attack", typeof createDirectionOfSupportingAttack>;
2322
+ "principal-direction-of-fire": ControlMeasureDefinition<"principal-direction-of-fire", typeof createPrincipalDirectionOfFire>;
2323
+ "final-protective-fire-left": ControlMeasureDefinition<"final-protective-fire-left", typeof createFinalProtectiveFireLeft>;
2324
+ "final-protective-fire-right": ControlMeasureDefinition<"final-protective-fire-right", typeof createFinalProtectiveFireRight>;
2325
+ "search-area": ControlMeasureDefinition<"search-area", (controlPoints: import("geojson").Position[], options?: TacticalArrowOptions) => import("geojson").FeatureCollection<import("geojson").MultiLineString | import("geojson").MultiPolygon, {
2326
+ part: "shaft" | "head";
2327
+ fill?: boolean;
2328
+ style?: StyleHints;
2329
+ }>>;
2330
+ encirclement: ControlMeasureDefinition<"encirclement", typeof createEncirclement>;
2331
+ area: ControlMeasureDefinition<"area", typeof createArea>;
2332
+ "area-defense": ControlMeasureDefinition<"area-defense", typeof createAreaDefense>;
2333
+ "assembly-area": ControlMeasureDefinition<"assembly-area", typeof createAssemblyArea>;
2334
+ "joint-tactical-action-area": ControlMeasureDefinition<"joint-tactical-action-area", typeof createJointTacticalActionArea>;
2335
+ "submarine-action-area": ControlMeasureDefinition<"submarine-action-area", typeof createSubmarineActionArea>;
2336
+ "submarine-generated-action-area": ControlMeasureDefinition<"submarine-generated-action-area", typeof createSubmarineGeneratedActionArea>;
2337
+ "drop-zone": ControlMeasureDefinition<"drop-zone", typeof createDropZone>;
2338
+ "extraction-zone": ControlMeasureDefinition<"extraction-zone", typeof createExtractionZone>;
2339
+ "landing-zone": ControlMeasureDefinition<"landing-zone", typeof createLandingZone>;
2340
+ "pickup-zone": ControlMeasureDefinition<"pickup-zone", typeof createPickupZone>;
2341
+ "assault-position": ControlMeasureDefinition<"assault-position", typeof createAssaultPosition>;
2342
+ "attack-position": ControlMeasureDefinition<"attack-position", typeof createAttackPosition>;
2343
+ "objective-area": ControlMeasureDefinition<"objective-area", typeof createObjectiveArea>;
2344
+ "area-of-operations": ControlMeasureDefinition<"area-of-operations", typeof createAreaOfOperations>;
2345
+ "named-area-of-interest": ControlMeasureDefinition<"named-area-of-interest", typeof createNamedAreaOfInterest>;
2346
+ "target-area-of-interest": ControlMeasureDefinition<"target-area-of-interest", typeof createTargetAreaOfInterest>;
2347
+ "airfield-zone": ControlMeasureDefinition<"airfield-zone", typeof createAirfieldZone>;
2348
+ "base-camp": ControlMeasureDefinition<"base-camp", typeof createBaseCamp>;
2349
+ "guerrilla-base": ControlMeasureDefinition<"guerrilla-base", typeof createGuerrillaBase>;
2350
+ "generic-c2-area": ControlMeasureDefinition<"generic-c2-area", typeof createGenericC2Area>;
2351
+ "main-attack": ControlMeasureDefinition<"main-attack", typeof createMainAttack>;
2352
+ "supporting-attack": ControlMeasureDefinition<"supporting-attack", typeof createSupportingAttack>;
2353
+ "classic-arrow": ControlMeasureDefinition<"classic-arrow", typeof createClassicArrow>;
2354
+ "block-arrow": ControlMeasureDefinition<"block-arrow", typeof createBlockArrow>;
2355
+ line: ControlMeasureDefinition<"line", typeof createGenericLine>;
2356
+ polygon: ControlMeasureDefinition<"polygon", typeof createGenericPolygon>;
2357
+ rectangle: ControlMeasureDefinition<"rectangle", typeof createGenericRectangle>;
2358
+ circle: ControlMeasureDefinition<"circle", typeof createGenericCircle>;
2359
+ "airborne-attack": ControlMeasureDefinition<"airborne-attack", typeof createAirborneAttack>;
2360
+ "attack-helicopter": ControlMeasureDefinition<"attack-helicopter", typeof createAttackHelicopter>;
2361
+ "support-by-fire": ControlMeasureDefinition<"support-by-fire", typeof createSupportByFire>;
2362
+ "attack-by-fire": ControlMeasureDefinition<"attack-by-fire", typeof createAttackByFire>;
2363
+ flot: ControlMeasureDefinition<"flot", typeof createFLOT>;
2364
+ "phase-line": ControlMeasureDefinition<"phase-line", typeof createPhaseLine>;
2365
+ "handover-line": ControlMeasureDefinition<"handover-line", typeof createHandoverLine>;
2366
+ "battle-handover-line": ControlMeasureDefinition<"battle-handover-line", typeof createBattleHandoverLine>;
2367
+ "block-mission-task": ControlMeasureDefinition<"block-mission-task", typeof createBlockMissionTaskSymbol>;
2368
+ breach: ControlMeasureDefinition<"breach", typeof createBreachSymbol>;
2369
+ bypass: ControlMeasureDefinition<"bypass", typeof createBypassSymbol>;
2370
+ canalize: ControlMeasureDefinition<"canalize", typeof createCanalizeSymbol>;
2371
+ clear: ControlMeasureDefinition<"clear", typeof createClearSymbol>;
2372
+ cover: ControlMeasureDefinition<"cover", typeof createCoverSymbol>;
2373
+ delay: ControlMeasureDefinition<"delay", typeof createDelaySymbol>;
2374
+ guard: ControlMeasureDefinition<"guard", typeof createGuardSymbol>;
2375
+ isolate: ControlMeasureDefinition<"isolate", typeof createIsolateSymbol>;
2376
+ screen: ControlMeasureDefinition<"screen", typeof createScreenSymbol>;
2377
+ "antitank-ditch-under-construction": ControlMeasureDefinition<"antitank-ditch-under-construction", typeof createAntitankDitchUnderConstruction>;
2378
+ "antitank-ditch-completed": ControlMeasureDefinition<"antitank-ditch-completed", typeof createAntitankDitchCompleted>;
2379
+ "antitank-wall": ControlMeasureDefinition<"antitank-wall", typeof createAntitankWall>;
2380
+ "fortified-line": ControlMeasureDefinition<"fortified-line", typeof createFortifiedLine>;
2381
+ "fortified-area": ControlMeasureDefinition<"fortified-area", typeof createFortifiedArea>;
2382
+ "frontal-attack": ControlMeasureDefinition<"frontal-attack", typeof createFrontalAttack>;
2383
+ "turning-movement": ControlMeasureDefinition<"turning-movement", typeof createTurningMovement>;
2384
+ block: ControlMeasureDefinition<"block", typeof createBlock>;
2385
+ disrupt: ControlMeasureDefinition<"disrupt", typeof createDisrupt>;
2386
+ fix: ControlMeasureDefinition<"fix", typeof createFix>;
2387
+ turn: ControlMeasureDefinition<"turn", typeof createTurn>;
2388
+ "obstacle-bypass-easy": ControlMeasureDefinition<"obstacle-bypass-easy", typeof createObstacleBypassEasy>;
2389
+ "obstacle-bypass-difficult": ControlMeasureDefinition<"obstacle-bypass-difficult", typeof createObstacleBypassDifficult>;
2390
+ "obstacle-bypass-impossible": ControlMeasureDefinition<"obstacle-bypass-impossible", typeof createObstacleBypassImpossible>;
2391
+ };
2392
+ type Definitions = typeof DEFINITIONS;
2393
+ /** Stable string id of a control measure — the keys of {@link DEFINITIONS}. */
2394
+ type ControlMeasureId = keyof Definitions;
2395
+ /**
2396
+ * The discriminant for {@link ControlMeasure}. Identical to
2397
+ * {@link ControlMeasureId}; kept as a distinct name for the `<K extends
2398
+ * ControlMeasureKind>` generics threaded through rendering and edit sessions.
2399
+ */
2400
+ type ControlMeasureKind = ControlMeasureId;
2401
+ /** Strips the internal `validationMode` knob from a public options surface. */
2402
+ type PublicOptions<T> = Omit<T, "validationMode">;
2403
+ /**
2404
+ * The per-kind public options map, derived covariantly from each definition's
2405
+ * generator (see {@link OptsOf}). Empty-options kinds resolve to `{}` — exactly
2406
+ * as loose as the former hand-written table. See ADR-0013.
2407
+ */
2408
+ type OptionsByKind = { [K in keyof Definitions]: PublicOptions<OptsOf<Definitions[K]>> };
2409
+ /** Insertion-ordered list of every control-measure id. */
2410
+ declare const CONTROL_MEASURE_IDS: readonly ControlMeasureId[];
2411
+ declare const CONTROL_MEASURE_METADATA: Readonly<Record<ControlMeasureId, ControlMeasureMetadata>>;
2412
+ declare function listControlMeasureMetadata(): readonly ControlMeasureMetadata[];
2413
+ declare function getControlMeasureMetadata(id: ControlMeasureId): ControlMeasureMetadata;
2414
+ declare function getControlMeasureMetadataByValue(value: string): ControlMeasureMetadata | undefined;
2415
+ declare function getDefaultOptions<K extends ControlMeasureKind>(kind: K): OptionsByKind[K];
2416
+ //#endregion
2417
+ //#region src/instance.d.ts
2418
+ interface ControlMeasure<K extends ControlMeasureKind = ControlMeasureKind> {
2419
+ id: string;
2420
+ kind: K;
2421
+ controlPoints: Position[];
2422
+ options?: OptionsByKind[K];
2423
+ style?: ControlMeasureStyle;
2424
+ properties?: Record<string, unknown>;
2425
+ /** Free-text amplifier fields (MIL-STD-2525E Appendix L Table L-II); see `./text-amplifiers`. */
2426
+ textAmplifiers?: TextAmplifiers;
2427
+ /** Optional user-adjusted anchors for independently rendered text amplifiers. */
2428
+ amplifierPlacements?: AmplifierPlacements;
2429
+ schemaVersion?: 1;
2430
+ }
2431
+ declare function isKind<K extends ControlMeasureKind>(cm: ControlMeasure, kind: K): cm is ControlMeasure<K>;
2432
+ /**
2433
+ * Deep-clone a `ControlMeasure` so held references survive mutations to the
2434
+ * original (and vice versa). Used by the session façade to build the
2435
+ * `graphic` half of TacticalDraw's `GraphicSnapshot`. Nested values inside
2436
+ * `options`, `style`, `properties`, and `textAmplifiers` are cloned too —
2437
+ * `properties` is `Record<string, unknown>` and may carry arbitrary host
2438
+ * metadata, so a shallow copy would leak shared references.
2439
+ *
2440
+ * Backed by `structuredClone`: only structured-cloneable values are
2441
+ * supported (no functions, DOM nodes, class instances). Absent optional
2442
+ * fields stay absent on the clone.
2443
+ */
2444
+ declare function cloneControlMeasure<K extends ControlMeasureKind>(cm: ControlMeasure<K>): ControlMeasure<K>;
2445
+ //#endregion
2446
+ //#region src/renderControlMeasure.d.ts
2447
+ interface RenderOptions {
2448
+ validationMode?: ValidationMode;
2449
+ /**
2450
+ * Façade-level default style (third / lowest-priority layer). Merged
2451
+ * shallowly under `cm.style` and any per-feature generator hint. When
2452
+ * omitted, style resolution matches the prior two-layer behavior.
2453
+ */
2454
+ graphicsStyle?: ControlMeasureStyle;
2455
+ }
2456
+ /**
2457
+ * Pure render: `ControlMeasure` → `ControlMeasureRender` (a
2458
+ * `FeatureCollection` of `FeaturePartProps`-typed features). Per-feature
2459
+ * stable ids follow `${cm.id}:${part}:${index}`. Style is resolved from the
2460
+ * three layers (graphicsStyle, cm.style, generator hint) and stamped on
2461
+ * `properties.style` when non-empty.
2462
+ */
2463
+ declare function renderControlMeasure<K extends ControlMeasureKind>(cm: ControlMeasure<K>, opts?: RenderOptions): ControlMeasureRender;
2464
+ //#endregion
2465
+ //#region src/freeze-orientation.d.ts
2466
+ /**
2467
+ * Dispatches to a measure kind's `freezeOrientation` hook (see
2468
+ * {@link import("./define").ControlMeasureDefinition.freezeOrientation}),
2469
+ * pinning orientation-derived option defaults to their current concrete
2470
+ * values ahead of a rigid rotation of `controlPoints`. Returns `undefined`
2471
+ * when the kind declares no hook, or when the hook itself finds nothing to
2472
+ * freeze. Edit hosts call this when a rotate gesture starts (ADR-0023).
2473
+ */
2474
+ declare function freezeOrientationOptions<K extends ControlMeasureKind>(kind: K, controlPoints: Position[], options: OptionsByKind[K] | undefined): Partial<OptionsByKind[K]> | undefined;
2475
+ //#endregion
2476
+ //#region src/styleResolver.d.ts
2477
+ /**
2478
+ * Three-layer style precedence for `renderControlMeasure`.
2479
+ *
2480
+ * Lower-priority → higher-priority: `graphicsStyle` (façade default) →
2481
+ * `measureStyle` (`cm.style`) → `generatorStyle` (per-feature hint emitted
2482
+ * by a generator). Merge is shallow and per-property; higher-priority layers
2483
+ * win key by key. Explicit `null` / `undefined` in a higher-priority layer
2484
+ * is treated as "no opinion" and does not clear a lower-priority key.
2485
+ *
2486
+ * Returns `undefined` when all three layers are absent so the renderer can
2487
+ * omit `properties.style` entirely — keeps the no-style case byte-identical
2488
+ * to a property-less feature.
2489
+ *
2490
+ * Pure function: inputs are never mutated; the returned object is always a
2491
+ * fresh allocation when defined.
2492
+ */
2493
+ declare function resolveStyleHints(graphicsStyle: ControlMeasureStyle | undefined, measureStyle: ControlMeasureStyle | undefined, generatorStyle: StyleHints | undefined): StyleHints | undefined;
2494
+ //#endregion
2495
+ //#region src/toSimpleStyle.d.ts
2496
+ /**
2497
+ * simplestyle-spec properties (the subset this library can express), flat on
2498
+ * `properties`. All keys are optional.
2499
+ *
2500
+ * @see https://github.com/mapbox/simplestyle-spec
2501
+ */
2502
+ interface SimpleStyleProps extends FeaturePartProps {
2503
+ stroke?: string;
2504
+ "stroke-width"?: number;
2505
+ "stroke-opacity"?: number;
2506
+ fill?: string;
2507
+ "fill-opacity"?: number;
2508
+ }
2509
+ /**
2510
+ * A `FeatureCollection` whose features carry simplestyle-spec keys instead of
2511
+ * the nested `properties.style` slot. The `FeaturePartProps` stable-id
2512
+ * contract (`part`, `index`, `feature.id`) is preserved.
2513
+ */
2514
+ type SimpleStyleRender = FeatureCollection<Geometry, SimpleStyleProps>;
2515
+ /**
2516
+ * Lossy interop transform: `ControlMeasureRender` → a `FeatureCollection`
2517
+ * whose features carry simplestyle-spec keys. Operates on the already-resolved
2518
+ * per-feature `style`, so it composes after `renderControlMeasure`'s
2519
+ * three-layer merge and stays a pure post-processing step.
2520
+ *
2521
+ * Lossy mapping, by design:
2522
+ * - `strokeDash` and `fillPattern` have no simplestyle equivalent and are
2523
+ * dropped — dashed sub-lines and patterned fills render solid in
2524
+ * simplestyle consumers.
2525
+ * - colors must be hex or `rgb()/rgba()`; alpha becomes `*-opacity`. Other
2526
+ * color forms (named, `hsl()`) are omitted rather than guessed.
2527
+ */
2528
+ declare function toSimpleStyle(render: ControlMeasureRender): SimpleStyleRender;
2529
+ //#endregion
2530
+ //#region src/internal/graphics-utils.d.ts
2531
+ /**
2532
+ * Small value used to avoid division by zero and floating-point precision issues.
2533
+ */
2534
+ declare const EPSILON = 0.000001;
2535
+ /**
2536
+ * Rounds a number to a specified number of decimal places.
2537
+ */
2538
+ declare const roundToFixed: (v: number, precision?: number) => number;
2539
+ /**
2540
+ * Calculates the meters-per-pixel ratio at a given latitude and zoom level.
2541
+ *
2542
+ * This is essential for maintaining consistent visual sizes on the map
2543
+ * regardless of zoom level. The formula accounts for:
2544
+ * - The Web Mercator projection's tile-based structure
2545
+ * - The latitude-dependent scale distortion in Mercator projection
2546
+ *
2547
+ * @param latitude - The latitude in degrees (affects scale due to projection)
2548
+ * @param zoomLevel - The current map zoom level
2549
+ * @returns The number of meters represented by one pixel at the given location and zoom
2550
+ *
2551
+ * @example
2552
+ * ```typescript
2553
+ * // At zoom 10, latitude 45°
2554
+ * const mpp = getMetersPerPixel(45, 10);
2555
+ * // To get a 20-pixel radius in meters:
2556
+ * const radiusMeters = 20 * mpp;
2557
+ * ```
2558
+ */
2559
+ declare const getMetersPerPixel: (latitude: number, zoomLevel: number) => number;
2560
+ //#endregion
2561
+ //#region src/draw-rules/baseline-frame.d.ts
2562
+ type BaselineFrameOrigin = "p1" | "p2" | "midpoint";
2563
+ type BaselineFrameNormal = "right" | "left";
2564
+ interface BaselineFrameOptions {
2565
+ origin?: BaselineFrameOrigin;
2566
+ normal?: BaselineFrameNormal;
2567
+ }
2568
+ interface BaselineFrame {
2569
+ readonly p1: Point2D;
2570
+ readonly p2: Point2D;
2571
+ readonly origin: Point2D;
2572
+ readonly direction: Point2D;
2573
+ readonly normal: Point2D;
2574
+ readonly length: number;
2575
+ signedNormalDistance(point: Position): number;
2576
+ pointAtNormalDistance(distance: number): Position | null;
2577
+ }
2578
+ declare function createBaselineFrame(p1: Position, p2: Position, options?: BaselineFrameOptions): BaselineFrame | null;
2579
+ //#endregion
2580
+ //#region src/draw-rules/midpoint-perpendicular.d.ts
2581
+ interface MidpointPerpendicularDrawRuleOptions {
2582
+ id: string;
2583
+ defaultDistanceRatio?: number;
2584
+ /** User clicks required to commit. Defaults to `2` (the third point is auto-derived). */
2585
+ minimumUserPoints?: number;
2586
+ /** Raw points at which a live preview can be derived. See {@link ControlMeasureDrawRule}. */
2587
+ minimumPreviewPoints?: number;
2588
+ /**
2589
+ * Index of the slot whose point is constrained to the perpendicular axis
2590
+ * through the configured origin of the other two ("baseline") slots. Must be
2591
+ * `0` or `2`. Defaults to `2`.
2592
+ *
2593
+ * Area11 (Block) and Point12 (obstacle-bypass) use `2`: P1/P2 are the free
2594
+ * baseline endpoints and P3 is constrained. Area7 (Attack-By-Fire) uses `0`:
2595
+ * P1 is the constrained arrowhead tip and P2/P3 are the free back-line
2596
+ * endpoints.
2597
+ */
2598
+ constrainedIndex?: 0 | 2;
2599
+ /** Frame origin for the perpendicular axis. Defaults to `"midpoint"`. */
2600
+ origin?: BaselineFrameOrigin;
2601
+ /** Side the positive normal points to. Defaults to `"right"`. */
2602
+ normal?: BaselineFrameNormal;
2603
+ }
2604
+ declare function createMidpointPerpendicularDrawRule(options: MidpointPerpendicularDrawRuleOptions): ControlMeasureDrawRule;
2605
+ declare function computeDefaultMidpointPerpendicularPoint(p1: Position, p2: Position, distanceRatio?: number): Position | null;
2606
+ declare function getMidpointPerpendicularSignedDistance(p1: Position, p2: Position, controlPoint: Position): number | null;
2607
+ declare function pointOnMidpointPerpendicularAxis(p1: Position, p2: Position, distance: number | null): Position | null;
2608
+ declare function snapToMidpointPerpendicular(p1: Position, p2: Position, controlPoint: Position): Position | null;
2609
+ //#endregion
2610
+ //#region src/draw-rules/area11.d.ts
2611
+ declare const blockDrawRule: ControlMeasureDrawRule;
2612
+ //#endregion
2613
+ //#region src/draw-rules/area12.d.ts
2614
+ /**
2615
+ * Area12 anchor draw rule for Disrupt.
2616
+ *
2617
+ * P1/P2 are the free spine endpoints. P3 is the longest-arrow tip, constrained
2618
+ * to the perpendicular axis through P1 (not the baseline midpoint).
2619
+ */
2620
+ declare const disruptDrawRule: ControlMeasureDrawRule;
2621
+ //#endregion
2622
+ //#region src/draw-rules/area15.d.ts
2623
+ declare const centerRadiusDrawRule: ControlMeasureDrawRule;
2624
+ //#endregion
2625
+ //#region src/draw-rules/point12.d.ts
2626
+ /**
2627
+ * Point12 anchor draw rule for the obstacle-bypass family.
2628
+ *
2629
+ * Shared by `obstacle-bypass-easy`, `obstacle-bypass-difficult`, and
2630
+ * `obstacle-bypass-impossible`: P1/P2 are the arrowhead tips and define the
2631
+ * opening; P3 is constrained to the perpendicular axis through
2632
+ * `midpoint(P1, P2)` and defines the rear of the symbol. Rear-line decoration
2633
+ * (plain, zigzag, barrier marks) is a generator concern, not a draw-rule one.
2634
+ */
2635
+ declare const point12DrawRule: ControlMeasureDrawRule;
2636
+ //#endregion
2637
+ //#region src/draw-rules/area7.d.ts
2638
+ /**
2639
+ * Area7 anchor draw rule for Attack By Fire.
2640
+ *
2641
+ * P2/P3 are the free back-line endpoints; P1 (slot index 0) is the arrowhead
2642
+ * tip, constrained to the perpendicular axis through `midpoint(P2, P3)`.
2643
+ */
2644
+ declare const attackByFireDrawRule: ControlMeasureDrawRule;
2645
+ //#endregion
2646
+ //#region src/draw-rules/line29.d.ts
2647
+ /**
2648
+ * Line29 anchor draw rule for Ambush.
2649
+ *
2650
+ * P2/P3 are the free back-line endpoints; P1 (slot index 0) is the arrowhead
2651
+ * tip, constrained to the perpendicular axis through `midpoint(P2, P3)`.
2652
+ */
2653
+ declare const ambushDrawRule: ControlMeasureDrawRule;
2654
+ //#endregion
2655
+ //#region src/draw-rules/line1.d.ts
2656
+ declare const line1DrawRule: ControlMeasureDrawRule;
2657
+ //#endregion
2658
+ //#region src/draw-rules/line10.d.ts
2659
+ /**
2660
+ * Line10 — PT1 is the arrow tip, PT2 is the rear, and derived PT3 selects
2661
+ * which side of the PT2 -> PT1 chord contains the 90-degree arc.
2662
+ */
2663
+ declare const turnDrawRule: ControlMeasureDrawRule;
2664
+ //#endregion
2665
+ //#region src/draw-rules/line23.d.ts
2666
+ /**
2667
+ * Line23 anchor draw rule for the Clear mission task.
2668
+ *
2669
+ * P1/P2 are the endpoints of the symbol's vertical line (its height); P3 is
2670
+ * constrained to the perpendicular axis through `midpoint(P1, P2)` and defines
2671
+ * the rear of the symbol (the shaft length). Geometrically identical to the
2672
+ * obstacle-bypass `Point12` rule, but kept as its own spec id to match the
2673
+ * doctrinal draw rule for Clear.
2674
+ */
2675
+ declare const line23DrawRule: ControlMeasureDrawRule;
2676
+ //#endregion
2677
+ //#region src/draw-rules/line24.d.ts
2678
+ /**
2679
+ * Line24 anchor draw rule for the Delay mission task.
2680
+ *
2681
+ * PT. 1 and PT. 2 are the free straight-line endpoints. PT. 3 is constrained to
2682
+ * the perpendicular axis through PT. 2, where its signed distance from PT. 2
2683
+ * defines the semicircular arc diameter and side. Unlike the sibling Line23
2684
+ * (Clear) rule, the third point must be placed explicitly (three user clicks),
2685
+ * with a two-point live preview before commit.
2686
+ */
2687
+ declare const line24DrawRule: ControlMeasureDrawRule;
2688
+ //#endregion
2689
+ //#region src/draw-rules/line26.d.ts
2690
+ /**
2691
+ * Line26 anchor draw rule for the Cover, Guard, and Screen security tasks.
2692
+ *
2693
+ * PT. 1/PT. 4 are the outward arrow tips and PT. 2/PT. 3 bound the opening
2694
+ * reserved for the supported tactical symbol. All four anchors are free: the
2695
+ * two sides may independently touch the symbols that define the task limits.
2696
+ * During drawing, the cursor after PT. 1 supplies a provisional PT. 2 and the
2697
+ * rule mirrors that first leg across a temporary center opening, so the full
2698
+ * symbol is visible before PT. 2 is committed.
2699
+ */
2700
+ declare const line26DrawRule: ControlMeasureDrawRule;
2701
+ //#endregion
2702
+ //#region src/draw-rules/area8.d.ts
2703
+ declare const supportByFireDrawRule: ControlMeasureDrawRule;
2704
+ //#endregion
2705
+ //#region src/draw-rules/axis1.d.ts
2706
+ declare const axis1DrawRule: ControlMeasureDrawRule;
2707
+ //#endregion
2708
+ //#region src/draw-rules/rectangle.d.ts
2709
+ declare const rectangleDrawRule: ControlMeasureDrawRule;
2710
+ //#endregion
2711
+ //#region src/generators/cm14-maneuver-lines/ambush.d.ts
2712
+ /**
2713
+ * Configuration options for the Ambush tactical symbol.
2714
+ */
2715
+ interface AmbushOptions {
2716
+ /** Number of segments used to draw the quadratic curve (default: 30) */
2717
+ arcSegments?: number;
2718
+ /** Size of arrowhead relative to chord span (default: 0.15) */
2719
+ arrowheadLengthRatio?: number;
2720
+ /** Width of arrowhead wings relative to its length (default: 0.5) */
2721
+ arrowheadWidthRatio?: number;
2722
+ /** Length of parallel hatches relative to chord span (default: 0.15) */
2723
+ hatchLengthRatio?: number;
2724
+ /** Number of parallel hatches along the curve (default: 5) */
2725
+ hatchCount?: number;
2726
+ /** Depth of the curve toward PT 1 relative to chord span (default: 0.25) */
2727
+ curveDepthRatio?: number;
2728
+ }
2729
+ declare const DEFAULT_AMBUSH_OPTIONS: Required<AmbushOptions>;
2730
+ //#endregion
2731
+ export { ObstacleBypassDifficultOptions as $, DirectionOfAttackAviationOptions as $n, SupportByFireOptions as $t, roundToFixed as A, DEFAULT_JOINT_TACTICAL_ACTION_AREA_OPTIONS as An, canonicalTextAmplifierKey as Ar, DEFAULT_TACTICAL_ARROW_OPTIONS as At, isKind as B, ControlMeasureRender as Bn, BlockMissionTaskOptions as Bt, BaselineFrame as C, computeInitialWidthPoint as Cn, CanonicalTextAmplifiers as Cr, ScreenOptions as Ct, createBaselineFrame as D, PickupZoneOptions as Dn, TextAmplifierField as Dr, DelayOptions as Dt, BaselineFrameOrigin as E, DEFAULT_PICKUP_ZONE_OPTIONS as En, TEXT_AMPLIFIER_FIELDS as Er, DEFAULT_DELAY_OPTIONS as Et, freezeOrientationOptions as F, DEFAULT_AREA_DEFENSE_OPTIONS as Fn, DEFAULT_CANALIZE_OPTIONS as Ft, OptionsByKind as G, FillPattern as Gn, HandoverLineOptions as Gt, CONTROL_MEASURE_METADATA as H, StyleHints as Hn, BattleHandoverLineOptions as Ht, RenderOptions as I, DEFAULT_ENCIRCLEMENT_OPTIONS as In, BypassOptions as It, getDefaultOptions as J, DEFAULT_DIRECTION_OF_SUPPORTING_ATTACK_OPTIONS as Jn, DEFAULT_FLOT_OPTIONS as Jt, getControlMeasureMetadata as K, DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS as Kn, DEFAULT_PHASE_LINE_OPTIONS as Kt, renderControlMeasure as L, EncirclementOptions as Ln, DEFAULT_BYPASS_OPTIONS as Lt, SimpleStyleRender as M, AssemblyAreaOptions as Mn, resolveAmplifierPlacement as Mr, ClearOptions as Mt, toSimpleStyle as N, DEFAULT_ASSEMBLY_AREA_OPTIONS as Nn, AnchorTransformEvent as Nr, DEFAULT_CLEAR_OPTIONS as Nt, EPSILON as O, DEFAULT_LANDING_ZONE_OPTIONS as On, TextAmplifierKey as Or, CoverOptions as Ot, resolveStyleHints as P, AreaDefenseOptions as Pn, ControlMeasureDrawRule as Pr, CanalizeOptions as Pt, DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS as Q, DEFAULT_DIRECTION_OF_ATTACK_AVIATION_OPTIONS as Qn, DEFAULT_SUPPORT_BY_FIRE_OPTIONS as Qt, ControlMeasure as R, DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS as Rn, BreachOptions as Rt, snapToMidpointPerpendicular as S, calculateMetrics as Sn, AmplifierPlacements as Sr, DEFAULT_SCREEN_OPTIONS as St, BaselineFrameOptions as T, DEFAULT_AREA_OF_OPERATIONS_OPTIONS as Tn, LabelPlacementOverride as Tr, GuardOptions as Tt, ControlMeasureId as U, controlMeasureIdFromFeature as Un, DEFAULT_BATTLE_HANDOVER_LINE_OPTIONS as Ut, CONTROL_MEASURE_IDS as V, FeaturePartProps as Vn, DEFAULT_BLOCK_MISSION_TASK_OPTIONS as Vt, ControlMeasureKind as W, ControlMeasureStyle as Wn, DEFAULT_HANDOVER_LINE_OPTIONS as Wt, DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS as X, DEFAULT_DIRECTION_OF_MAIN_ATTACK_OPTIONS as Xn, AttackByFireOptions as Xt, listControlMeasureMetadata as Y, DirectionOfSupportingAttackOptions as Yn, FLOTOptions as Yt, ObstacleBypassImpossibleOptions as Z, DirectionOfMainAttackOptions as Zn, DEFAULT_ATTACK_BY_FIRE_OPTIONS as Zt, MidpointPerpendicularDrawRuleOptions as _, DEFAULT_CLASSIC_ARROW_OPTIONS as _n, ControlMeasureGeometryType as _r, FortifiedLineOptions as _t, supportByFireDrawRule as a, GenericCircleOptions as an, GenericC2LineOptions as ar, FixOptions as at, getMidpointPerpendicularSignedDistance as b, DEFAULT_MAIN_ATTACK_OPTIONS as bn, TextAmplifierDescriptor as br, AntitankDitchOptions as bt, line23DrawRule as c, DEFAULT_GENERIC_POLYGON_OPTIONS as cn, DEFAULT_LIGHT_LINE_OPTIONS as cr, BlockOptions as ct, ambushDrawRule as d, GenericLineOptions as dn, Point2D as dr, TurningMovementOptions as dt, AttackHelicopterOptions as en, DEFAULT_STRONG_POINT_OPTIONS as er, DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS as et, attackByFireDrawRule as f, BlockArrowHeadStyle as fn, project as fr, DEFAULT_FRONTAL_ATTACK_OPTIONS as ft, blockDrawRule as g, ClassicArrowOptions as gn, ControlMeasureGeometry as gr, DEFAULT_FORTIFIED_LINE_OPTIONS as gt, disruptDrawRule as h, ClassicArrowHeadStyle as hn, DEFAULT_BOUNDARY_OPTIONS as hr, FortifiedAreaOptions as ht, axis1DrawRule as i, DEFAULT_GENERIC_CIRCLE_OPTIONS as in, DEFAULT_GENERIC_C2_LINE_OPTIONS as ir, DEFAULT_FIX_OPTIONS as it, SimpleStyleProps as j, JointTacticalActionAreaOptions as jn, normalizeTextAmplifiers as jr, TacticalArrowOptions as jt, getMetersPerPixel as k, LandingZoneOptions as kn, TextAmplifiers as kr, DEFAULT_COVER_OPTIONS as kt, turnDrawRule as l, GenericPolygonOptions as ln, LightLineOptions as lr, DEFAULT_BLOCK_OPTIONS as lt, centerRadiusDrawRule as m, DEFAULT_BLOCK_ARROW_OPTIONS as mn, BoundaryOptions as mr, DEFAULT_FORTIFIED_AREA_OPTIONS as mt, DEFAULT_AMBUSH_OPTIONS as n, AirborneAttackOptions as nn, BattlePositionOptions as nr, DEFAULT_TURN_OPTIONS as nt, line26DrawRule as o, DEFAULT_GENERIC_RECTANGLE_OPTIONS as on, DEFAULT_ENGINEER_WORK_LINE_OPTIONS as or, DEFAULT_DISRUPT_OPTIONS as ot, point12DrawRule as p, BlockArrowOptions as pn, unproject as pr, FrontalAttackOptions as pt, getControlMeasureMetadataByValue as q, PrincipalDirectionOfFireOptions as qn, PhaseLineOptions as qt, rectangleDrawRule as r, DEFAULT_AIRBORNE_ATTACK_OPTIONS as rn, DEFAULT_BATTLE_POSITION_OPTIONS as rr, TurnOptions as rt, line24DrawRule as s, GenericRectangleOptions as sn, EngineerWorkLineOptions as sr, DisruptOptions as st, AmbushOptions as t, DEFAULT_ATTACK_HELICOPTER_OPTIONS as tn, StrongPointOptions as tr, ObstacleBypassEasyOptions as tt, line1DrawRule as u, DEFAULT_GENERIC_LINE_OPTIONS as un, LabelSizeOptions as ur, DEFAULT_TURNING_MOVEMENT_OPTIONS as ut, computeDefaultMidpointPerpendicularPoint as v, DEFAULT_SUPPORTING_ATTACK_OPTIONS as vn, ControlMeasureMetadata as vr, AntitankWallOptions as vt, BaselineFrameNormal as w, AreaOfOperationsOptions as wn, GeneratedLabelKey as wr, DEFAULT_GUARD_OPTIONS as wt, pointOnMidpointPerpendicularAxis as x, MainAttackOptions as xn, AmplifierPlacement as xr, DEFAULT_ANTITANK_DITCH_OPTIONS as xt, createMidpointPerpendicularDrawRule as y, SupportingAttackOptions as yn, ParamDescriptor as yr, DEFAULT_ANTITANK_WALL_OPTIONS as yt, cloneControlMeasure as z, FinalProtectiveFireOptions as zn, DEFAULT_BREACH_OPTIONS as zt };