@orbat-mapper/control-measures 0.2.0-alpha.8 → 0.2.0

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