@orbat-mapper/control-measures 0.2.0-alpha.3 → 0.2.0-alpha.31

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 (87) hide show
  1. package/README.md +55 -3
  2. package/dist/index-c_3HSN3X.d.mts +2939 -0
  3. package/dist/index.d.mts +2 -2
  4. package/dist/index.mjs +38 -8
  5. package/dist/preview/index.d.mts +110 -3
  6. package/dist/preview/index.mjs +235 -21
  7. package/dist/renderControlMeasure-EdeAQZIo.mjs +12589 -0
  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 -0
  33. package/media/classic-arrow.svg +1 -1
  34. package/media/clear.svg +1 -1
  35. package/media/cover.svg +1 -0
  36. package/media/delay.svg +1 -1
  37. package/media/direction-of-attack-aviation.svg +1 -0
  38. package/media/direction-of-main-attack.svg +1 -0
  39. package/media/direction-of-supporting-attack.svg +1 -0
  40. package/media/disrupt.svg +1 -1
  41. package/media/drop-zone.svg +1 -0
  42. package/media/encirclement.svg +1 -0
  43. package/media/engineer-work-line.svg +1 -0
  44. package/media/extraction-zone.svg +1 -0
  45. package/media/final-protective-fire-left.svg +1 -1
  46. package/media/final-protective-fire-right.svg +1 -1
  47. package/media/fix.svg +1 -1
  48. package/media/flot.svg +1 -1
  49. package/media/fortified-area.svg +1 -1
  50. package/media/fortified-line.svg +1 -1
  51. package/media/frontal-attack.svg +1 -0
  52. package/media/generic-c2-area.svg +1 -0
  53. package/media/generic-c2-line.svg +1 -0
  54. package/media/guard.svg +1 -0
  55. package/media/guerrilla-base.svg +1 -0
  56. package/media/handover-line.svg +1 -0
  57. package/media/isolate.svg +1 -1
  58. package/media/joint-tactical-action-area.svg +1 -0
  59. package/media/landing-zone.svg +1 -0
  60. package/media/light-line.svg +1 -0
  61. package/media/limited-access-area.svg +1 -0
  62. package/media/line.svg +1 -0
  63. package/media/main-attack.svg +1 -1
  64. package/media/named-area-of-interest.svg +1 -0
  65. package/media/no-fire-area-irregular.svg +1 -0
  66. package/media/objective-area.svg +1 -0
  67. package/media/obstacle-bypass-difficult.svg +1 -1
  68. package/media/obstacle-bypass-easy.svg +1 -1
  69. package/media/obstacle-bypass-impossible.svg +1 -1
  70. package/media/phase-line.svg +1 -0
  71. package/media/pickup-zone.svg +1 -0
  72. package/media/polygon.svg +1 -0
  73. package/media/principal-direction-of-fire.svg +1 -1
  74. package/media/rectangle.svg +1 -0
  75. package/media/screen.svg +1 -0
  76. package/media/search-area.svg +1 -1
  77. package/media/strong-point.svg +1 -0
  78. package/media/submarine-action-area.svg +1 -0
  79. package/media/submarine-generated-action-area.svg +1 -0
  80. package/media/support-by-fire.svg +1 -1
  81. package/media/supporting-attack.svg +1 -1
  82. package/media/target-area-of-interest.svg +1 -0
  83. package/media/turn.svg +1 -1
  84. package/media/turning-movement.svg +1 -0
  85. package/package.json +1 -1
  86. package/dist/index-BJYbQlzo.d.mts +0 -1713
  87. package/dist/renderControlMeasure-DkXDSrLz.mjs +0 -6877
@@ -0,0 +1,2939 @@
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/rendered.d.ts
1011
+ /**
1012
+ * Per-feature style hints carried on `properties.style`.
1013
+ *
1014
+ * These are *resolved*: `renderControlMeasure` cascades `graphicsStyle` →
1015
+ * `cm.style` → any generator pattern hint, then expands the monocolor `color`
1016
+ * into concrete `strokeColor` / `fillColor` per feature (see ADR-0011 and
1017
+ * `resolveSymbolColor`). Output therefore carries concrete colors, never the
1018
+ * input-only `color` key, and a `fillColor` only on parts the generator
1019
+ * marked filled.
1020
+ *
1021
+ * Generators contribute paint *role* and *pattern* (a part is filled; a
1022
+ * sub-line is dashed regardless of the user's stroke), never a hue. Adapters
1023
+ * merge the resulting `StyleHints` over their layer-level style at draw time.
1024
+ */
1025
+ interface StyleHints extends ControlMeasureStyle {}
1026
+ /**
1027
+ * Per-feature properties emitted by `renderControlMeasure`.
1028
+ *
1029
+ * Stable-id contract — every feature produced by the renderer has:
1030
+ * - `feature.id` of the form `${cmId}:${part}:${index}`
1031
+ * - `properties.part` matching the `part` segment of the id
1032
+ * - `properties.index` matching the `index` segment of the id
1033
+ *
1034
+ * Adapters rely on this contract to diff renders in place without keeping
1035
+ * their own bookkeeping. Use `controlMeasureIdFromFeature` to recover the
1036
+ * `cmId` from a picked feature.
1037
+ */
1038
+ interface FeaturePartProps {
1039
+ part: string;
1040
+ index: number;
1041
+ style?: StyleHints;
1042
+ /** Label text emitted by generators (e.g. breach "B"). */
1043
+ text?: string;
1044
+ /** Label rotation in radians, emitted by generators. */
1045
+ rotation?: number;
1046
+ /**
1047
+ * Horizontal text alignment relative to the label point: `"start"` = the
1048
+ * text begins at the point, `"end"` = it ends there. Absent = centered.
1049
+ */
1050
+ textAnchor?: "start" | "end";
1051
+ /** Render an opaque light backdrop behind text placed over patterned geometry. */
1052
+ textBackground?: boolean;
1053
+ /** Render a contrast-aware halo behind the glyphs so text stays legible on busy backgrounds. */
1054
+ textHalo?: boolean;
1055
+ /** Halo color contrasting with the resolved text color; present only when `textHalo` is set. */
1056
+ textHaloColor?: string;
1057
+ /** Canonical field key for a text-amplifier label that may be repositioned. */
1058
+ amplifierField?: TextAmplifierKey;
1059
+ /** Stable key used to persist a user-adjusted anchor for any rendered label. */
1060
+ labelPlacementKey?: string;
1061
+ /**
1062
+ * Screen-anchored label size in CSS pixels — held constant on screen
1063
+ * (ADR-0028). Mutually exclusive with `textSizeMeters`; absent both,
1064
+ * adapters render their engine default, screen-fixed.
1065
+ */
1066
+ textSizePixels?: number;
1067
+ /**
1068
+ * Ground-anchored label text height in projected meters (ADR-0028).
1069
+ * Adapters render `clamp(textSizeMeters / resolution, min, max)` px, per
1070
+ * their configured clamp band.
1071
+ */
1072
+ textSizeMeters?: number;
1073
+ /**
1074
+ * Multi-line justification within the text block (Text's `textAlign`
1075
+ * option); the block itself stays centered on the anchor regardless of this
1076
+ * value — unrelated to the block-shifting `textAnchor`.
1077
+ */
1078
+ textJustify?: "left" | "center" | "right";
1079
+ /** Closed typography preset for a text label (Text's `textStyle` option). */
1080
+ textStyle?: "regular" | "italic" | "light" | "caps";
1081
+ /**
1082
+ * Hide threshold in CSS pixels: when the derived on-screen text size exceeds
1083
+ * this, adapters render nothing for the label instead of clamping (ADR-0037)
1084
+ * and skip the default 8-24px ground clamp band.
1085
+ */
1086
+ textMaxSizePixels?: number;
1087
+ }
1088
+ /**
1089
+ * Output of `renderControlMeasure`. A GeoJSON `FeatureCollection` whose
1090
+ * features satisfy the `FeaturePartProps` stable-id contract. See ADR-0010.
1091
+ */
1092
+ type ControlMeasureRender = FeatureCollection<Geometry, FeaturePartProps>;
1093
+ /**
1094
+ * Recover the originating control measure id (`cmId`) from a feature emitted
1095
+ * by `renderControlMeasure`. The feature id must match the stable-id contract
1096
+ * `${cmId}:${part}:${index}`; otherwise this throws.
1097
+ */
1098
+ declare function controlMeasureIdFromFeature(feature: Feature<Geometry, FeaturePartProps> | {
1099
+ id?: string | number;
1100
+ }): string;
1101
+ //#endregion
1102
+ //#region src/generators/cm14-maneuver-lines/finalProtectiveFire.d.ts
1103
+ /**
1104
+ * Configuration options for the Final Protective Fire tactical symbols.
1105
+ *
1106
+ * Identical to Principal Direction of Fire (arrowhead sizing), plus a filled
1107
+ * "blade" running along the inside of one arm.
1108
+ */
1109
+ interface FinalProtectiveFireOptions {
1110
+ /** Arrowhead length relative to each arm's own length (default: 0.07) */
1111
+ arrowheadLengthRatio?: number;
1112
+ /** Arrowhead wing spread relative to the arrowhead length (default: 0.67) */
1113
+ arrowheadWidthRatio?: number;
1114
+ /**
1115
+ * Blade height (its perpendicular reach into the inside of the V) relative
1116
+ * to the bladed arm's own length (default: 0.03).
1117
+ */
1118
+ bladeHeightRatio?: number;
1119
+ }
1120
+ declare const DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS: Required<FinalProtectiveFireOptions>;
1121
+ type FpfProps = {
1122
+ part?: string;
1123
+ fill?: true;
1124
+ style?: StyleHints;
1125
+ };
1126
+ declare function createFinalProtectiveFireLeft(coordinates: Position[], options?: FinalProtectiveFireOptions): FeatureCollection<MultiLineString | Polygon, FpfProps>;
1127
+ declare function createFinalProtectiveFireRight(coordinates: Position[], options?: FinalProtectiveFireOptions): FeatureCollection<MultiLineString | Polygon, FpfProps>;
1128
+ //#endregion
1129
+ //#region src/generators/cm15-maneuver-areas/encirclement.d.ts
1130
+ /**
1131
+ * Configuration options for the Encirclement control measure. Also carries
1132
+ * the shared {@link AreaLabelOptions} label placement for its Field N (ENY)
1133
+ * marker — the doctrinal example shows only the hostile marker, no name/H/W
1134
+ * rows.
1135
+ */
1136
+ interface EncirclementOptions extends AreaLabelOptions {
1137
+ /**
1138
+ * Spacing between adjacent barbs as a ratio of the symbol's mean radius;
1139
+ * smaller values pack the barbs more densely. The barbs are then distributed
1140
+ * evenly so they close the ring exactly.
1141
+ * @default 0.4
1142
+ */
1143
+ barbSpacingRatio?: number;
1144
+ /**
1145
+ * Barb length (height/amplitude) as a ratio of the symbol's mean radius.
1146
+ * @default 0.16
1147
+ */
1148
+ barbLengthRatio?: number;
1149
+ /**
1150
+ * Round the boundary by curving it through the control points (closed
1151
+ * centripetal Catmull-Rom) before tracing the barbs.
1152
+ * @default true
1153
+ */
1154
+ smooth?: boolean;
1155
+ /**
1156
+ * Number of samples per segment when `smooth` is enabled.
1157
+ * @default 16
1158
+ */
1159
+ smoothResolution?: number;
1160
+ }
1161
+ /**
1162
+ * Default options for the Encirclement control measure. Not `Required<...>`
1163
+ * — the inherited label-size options ({@link AreaLabelOptions}) have no
1164
+ * static default, so this covers only the barb/smoothing options.
1165
+ */
1166
+ declare const DEFAULT_ENCIRCLEMENT_OPTIONS: EncirclementOptions;
1167
+ /**
1168
+ * Creates an Encirclement tactical graphic: a complete smooth boundary ring
1169
+ * with outward arrowhead barbs resting on it. The boundary is an unfilled
1170
+ * Polygon; the barbs are open "V" strokes (a MultiLineString) whose base is the
1171
+ * boundary arc itself. When a Field N (ENY) marker is set, it masks the
1172
+ * boundary with a knockout gap wherever its text box touches the ring
1173
+ * (mirroring Field B's echelon glyph, ADR-0023) — the boundary becomes a
1174
+ * gapped MultiLineString instead of a closed Polygon, and any barb whose
1175
+ * center falls inside the gap is suppressed; the no-`N` case is unaffected.
1176
+ *
1177
+ * @param positions - Area anchor points (>=3); the input contract is enforced
1178
+ * at the render seam (ADR-0014).
1179
+ * @param options - {@link EncirclementOptions}.
1180
+ * @param textAmplifiers - Field N only — rendered as "ENY" markers at the
1181
+ * ring's west and east edges, per the doctrinal hostile example.
1182
+ */
1183
+ declare function createEncirclement(positions: Position[], options?: EncirclementOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1184
+ //#endregion
1185
+ //#region src/generators/cm15-maneuver-areas/area.d.ts
1186
+ /** Configuration options for the Area control measure. */
1187
+ type AreaOptions = LabeledAreaOptions;
1188
+ /**
1189
+ * Creates an Area control measure: a closed area through `positions` labeled
1190
+ * at its center with an un-prefixed `T` (Field T) plus an `N` (Field N) ENY
1191
+ * marker, per {@link labeledAreaFeatures}.
1192
+ */
1193
+ declare function createArea(positions: Position[], options?: AreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1194
+ //#endregion
1195
+ //#region src/generators/cm15-maneuver-areas/area-defense.d.ts
1196
+ interface AreaDefenseOptions extends LabelSizeOptions {
1197
+ /** Angular opening between the two arrow tips, in degrees. */
1198
+ arrowOpeningAngle?: number;
1199
+ /** Angular opening occupied by the AD label, in degrees. */
1200
+ labelOpeningAngle?: number;
1201
+ /** Number of filled outward barbs distributed over both arcs. */
1202
+ barbCount?: number;
1203
+ /** Barb height as a ratio of the radius. */
1204
+ barbLengthRatio?: number;
1205
+ /** Open-arrowhead length as a ratio of the radius. */
1206
+ arrowheadLengthRatio?: number;
1207
+ }
1208
+ declare const DEFAULT_AREA_DEFENSE_OPTIONS: Required<Omit<AreaDefenseOptions, keyof LabelSizeOptions>>;
1209
+ declare function createAreaDefense(coordinates: Position[], options?: AreaDefenseOptions): FeatureCollection<MultiLineString | MultiPolygon | Point>;
1210
+ //#endregion
1211
+ //#region src/generators/cm15-maneuver-areas/assemblyArea.d.ts
1212
+ /** Configuration options for the Assembly area control measure. */
1213
+ type AssemblyAreaOptions = LabeledAreaOptions;
1214
+ /** Default options for the Assembly area control measure. */
1215
+ declare const DEFAULT_ASSEMBLY_AREA_OPTIONS: AssemblyAreaOptions;
1216
+ /**
1217
+ * Creates an Assembly area control measure: a closed area through
1218
+ * `positions` labeled at its center with "AA "-prefixed `T` (Field T) plus
1219
+ * `H`/`W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1220
+ */
1221
+ declare function createAssemblyArea(positions: Position[], options?: AssemblyAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1222
+ //#endregion
1223
+ //#region src/generators/cm15-maneuver-areas/jointTacticalActionArea.d.ts
1224
+ /** Configuration options for the Joint tactical action area control measure. */
1225
+ type JointTacticalActionAreaOptions = LabeledAreaOptions;
1226
+ /** Default options for the Joint tactical action area control measure. */
1227
+ declare const DEFAULT_JOINT_TACTICAL_ACTION_AREA_OPTIONS: JointTacticalActionAreaOptions;
1228
+ /**
1229
+ * Creates a Joint tactical action area control measure: a closed area
1230
+ * through `positions` labeled at its center with "JTAA -"-prefixed `T`
1231
+ * (Field T) plus `H`/`W`/`W1`/`N` amplifier rows, per
1232
+ * {@link labeledAreaFeatures}.
1233
+ */
1234
+ declare function createJointTacticalActionArea(positions: Position[], options?: JointTacticalActionAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1235
+ //#endregion
1236
+ //#region src/generators/cm15-maneuver-areas/submarineActionArea.d.ts
1237
+ /** Configuration options for the Submarine action area control measure. */
1238
+ type SubmarineActionAreaOptions = LabeledAreaOptions;
1239
+ /**
1240
+ * Creates a Submarine action area control measure: a closed area through
1241
+ * `positions` labeled at its center with "SAA -"-prefixed `T` (Field T) plus
1242
+ * `W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1243
+ */
1244
+ declare function createSubmarineActionArea(positions: Position[], options?: SubmarineActionAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1245
+ //#endregion
1246
+ //#region src/generators/cm15-maneuver-areas/submarineGeneratedActionArea.d.ts
1247
+ /** Configuration options for the Submarine-generated action area control measure. */
1248
+ type SubmarineGeneratedActionAreaOptions = LabeledAreaOptions;
1249
+ /**
1250
+ * Creates a Submarine-generated action area control measure: a closed area
1251
+ * through `positions` labeled at its center with "SGSA -"-prefixed `T`
1252
+ * (Field T) plus `W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1253
+ */
1254
+ declare function createSubmarineGeneratedActionArea(positions: Position[], options?: SubmarineGeneratedActionAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1255
+ //#endregion
1256
+ //#region src/generators/cm15-maneuver-areas/dropZone.d.ts
1257
+ /** Configuration options for the Drop zone control measure. */
1258
+ type DropZoneOptions = LabeledAreaOptions;
1259
+ /**
1260
+ * Creates a Drop zone control measure: a closed area through `positions`
1261
+ * labeled at its center with "DZ "-prefixed `T` (Field T) plus an `N`
1262
+ * (Field N) ENY marker, per {@link labeledAreaFeatures}.
1263
+ */
1264
+ declare function createDropZone(positions: Position[], options?: DropZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1265
+ //#endregion
1266
+ //#region src/generators/cm15-maneuver-areas/extractionZone.d.ts
1267
+ /** Configuration options for the Extraction zone control measure. */
1268
+ type ExtractionZoneOptions = LabeledAreaOptions;
1269
+ /**
1270
+ * Creates an Extraction zone control measure: a closed area through
1271
+ * `positions` labeled at its center with "EZ "-prefixed `T` (Field T) plus
1272
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1273
+ */
1274
+ declare function createExtractionZone(positions: Position[], options?: ExtractionZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1275
+ //#endregion
1276
+ //#region src/generators/cm15-maneuver-areas/landingZone.d.ts
1277
+ /** Configuration options for the Landing zone control measure. */
1278
+ type LandingZoneOptions = LabeledAreaOptions;
1279
+ /** Default options for the Landing zone control measure. */
1280
+ declare const DEFAULT_LANDING_ZONE_OPTIONS: LandingZoneOptions;
1281
+ /**
1282
+ * Creates a Landing zone control measure: a closed area through `positions`
1283
+ * labeled at its center with "LZ "-prefixed `T` (Field T) plus `H`/`W`/`W1`/`N`
1284
+ * amplifier rows, per {@link labeledAreaFeatures}.
1285
+ */
1286
+ declare function createLandingZone(positions: Position[], options?: LandingZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1287
+ //#endregion
1288
+ //#region src/generators/cm15-maneuver-areas/limitedAccessArea.d.ts
1289
+ /** Configuration options for the Limited Access Area control measure. */
1290
+ interface LimitedAccessAreaOptions extends AreaLabelOptions {
1291
+ /** Round the area's corners through its control points. */
1292
+ smooth?: boolean;
1293
+ /** Number of samples per segment when smoothing is enabled. */
1294
+ smoothResolution?: number;
1295
+ }
1296
+ /** Creates a back-hatched free area with a movable "LAA" label, centered by default. */
1297
+ declare function createLimitedAccessArea(positions: Position[], options?: LimitedAccessAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1298
+ //#endregion
1299
+ //#region src/generators/cm24-fire-areas/noFireAreaIrregular.d.ts
1300
+ /** Configuration options for the irregular No Fire Area control measure. */
1301
+ interface NoFireAreaIrregularOptions extends AreaLabelOptions {
1302
+ /** Round the area's corners through its control points. */
1303
+ smooth?: boolean;
1304
+ /** Number of samples per segment when smoothing is enabled. */
1305
+ smoothResolution?: number;
1306
+ }
1307
+ /** Creates a back-hatched irregular NFA with its centered movable label fields. */
1308
+ declare function createNoFireAreaIrregular(positions: Position[], options?: NoFireAreaIrregularOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1309
+ //#endregion
1310
+ //#region src/generators/cm15-maneuver-areas/pickupZone.d.ts
1311
+ /** Configuration options for the Pickup zone control measure. */
1312
+ type PickupZoneOptions = LabeledAreaOptions;
1313
+ /** Default options for the Pickup zone control measure. */
1314
+ declare const DEFAULT_PICKUP_ZONE_OPTIONS: PickupZoneOptions;
1315
+ /**
1316
+ * Creates a Pickup zone control measure: a closed area through `positions`
1317
+ * labeled at its center with "PZ "-prefixed `T` (Field T) plus `H`/`W`/`W1`/`N`
1318
+ * amplifier rows, per {@link labeledAreaFeatures}.
1319
+ */
1320
+ declare function createPickupZone(positions: Position[], options?: PickupZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1321
+ //#endregion
1322
+ //#region src/generators/cm15-maneuver-areas/assaultPosition.d.ts
1323
+ /** Configuration options for the Assault position control measure. */
1324
+ type AssaultPositionOptions = LabeledAreaOptions;
1325
+ /**
1326
+ * Creates an Assault position control measure: a closed area through
1327
+ * `positions` labeled at its center with "ASLT "-prefixed `T` (Field T) plus
1328
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1329
+ */
1330
+ declare function createAssaultPosition(positions: Position[], options?: AssaultPositionOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1331
+ //#endregion
1332
+ //#region src/generators/cm15-maneuver-areas/attackPosition.d.ts
1333
+ /** Configuration options for the Attack position control measure. */
1334
+ type AttackPositionOptions = LabeledAreaOptions;
1335
+ /**
1336
+ * Creates an Attack position control measure: a closed area through
1337
+ * `positions` labeled at its center with "ATK "-prefixed `T` (Field T) plus
1338
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1339
+ */
1340
+ declare function createAttackPosition(positions: Position[], options?: AttackPositionOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1341
+ //#endregion
1342
+ //#region src/generators/cm15-maneuver-areas/objectiveArea.d.ts
1343
+ /** Configuration options for the Objective area control measure. */
1344
+ type ObjectiveAreaOptions = LabeledAreaOptions;
1345
+ /**
1346
+ * Creates an Objective area control measure: a closed area through
1347
+ * `positions` labeled at its center with "OBJ "-prefixed `T` (Field T) plus
1348
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1349
+ */
1350
+ declare function createObjectiveArea(positions: Position[], options?: ObjectiveAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1351
+ //#endregion
1352
+ //#region src/generators/cm12-command-control-areas/area-of-operations.d.ts
1353
+ /** Configuration options for the Area of operations control measure. */
1354
+ type AreaOfOperationsOptions = LabeledAreaOptions;
1355
+ /** Default options for the Area of operations control measure. */
1356
+ declare const DEFAULT_AREA_OF_OPERATIONS_OPTIONS: AreaOfOperationsOptions;
1357
+ /**
1358
+ * Creates an Area of operations control measure: a closed area through
1359
+ * `positions` labeled at its center with "AO "-prefixed `T` (Field T) plus
1360
+ * `H`/`W`/`W1`/`N` amplifier rows, per {@link labeledAreaFeatures}.
1361
+ */
1362
+ declare function createAreaOfOperations(positions: Position[], options?: AreaOfOperationsOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1363
+ //#endregion
1364
+ //#region src/generators/cm12-command-control-areas/named-area-of-interest.d.ts
1365
+ /** Configuration options for the Named area of interest control measure. */
1366
+ type NamedAreaOfInterestOptions = LabeledAreaOptions;
1367
+ /**
1368
+ * Creates a Named area of interest control measure: a closed area through
1369
+ * `positions` labeled at its center with "NAI "-prefixed `T` (Field T) plus
1370
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1371
+ */
1372
+ declare function createNamedAreaOfInterest(positions: Position[], options?: NamedAreaOfInterestOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1373
+ //#endregion
1374
+ //#region src/generators/cm12-command-control-areas/target-area-of-interest.d.ts
1375
+ /** Configuration options for the Target area of interest control measure. */
1376
+ type TargetAreaOfInterestOptions = LabeledAreaOptions;
1377
+ /**
1378
+ * Creates a Target area of interest control measure: a closed area through
1379
+ * `positions` labeled at its center with "TAI "-prefixed `T` (Field T) plus
1380
+ * an `N` (Field N) ENY marker, per {@link labeledAreaFeatures}.
1381
+ */
1382
+ declare function createTargetAreaOfInterest(positions: Position[], options?: TargetAreaOfInterestOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1383
+ //#endregion
1384
+ //#region src/generators/cm12-command-control-areas/airfield-zone.d.ts
1385
+ /** Configuration options for the Airfield zone control measure. */
1386
+ interface AirfieldZoneOptions extends LabeledAreaOptions {
1387
+ /**
1388
+ * The runway glyph's long line, as a ratio of the ring's projected
1389
+ * bounding-box width (full length, not half).
1390
+ * @default 0.55
1391
+ */
1392
+ glyphSizeRatio?: number;
1393
+ }
1394
+ /**
1395
+ * Creates an Airfield zone control measure: a closed area through
1396
+ * `positions` with a runway glyph (two crossed lines forming a shallow
1397
+ * asymmetric X) centered on the ring, and Field H placed outside the area to
1398
+ * the east when set.
1399
+ *
1400
+ * @param positions - Area anchor points (≥3); the input contract is enforced
1401
+ * at the render seam (ADR-0014).
1402
+ * @param options - {@link AirfieldZoneOptions}.
1403
+ * @param textAmplifiers - Field H (placed east of the area) plus an optional
1404
+ * Field N "ENY" hostile marker on the west/east edges.
1405
+ */
1406
+ declare function createAirfieldZone(positions: Position[], options?: AirfieldZoneOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1407
+ //#endregion
1408
+ //#region src/generators/cm12-command-control-areas/echelon-labeled-area.d.ts
1409
+ /**
1410
+ * Configuration options shared by Base Camp and Guerrilla Base: the full L-15
1411
+ * label placement ({@link LabeledAreaOptions}) plus Battle Position's Field B
1412
+ * echelon knobs.
1413
+ */
1414
+ interface EchelonLabeledAreaOptions extends LabeledAreaOptions {
1415
+ /**
1416
+ * Field B echelon straddling the boundary. `"none"` (the default — the
1417
+ * standard's examples show no echelon glyph), empty, or unknown renders no
1418
+ * glyph and leaves the boundary unaffected by echelon masking.
1419
+ * @default "none"
1420
+ */
1421
+ echelon?: string;
1422
+ /**
1423
+ * Echelon glyph height in meters (ground-anchored). Ignored when
1424
+ * `echelonSizePixels` is supplied together with `metersPerPixel`.
1425
+ * @default 750
1426
+ */
1427
+ echelonSize?: number;
1428
+ /**
1429
+ * Echelon glyph height in screen pixels (screen-anchored). Resolved to
1430
+ * meters against `metersPerPixel`; bakes to a meter size on draw/edit
1431
+ * commit (ADR-0020).
1432
+ * @default 16
1433
+ */
1434
+ echelonSizePixels?: number;
1435
+ /**
1436
+ * Gap left on each side of the echelon glyph, as a ratio of the glyph
1437
+ * height. `0` butts the boundary against the glyph; larger values widen
1438
+ * the break.
1439
+ * @default 0.3
1440
+ */
1441
+ echelonPadding?: number;
1442
+ /**
1443
+ * Slides the echelon along the boundary, as a signed fraction of the total
1444
+ * perimeter measured from its default anchor on the bottom edge.
1445
+ * @default 0
1446
+ */
1447
+ echelonPosition?: number;
1448
+ /**
1449
+ * Absolute anchor for the echelon glyph, as a fraction of the total
1450
+ * perimeter measured from the ring seam, wrapped into `[0, 1)`. See Battle
1451
+ * Position's `echelonAnchor` (ADR-0023) — edit controllers freeze this via
1452
+ * the `freezeOrientation` hook the moment a rotate gesture starts.
1453
+ */
1454
+ echelonAnchor?: number;
1455
+ /**
1456
+ * Meters-per-pixel at the current zoom/latitude. Stamped by the host when
1457
+ * the measure is screen-anchored; required to resolve `echelonSizePixels`.
1458
+ */
1459
+ metersPerPixel?: number;
1460
+ }
1461
+ //#endregion
1462
+ //#region src/generators/cm12-command-control-areas/base-camp.d.ts
1463
+ /** Configuration options for the Base camp control measure. */
1464
+ type BaseCampOptions = EchelonLabeledAreaOptions;
1465
+ /**
1466
+ * Creates a Base camp control measure: a closed area through `positions`
1467
+ * labeled at its center with "BC "-prefixed `T` (Field T) plus `H`/`W`/`W1`/`N`
1468
+ * amplifier rows, and an optional Field B echelon glyph straddling the
1469
+ * boundary, per {@link echelonLabeledAreaFeatures}.
1470
+ */
1471
+ declare function createBaseCamp(positions: Position[], options?: BaseCampOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | MultiPolygon | Point>;
1472
+ //#endregion
1473
+ //#region src/generators/cm12-command-control-areas/guerrilla-base.d.ts
1474
+ /** Configuration options for the Guerrilla base control measure. */
1475
+ type GuerrillaBaseOptions = EchelonLabeledAreaOptions;
1476
+ /**
1477
+ * Creates a Guerrilla base control measure: a closed area through
1478
+ * `positions` labeled at its center with "GB "-prefixed `T` (Field T) plus
1479
+ * `H`/`W`/`W1`/`N` amplifier rows, and an optional Field B echelon glyph
1480
+ * straddling the boundary, per {@link echelonLabeledAreaFeatures}.
1481
+ */
1482
+ declare function createGuerrillaBase(positions: Position[], options?: GuerrillaBaseOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | MultiPolygon | Point>;
1483
+ //#endregion
1484
+ //#region src/generators/cm12-command-control-areas/generic-c2-area.d.ts
1485
+ /** Configuration options for the Generic command and control area control measure. */
1486
+ type GenericC2AreaOptions = LabeledAreaOptions;
1487
+ /**
1488
+ * Creates a Generic command and control area control measure: a closed area
1489
+ * through `positions` labeled at its center with the bare `T` (Field T) plus
1490
+ * `H`/`W`/`W1`/`N` amplifier rows — no prefix, per {@link labeledAreaFeatures}.
1491
+ */
1492
+ declare function createGenericC2Area(positions: Position[], options?: GenericC2AreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
1493
+ //#endregion
1494
+ //#region src/attack-utils.d.ts
1495
+ interface AttackOptions {
1496
+ shaftWidthRatio?: number;
1497
+ smooth?: boolean;
1498
+ smoothResolution?: number;
1499
+ }
1500
+ /**
1501
+ * Calculates the relative metrics (longitudinal and lateral) of the width point
1502
+ * relative to the Tip-Neck axis.
1503
+ *
1504
+ * @param pts - Array of positions [Tip, Neck, ..., WidthPoint]
1505
+ * @returns { longitudinal: number, lateral: number } | null
1506
+ */
1507
+ declare function calculateMetrics(pts: Position[]): {
1508
+ longitudinal: number;
1509
+ lateral: number;
1510
+ } | null;
1511
+ /**
1512
+ * Computes an initial Width Point based on the Tip and Neck positions.
1513
+ * It places the point perpendicular to the neck at a default distance relative to the length.
1514
+ *
1515
+ * @param tip - Tip position (Lon/Lat)
1516
+ * @param neck - Neck position (Lon/Lat)
1517
+ * @returns Width Point position (Lon/Lat)
1518
+ */
1519
+ declare function computeInitialWidthPoint(tip: Position, neck: Position): Position;
1520
+ //#endregion
1521
+ //#region src/generators/cm15-maneuver-areas/mainAttack.d.ts
1522
+ declare const DEFAULT_MAIN_ATTACK_OPTIONS: Required<AttackOptions>;
1523
+ type MainAttackOptions = AttackOptions;
1524
+ /**
1525
+ * Generates a GeoJSON FeatureCollection for a Main Attack tactical symbol.
1526
+ *
1527
+ * The symbol consists of a single MultiLineString feature containing:
1528
+ * 1. **Arrowhead**: A line forming a "chevron" or "roof" shape.
1529
+ * 2. **Shaft**: Two parallel lines behind the arrow.
1530
+ *
1531
+ * The shaft is calculated to terminate exactly where it touches the inner walls
1532
+ * of the arrowhead, creating a seamless connection.
1533
+ *
1534
+ * @param coordinates - An array of GeoJSON Positions (Lon/Lat).
1535
+ * Minimum 3 points required.
1536
+ * **Order matters:** * - Index 0: **Tip** (The sharp point of the arrow)
1537
+ * - Index 1 to N-2: **Spine** (The path the shaft follows)
1538
+ * - Index N-1: **Width Control** (Determines the width of the arrowhead)
1539
+ * @param options - Configuration for ratios and properties.
1540
+ * @returns A GeoJSON FeatureCollection containing a single MultiLineString.
1541
+ */
1542
+ declare function createMainAttack(coordinates: Position[], options?: MainAttackOptions): FeatureCollection<MultiLineString>;
1543
+ //#endregion
1544
+ //#region src/generators/cm15-maneuver-areas/supportingAttack.d.ts
1545
+ type SupportingAttackOptions = AttackOptions;
1546
+ declare const DEFAULT_SUPPORTING_ATTACK_OPTIONS: Required<SupportingAttackOptions>;
1547
+ /**
1548
+ * Generates a GeoJSON FeatureCollection for a Supporting Attack tactical symbol.
1549
+ *
1550
+ * The symbol differs from Main Attack in that it is a single LineString
1551
+ * outlining the arrow shape, rather than a filled Polygon header + Shaft lines.
1552
+ *
1553
+ * @param coordinates - An array of GeoJSON Positions.
1554
+ * @param options - Configuration options.
1555
+ * @returns A GeoJSON FeatureCollection<LineString>.
1556
+ */
1557
+ declare function createSupportingAttack(coordinates: Position[], options?: SupportingAttackOptions): FeatureCollection<LineString>;
1558
+ //#endregion
1559
+ //#region src/generators/cm99-generic-arrows/classicArrow.d.ts
1560
+ /**
1561
+ * A plain, clean arrow for illustrations — not a doctrinal symbol. The shaft is
1562
+ * a straight polyline through the drawn control points (Line1 contract) and the
1563
+ * tip carries a solid triangular arrowhead. No wobble, no curve: the canonical
1564
+ * "draw an arrow" graphic.
1565
+ */
1566
+ /**
1567
+ * Arrowhead silhouette:
1568
+ * - `triangle` — solid triangle with a flat back (the default).
1569
+ * - `barbed` — swept-back barbs with a forward notch (classic arrowhead).
1570
+ * - `concave` — a sharper barbed head with a deep forward notch.
1571
+ * - `diamond` — a rhombus, widest at its middle.
1572
+ * - `harpoon` — an asymmetric single-sided barb.
1573
+ * - `swallowtail` — barbs that sweep back into two trailing tails.
1574
+ * - `chevron` — a thick hollow "V".
1575
+ * - `circle` — a round dot terminator.
1576
+ * - `tee` — a flat crossbar terminator (no point).
1577
+ * - `open` — an unfilled "V", drawn as two strokes meeting at the tip.
1578
+ */
1579
+ type ClassicArrowHeadStyle = "triangle" | "barbed" | "concave" | "diamond" | "harpoon" | "swallowtail" | "chevron" | "circle" | "tee" | "open";
1580
+ interface ClassicArrowOptions {
1581
+ /** Arrowhead silhouette. */
1582
+ arrowheadStyle?: ClassicArrowHeadStyle;
1583
+ /** Round the shaft's corners by curving it through the control points. */
1584
+ smooth?: boolean;
1585
+ /** Number of samples per segment when smooth mode is enabled. */
1586
+ smoothResolution?: number;
1587
+ /** Arrowhead length as a fraction of the total path length. */
1588
+ arrowheadLengthRatio?: number;
1589
+ /** Arrowhead base width as a fraction of the total path length. */
1590
+ arrowheadWidthRatio?: number;
1591
+ }
1592
+ declare const DEFAULT_CLASSIC_ARROW_OPTIONS: Required<ClassicArrowOptions>;
1593
+ /**
1594
+ * Generates a GeoJSON FeatureCollection for the Classic Arrow: a shaft
1595
+ * LineString (trimmed so it doesn't poke through the head) plus a head feature
1596
+ * whose silhouette follows `arrowheadStyle` — a filled Polygon for the solid heads,
1597
+ * or an open "V" LineString for `open`.
1598
+ */
1599
+ declare function createClassicArrow(coordinates: Position[], options?: ClassicArrowOptions): FeatureCollection<LineString | Polygon, {
1600
+ part: "shaft" | "head";
1601
+ fill?: boolean;
1602
+ style?: StyleHints;
1603
+ }>;
1604
+ //#endregion
1605
+ //#region src/generators/cm99-generic-arrows/blockArrow.d.ts
1606
+ /**
1607
+ * A solid "block" arrow for illustrations — not a doctrinal symbol. The whole
1608
+ * arrow is one filled polygon: a shaft band of controllable width that runs
1609
+ * through the drawn Axis1 spine and flares into a wider triangular head at the
1610
+ * tip. Axis1 control points are ordered `[tip, neck, ...spine, width]`.
1611
+ */
1612
+ /**
1613
+ * Arrowhead silhouette (all carved from the one filled body):
1614
+ * - `triangle` — a flat-backed triangular head (the default).
1615
+ * - `barbed` — swept-back barbs with the shaft entering at a forward notch.
1616
+ * - `concave` — a sharper barbed head with a deeper notch.
1617
+ * - `diamond` — a kite that flares to its widest mid-head.
1618
+ * - `harpoon` — an asymmetric single-sided barb.
1619
+ * - `swallowtail` — barbs that sweep back into two trailing tails.
1620
+ * - `tee` — a flat crossbar terminator (no point).
1621
+ */
1622
+ type BlockArrowHeadStyle = "triangle" | "barbed" | "concave" | "diamond" | "harpoon" | "swallowtail" | "tee";
1623
+ interface BlockArrowOptions {
1624
+ /** Shaft band width as a fraction of the total path length. */
1625
+ shaftWidthRatio?: number;
1626
+ /** Arrowhead silhouette. */
1627
+ arrowheadStyle?: BlockArrowHeadStyle;
1628
+ /** Arrowhead base width as a fraction of the total path length. */
1629
+ arrowheadWidthRatio?: number;
1630
+ /** Arrowhead length as a fraction of the total path length. */
1631
+ arrowheadLengthRatio?: number;
1632
+ /** Round the shaft's corners by curving it through the control points. */
1633
+ smooth?: boolean;
1634
+ /** Number of samples per segment when smooth mode is enabled. */
1635
+ smoothResolution?: number;
1636
+ /** Fill the body solid; when false the arrow is drawn as an outline only. */
1637
+ filled?: boolean;
1638
+ }
1639
+ declare const DEFAULT_BLOCK_ARROW_OPTIONS: Required<BlockArrowOptions>;
1640
+ /**
1641
+ * Generates a GeoJSON FeatureCollection for the Block Arrow: a single filled
1642
+ * Polygon whose outline runs up the left side of the shaft, around the head
1643
+ * (whose silhouette follows `arrowheadStyle`) to the tip and back, then down the
1644
+ * right side of the shaft.
1645
+ */
1646
+ declare function createBlockArrow(coordinates: Position[], options?: BlockArrowOptions): FeatureCollection<Polygon, {
1647
+ part: "body";
1648
+ fill: boolean;
1649
+ }>;
1650
+ //#endregion
1651
+ //#region src/generators/cm99-generic-graphics/params.d.ts
1652
+ interface SmoothPathOptions {
1653
+ /** Curve the rendered path through the unchanged control points. */
1654
+ smooth?: boolean;
1655
+ /** Number of samples per segment when smoothing is enabled. */
1656
+ smoothResolution?: number;
1657
+ }
1658
+ interface FilledAreaOptions {
1659
+ /** Fill the polygon interior; false renders only its outline. */
1660
+ filled?: boolean;
1661
+ }
1662
+ //#endregion
1663
+ //#region src/generators/cm99-generic-graphics/line.d.ts
1664
+ type GenericLineOptions = SmoothPathOptions;
1665
+ declare const DEFAULT_GENERIC_LINE_OPTIONS: Required<GenericLineOptions>;
1666
+ declare function createGenericLine(coordinates: Position[], options?: GenericLineOptions): FeatureCollection<LineString>;
1667
+ //#endregion
1668
+ //#region src/generators/cm99-generic-graphics/polygon.d.ts
1669
+ interface GenericPolygonOptions extends SmoothPathOptions, FilledAreaOptions {}
1670
+ declare const DEFAULT_GENERIC_POLYGON_OPTIONS: Required<GenericPolygonOptions>;
1671
+ declare function createGenericPolygon(coordinates: Position[], options?: GenericPolygonOptions): FeatureCollection<Polygon, {
1672
+ part: string;
1673
+ fill: boolean;
1674
+ }>;
1675
+ //#endregion
1676
+ //#region src/generators/cm99-generic-graphics/rectangle.d.ts
1677
+ type GenericRectangleOptions = FilledAreaOptions;
1678
+ declare const DEFAULT_GENERIC_RECTANGLE_OPTIONS: Required<GenericRectangleOptions>;
1679
+ declare function createGenericRectangle(coordinates: Position[], options?: GenericRectangleOptions): FeatureCollection<Polygon, {
1680
+ part: string;
1681
+ fill: boolean;
1682
+ }>;
1683
+ //#endregion
1684
+ //#region src/generators/cm99-generic-graphics/circle.d.ts
1685
+ type GenericCircleOptions = FilledAreaOptions;
1686
+ declare const DEFAULT_GENERIC_CIRCLE_OPTIONS: Required<GenericCircleOptions>;
1687
+ declare function createGenericCircle(coordinates: Position[], options?: GenericCircleOptions): FeatureCollection<Polygon, {
1688
+ part: string;
1689
+ fill: boolean;
1690
+ }>;
1691
+ //#endregion
1692
+ //#region src/generators/cm99-generic-graphics/text.d.ts
1693
+ /** Configuration options for the generic Text control measure. */
1694
+ interface GenericTextOptions {
1695
+ /** Plain text; explicit `\n` breaks lines — never auto-wraps. @default "Text" */
1696
+ text?: string;
1697
+ /**
1698
+ * Placement of the text block relative to the anchor point, and the
1699
+ * justification of its lines. `left` puts the anchor at the block's left edge
1700
+ * (text extends rightward, lines left-justified); `right` puts the anchor at
1701
+ * the right edge (text extends leftward, lines right-justified); `center`
1702
+ * centers the block on the anchor (lines centered). Maps onto the existing
1703
+ * block-shifting `textAnchor` prop (`left` → `start`, `right` → `end`, `center`
1704
+ * → none) plus the `textJustify` prop; rotation always pivots at the anchor.
1705
+ * @default "center"
1706
+ */
1707
+ textAlign?: "left" | "center" | "right";
1708
+ /** Closed typography preset. `caps` uppercases `regular`; `light` is weight 300. @default "regular" */
1709
+ textStyle?: "regular" | "italic" | "light" | "caps";
1710
+ /** Clockwise rotation in degrees on screen. @default 0 */
1711
+ rotation?: number;
1712
+ /**
1713
+ * Text height (cap height) in projected meters — ground-anchored
1714
+ * (ADR-0020). Ignored whenever `sizePixels` is present.
1715
+ */
1716
+ sizeMeters?: number;
1717
+ /**
1718
+ * Text height in CSS pixels — screen-anchored (ADR-0020). A fresh draw is
1719
+ * authored in pixels and bakes to `sizeMeters` on commit.
1720
+ * @default 24
1721
+ */
1722
+ sizePixels?: number;
1723
+ /**
1724
+ * Hide threshold in CSS pixels: once the ground-derived on-screen size
1725
+ * exceeds this, adapters hide the text entirely instead of clamping it
1726
+ * (ADR-0037); there is no minimum, so the text just keeps shrinking on
1727
+ * zoom-out.
1728
+ * @default 200
1729
+ */
1730
+ maxSizePixels?: number;
1731
+ }
1732
+ declare const DEFAULT_GENERIC_TEXT_OPTIONS: GenericTextOptions;
1733
+ declare function createGenericText(coordinates: Position[], options?: GenericTextOptions): FeatureCollection<Point, Record<string, unknown>>;
1734
+ //#endregion
1735
+ //#region src/generators/cm15-maneuver-areas/airborneAttack.d.ts
1736
+ type AirborneAttackOptions = AttackOptions;
1737
+ declare const DEFAULT_AIRBORNE_ATTACK_OPTIONS: Required<AirborneAttackOptions>;
1738
+ /**
1739
+ * Generates a GeoJSON FeatureCollection for an Airborne Attack tactical symbol.
1740
+ *
1741
+ * The symbol is similar to Supporting Attack but features a crossover point
1742
+ * between the shaft and the head (Points 1 and 2/Neck).
1743
+ *
1744
+ * @param coordinates - An array of GeoJSON Positions.
1745
+ * @param options - Configuration options.
1746
+ * @returns A GeoJSON FeatureCollection<LineString>.
1747
+ */
1748
+ declare function createAirborneAttack(coordinates: Position[], options?: AirborneAttackOptions): FeatureCollection<LineString>;
1749
+ //#endregion
1750
+ //#region src/generators/cm15-maneuver-areas/attackHelicopter.d.ts
1751
+ interface AttackHelicopterOptions extends AttackOptions {
1752
+ symbolHeightRatio?: number;
1753
+ triangleSizeRatio?: number;
1754
+ bottomBarWidthRatio?: number;
1755
+ bowtieWidthRatio?: number;
1756
+ }
1757
+ declare const DEFAULT_ATTACK_HELICOPTER_OPTIONS: Required<AttackHelicopterOptions>;
1758
+ /**
1759
+ * Generates a GeoJSON FeatureCollection for an Attack Helicopter tactical symbol.
1760
+ *
1761
+ * The symbol is based on the Airborne Attack (bow tie) geometry but features
1762
+ * an additional symbol (vertical line + triangle) at the crossover point.
1763
+ *
1764
+ * @param coordinates - An array of GeoJSON Positions.
1765
+ * @param options - Configuration options.
1766
+ * @returns A GeoJSON FeatureCollection containing the main graphic and the symbol.
1767
+ */
1768
+ declare function createAttackHelicopter(coordinates: Position[], options?: AttackHelicopterOptions): FeatureCollection<LineString | Polygon>;
1769
+ //#endregion
1770
+ //#region src/generators/cm15-maneuver-areas/supportByFire.d.ts
1771
+ interface SupportByFireOptions {
1772
+ arrowheadWidthRatio?: number;
1773
+ rearLineLengthRatio?: number;
1774
+ rearLineAngle?: number;
1775
+ }
1776
+ declare const DEFAULT_SUPPORT_BY_FIRE_OPTIONS: Required<SupportByFireOptions>;
1777
+ /**
1778
+ * Generates a GeoJSON FeatureCollection for a Support By Fire tactical graphic.
1779
+ *
1780
+ * Input:
1781
+ * - PT1: Left Base
1782
+ * - PT2: Right Base
1783
+ * - PT3: Left Tip
1784
+ * - PT4: Right Tip
1785
+ */
1786
+ declare function createSupportByFire(coordinates: Position[], options?: SupportByFireOptions): FeatureCollection<LineString>;
1787
+ //#endregion
1788
+ //#region src/generators/cm15-maneuver-areas/attackByFire.d.ts
1789
+ interface AttackByFireOptions {
1790
+ arrowheadWidthRatio?: number;
1791
+ rearLineLengthRatio?: number;
1792
+ rearLineAngle?: number;
1793
+ }
1794
+ declare const DEFAULT_ATTACK_BY_FIRE_OPTIONS: Required<AttackByFireOptions>;
1795
+ /**
1796
+ * Generates a GeoJSON FeatureCollection for an Attack By Fire tactical graphic.
1797
+ *
1798
+ * Input:
1799
+ * - PT1: Arrow Tip (Target)
1800
+ * - PT2: Left Base
1801
+ * - PT3: Right Base
1802
+ *
1803
+ * Logic:
1804
+ * - Shaft: Midpoint(PT2, PT3) -> PT1
1805
+ * - Base Line: PT2 -> PT3
1806
+ * - Wings: Splayed out from PT2 and PT3
1807
+ */
1808
+ declare function createAttackByFire(coordinates: Position[], options?: AttackByFireOptions): FeatureCollection<LineString>;
1809
+ //#endregion
1810
+ //#region src/generators/cm14-maneuver-lines/flot.d.ts
1811
+ /**
1812
+ * Configuration options for the FLOT (Forward Line of Own Troops) geometry.
1813
+ */
1814
+ interface FLOTOptions extends SmoothLineOptions, LineLabelOptions {
1815
+ /**
1816
+ * The radius of the semicircular arcs in meters.
1817
+ * Semicircles are placed tangent to each other (diameter = 2 * radius).
1818
+ * This is ignored if radiusPixels is provided along with metersPerPixel.
1819
+ * @default 50
1820
+ */
1821
+ radius?: number;
1822
+ /**
1823
+ * The radius of the semi-circular arcs in pixels.
1824
+ * When provided along with metersPerPixel, the actual meter radius is calculated
1825
+ * dynamically to maintain consistent visual size on screen.
1826
+ * Takes precedence over radius when metersPerPixel is also provided.
1827
+ * @default 10
1828
+ */
1829
+ radiusPixels?: number;
1830
+ /**
1831
+ * The meters-per-pixel ratio at the current zoom level and latitude.
1832
+ * Required when using radiusPixels for zoom-aware sizing.
1833
+ * Can be obtained from the map view's resolution or calculated using getMetersPerPixel().
1834
+ */
1835
+ metersPerPixel?: number;
1836
+ /**
1837
+ * The number of points used to render each individual semi-circle.
1838
+ * Higher values create smoother arcs.
1839
+ * @default 16
1840
+ */
1841
+ arcSegments?: number;
1842
+ }
1843
+ /**
1844
+ * Default options for the FLOT graphic.
1845
+ */
1846
+ declare const DEFAULT_FLOT_OPTIONS: Required<Omit<FLOTOptions, keyof LineLabelOptions>>;
1847
+ /**
1848
+ * Creates a FLOT (Forward Line of Own Troops) tactical graphic.
1849
+ *
1850
+ * Generates a scalloped/arc line representing the forward edge of friendly forces.
1851
+ * The line consists of semi-circular arcs that bulge perpendicular to the base path,
1852
+ * creating a distinctive visual pattern used in military tactical graphics.
1853
+ *
1854
+ * @param positions - Array of GeoJSON positions defining the base path
1855
+ * @param options - Configuration options for the graphic
1856
+ * @returns A GeoJSON FeatureCollection containing the scalloped LineString
1857
+ *
1858
+ * @example
1859
+ * ```typescript
1860
+ * const flot = createFLOT(
1861
+ * [[-122.4194, 37.7749], [-122.4100, 37.7800], [-122.4000, 37.7750]],
1862
+ * { radius: 100, arcSegments: 20 }
1863
+ * );
1864
+ * ```
1865
+ */
1866
+ declare function createFLOT(positions: Position[], options?: FLOTOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1867
+ //#endregion
1868
+ //#region src/generators/cm14-maneuver-lines/phase-line.d.ts
1869
+ /** Configuration options for the Phase line control measure. */
1870
+ interface PhaseLineOptions extends LineLabelOptions, SmoothLineOptions {
1871
+ /**
1872
+ * Prefix the end labels with "PL" (`"PL ECHO"`, or a bare `"PL"` when no
1873
+ * designation is set). When `false`, the label is the bare designation
1874
+ * (`Field T`) alone, and the line carries no label at all when `T` is empty.
1875
+ * @default true
1876
+ */
1877
+ includePrefix?: boolean;
1878
+ }
1879
+ /** Default options for the Phase line control measure. */
1880
+ declare const DEFAULT_PHASE_LINE_OPTIONS: PhaseLineOptions;
1881
+ /**
1882
+ * Creates a Phase line control measure: a polyline through `positions`
1883
+ * labeled at each end with `T` (optionally "PL"-prefixed).
1884
+ */
1885
+ declare function createPhaseLine(positions: Position[], options?: PhaseLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1886
+ //#endregion
1887
+ //#region src/generators/cm14-maneuver-lines/handover-line.d.ts
1888
+ /** Configuration options for the Handover line control measure. */
1889
+ interface HandoverLineOptions extends LineLabelOptions, SmoothLineOptions {
1890
+ /**
1891
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
1892
+ * the line, additive to the fixed "HOL" labels. Empty or whitespace-only
1893
+ * renders no label.
1894
+ * @default none
1895
+ */
1896
+ phaseLineName?: string;
1897
+ /**
1898
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
1899
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
1900
+ * Phase Line itself, this measure already carries its own fixed "HOL"
1901
+ * label, so there is no bare "PL" fallback.
1902
+ * @default true
1903
+ */
1904
+ includePrefix?: boolean;
1905
+ }
1906
+ /** Default options for the Handover line control measure. */
1907
+ declare const DEFAULT_HANDOVER_LINE_OPTIONS: HandoverLineOptions;
1908
+ /**
1909
+ * Creates a Handover line control measure: a polyline through `positions`
1910
+ * labeled "HOL" above the line near each end.
1911
+ */
1912
+ declare function createHandoverLine(positions: Position[], options?: HandoverLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1913
+ //#endregion
1914
+ //#region src/generators/cm14-maneuver-lines/battle-handover-line.d.ts
1915
+ /** Configuration options for the Battle handover line control measure. */
1916
+ interface BattleHandoverLineOptions extends LineLabelOptions, SmoothLineOptions {
1917
+ /**
1918
+ * Optional phase line naming: renders `PL <name>` just beyond each end of
1919
+ * the line, additive to the fixed "BHL" labels. Empty or whitespace-only
1920
+ * renders no label.
1921
+ * @default none
1922
+ */
1923
+ phaseLineName?: string;
1924
+ /**
1925
+ * Prefix the `phaseLineName` label with "PL" (`"PL DAVID"`, or a bare
1926
+ * "DAVID" when `false`). No effect when `phaseLineName` is empty — unlike
1927
+ * Phase Line itself, this measure already carries its own fixed "BHL"
1928
+ * label, so there is no bare "PL" fallback.
1929
+ * @default true
1930
+ */
1931
+ includePrefix?: boolean;
1932
+ }
1933
+ /** Default options for the Battle handover line control measure. */
1934
+ declare const DEFAULT_BATTLE_HANDOVER_LINE_OPTIONS: BattleHandoverLineOptions;
1935
+ /**
1936
+ * Creates a Battle handover line control measure: a polyline through
1937
+ * `positions` labeled "BHL" above the line near each end.
1938
+ */
1939
+ declare function createBattleHandoverLine(positions: Position[], options?: BattleHandoverLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
1940
+ //#endregion
1941
+ //#region src/generators/cm34-mission-tasks/block.d.ts
1942
+ interface BlockMissionTaskOptions {
1943
+ /** Gap for the 'B' label as a ratio of the front length (default: 0.2) */
1944
+ labelGapRatio?: number;
1945
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
1946
+ labelSize?: number;
1947
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1948
+ labelSizePixels?: number;
1949
+ }
1950
+ declare const DEFAULT_BLOCK_MISSION_TASK_OPTIONS: Required<Omit<BlockMissionTaskOptions, "labelSize" | "labelSizePixels">>;
1951
+ /**
1952
+ * Generates a GeoJSON FeatureCollection for a BLOCK mission task symbol (340100).
1953
+ *
1954
+ * Uses the same T-shape geometry as the protection-area Block symbol, with a
1955
+ * "B" label centered on the shaft.
1956
+ *
1957
+ * @param coordinates - [PT. 1, PT. 2, optional PT. 3] as Position arrays
1958
+ * @param options - Configuration options
1959
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
1960
+ */
1961
+ declare function createBlockMissionTaskSymbol(coordinates: Position[], options?: BlockMissionTaskOptions): FeatureCollection<MultiLineString | Point>;
1962
+ //#endregion
1963
+ //#region src/generators/cm34-mission-tasks/breach.d.ts
1964
+ /**
1965
+ * Configuration options for the BREACH tactical symbol.
1966
+ */
1967
+ interface BreachOptions {
1968
+ /** Tick mark length ratio relative to front opening (default: 0.15) */
1969
+ tickLengthRatio?: number;
1970
+ /** Tick mark angle in degrees from perpendicular (default: 45) */
1971
+ tickAngle?: number;
1972
+ /** Gap for the 'B' label as a ratio of the front length (default: 0.2) */
1973
+ labelGapRatio?: number;
1974
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
1975
+ labelSize?: number;
1976
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
1977
+ labelSizePixels?: number;
1978
+ }
1979
+ /**
1980
+ * Default options for the BREACH symbol.
1981
+ */
1982
+ declare const DEFAULT_BREACH_OPTIONS: Required<Omit<BreachOptions, "labelSize" | "labelSizePixels">>;
1983
+ /**
1984
+ * Generates a GeoJSON FeatureCollection for a BREACH mission task symbol (340200).
1985
+ *
1986
+ * A three-sided bracket (see {@link createBracketSymbol}) whose front opening
1987
+ * endpoints terminate in tick marks pointing **outward** (away from the rear
1988
+ * "B" line).
1989
+ *
1990
+ * @param coordinates - [PT. 1, PT. 2, PT. 3] as Position arrays
1991
+ * @param options - Configuration options
1992
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
1993
+ */
1994
+ declare function createBreachSymbol(coordinates: Position[], options?: BreachOptions): FeatureCollection<MultiLineString | Point>;
1995
+ //#endregion
1996
+ //#region src/generators/cm34-mission-tasks/bypass.d.ts
1997
+ /**
1998
+ * Configuration options for the BYPASS tactical symbol.
1999
+ */
2000
+ interface BypassOptions {
2001
+ /** Arrowhead length ratio relative to front opening (default: 0.2) */
2002
+ arrowheadLengthRatio?: number;
2003
+ /** Gap for the 'B' label as a ratio of the front length (default: 0.2) */
2004
+ labelGapRatio?: number;
2005
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2006
+ labelSize?: number;
2007
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
2008
+ labelSizePixels?: number;
2009
+ }
2010
+ /**
2011
+ * Default options for the BYPASS symbol.
2012
+ */
2013
+ declare const DEFAULT_BYPASS_OPTIONS: Required<Omit<BypassOptions, "labelSize" | "labelSizePixels">>;
2014
+ /**
2015
+ * Generates a GeoJSON FeatureCollection for a BYPASS mission task symbol (340300).
2016
+ *
2017
+ * A three-sided bracket (see {@link createBracketSymbol}) with a "B" label on
2018
+ * the rear line, whose front opening endpoints terminate in outward-flaring
2019
+ * chevron arrowheads instead of tick marks.
2020
+ *
2021
+ * @param coordinates - [PT. 1, PT. 2, PT. 3] as Position arrays
2022
+ * @param options - Configuration options
2023
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
2024
+ */
2025
+ declare function createBypassSymbol(coordinates: Position[], options?: BypassOptions): FeatureCollection<MultiLineString | Point>;
2026
+ //#endregion
2027
+ //#region src/generators/cm34-mission-tasks/canalize.d.ts
2028
+ /**
2029
+ * Configuration options for the CANALIZE tactical symbol.
2030
+ */
2031
+ interface CanalizeOptions {
2032
+ /** Tick mark length ratio relative to front opening (default: 0.15) */
2033
+ tickLengthRatio?: number;
2034
+ /** Tick mark angle in degrees from perpendicular (default: 45) */
2035
+ tickAngle?: number;
2036
+ /** Gap for the 'C' label as a ratio of the front length (default: 0.2) */
2037
+ labelGapRatio?: number;
2038
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2039
+ labelSize?: number;
2040
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
2041
+ labelSizePixels?: number;
2042
+ }
2043
+ /**
2044
+ * Default options for the CANALIZE symbol.
2045
+ */
2046
+ declare const DEFAULT_CANALIZE_OPTIONS: Required<Omit<CanalizeOptions, "labelSize" | "labelSizePixels">>;
2047
+ /**
2048
+ * Generates a GeoJSON FeatureCollection for a CANALIZE mission task symbol (340400).
2049
+ *
2050
+ * A three-sided bracket (see {@link createBracketSymbol}) whose front opening
2051
+ * endpoints terminate in tick marks pointing **inward** (toward the rear "C"
2052
+ * line), opposite BREACH's outward-facing ticks.
2053
+ *
2054
+ * @param coordinates - [PT. 1, PT. 2, PT. 3] as Position arrays
2055
+ * @param options - Configuration options
2056
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
2057
+ */
2058
+ declare function createCanalizeSymbol(coordinates: Position[], options?: CanalizeOptions): FeatureCollection<MultiLineString | Point>;
2059
+ //#endregion
2060
+ //#region src/generators/cm34-mission-tasks/clear.d.ts
2061
+ /**
2062
+ * Configuration options for the CLEAR tactical mission task symbol.
2063
+ */
2064
+ interface ClearOptions {
2065
+ /**
2066
+ * Padding between the vertical line's endpoints and the outer arrows, as a
2067
+ * ratio of the symbol height. Insets the top and bottom arrows so they sit
2068
+ * clear of PT. 1 / PT. 2 (default: 0.15).
2069
+ */
2070
+ arrowInsetRatio?: number;
2071
+ /** Arrowhead depth (toward the rear) as a ratio of the symbol height (default: 0.15). */
2072
+ arrowheadLengthRatio?: number;
2073
+ /** Arrowhead width (along the vertical line) as a ratio of the symbol height (default: 0.2). */
2074
+ arrowheadWidthRatio?: number;
2075
+ /** Gap for the 'C' label as a ratio of the shaft length (default: 0.2). */
2076
+ labelGapRatio?: number;
2077
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2078
+ labelSize?: number;
2079
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
2080
+ labelSizePixels?: number;
2081
+ }
2082
+ /**
2083
+ * Default options for the CLEAR symbol.
2084
+ */
2085
+ declare const DEFAULT_CLEAR_OPTIONS: Required<Omit<ClearOptions, "labelSize" | "labelSizePixels">>;
2086
+ /**
2087
+ * Generates a GeoJSON FeatureCollection for a CLEAR mission task symbol (340500).
2088
+ *
2089
+ * A vertical line (PT. 1 → PT. 2) with three arrows pointing at it,
2090
+ * perpendicular to the line. The arrows come from the rear — the side PT. 3
2091
+ * sits on — and their tips touch the vertical line; each carries a shaft
2092
+ * reaching back to the rear. The arrows are evenly spaced along the line, so
2093
+ * the middle arrow's tip sits at the midpoint of the vertical line and its
2094
+ * shaft carries the 'C' glyph. The arrows stay perpendicular to the vertical
2095
+ * line at any rotation.
2096
+ *
2097
+ * Input Points:
2098
+ * - PT. 1: Top endpoint of the vertical line
2099
+ * - PT. 2: Bottom endpoint of the vertical line — defines height with PT. 1
2100
+ * - PT. 3: Rear point — defines the shaft length (and which side the arrows
2101
+ * come from)
2102
+ *
2103
+ * @param coordinates - [PT. 1, PT. 2, PT. 3] as Position arrays
2104
+ * @param options - Configuration options
2105
+ * @returns GeoJSON FeatureCollection containing MultiLineString and Point features
2106
+ */
2107
+ declare function createClearSymbol(coordinates: Position[], options?: ClearOptions): FeatureCollection<MultiLineString | Point>;
2108
+ //#endregion
2109
+ //#region src/generators/cm15-maneuver-areas/searchArea.d.ts
2110
+ /**
2111
+ * Configuration options to tweak the tactical arrow's geometry.
2112
+ */
2113
+ interface TacticalArrowOptions {
2114
+ /** Ratio of arrowhead length to total leg length (default: 0.12) */
2115
+ arrowheadLengthRatio?: number;
2116
+ /** Width multiplier for the arrowhead wings (default: 0.5) */
2117
+ arrowheadWidthRatio?: number;
2118
+ /** Percentage along the leg where the zigzag begins, 0.0-1.0 (default: 0.55) */
2119
+ zigzagStart?: number;
2120
+ /** Percentage along the leg where the zigzag returns, 0.0-1.0 (default: 0.45) */
2121
+ zigzagEnd?: number;
2122
+ /** Perpendicular offset for the lightning "kink", relative to leg length (default: 0.07) */
2123
+ zigzagAmplitudeRatio?: number;
2124
+ }
2125
+ /**
2126
+ * Default options for the tactical arrow.
2127
+ */
2128
+ declare const DEFAULT_TACTICAL_ARROW_OPTIONS: Required<TacticalArrowOptions>;
2129
+ //#endregion
2130
+ //#region src/generators/cm34-mission-tasks/security-task-shared.d.ts
2131
+ interface SecurityTaskOptions extends TacticalArrowOptions {
2132
+ /** Position of each task letter inward from PT. 2/PT. 3 as a ratio of the opening. */
2133
+ labelInsetRatio?: number;
2134
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2135
+ labelSize?: number;
2136
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
2137
+ labelSizePixels?: number;
2138
+ }
2139
+ //#endregion
2140
+ //#region src/generators/cm34-mission-tasks/cover.d.ts
2141
+ type CoverOptions = SecurityTaskOptions;
2142
+ declare const DEFAULT_COVER_OPTIONS: Required<Omit<SecurityTaskOptions, "labelSize" | "labelSizePixels">>;
2143
+ declare function createCoverSymbol(coordinates: Position[], options?: CoverOptions): FeatureCollection<MultiLineString | Point>;
2144
+ //#endregion
2145
+ //#region src/generators/cm34-mission-tasks/delay.d.ts
2146
+ interface DelayOptions {
2147
+ /** Arrowhead depth as a ratio of the straight-line length (default: 0.12). */
2148
+ arrowheadLengthRatio?: number;
2149
+ /** Arrowhead width as a ratio of the straight-line length (default: 0.12). */
2150
+ arrowheadWidthRatio?: number;
2151
+ /** Gap for the 'D' label as a ratio of the straight-line length (default: 0.18). */
2152
+ labelGapRatio?: number;
2153
+ /** Number of segments used to approximate the 180-degree arc (default: 32). */
2154
+ arcSegments?: number;
2155
+ /** Text height in projected meters — ground-anchored label size (ADR-0028). */
2156
+ labelSize?: number;
2157
+ /** Text height in CSS pixels — screen-anchored label size (ADR-0028). */
2158
+ labelSizePixels?: number;
2159
+ }
2160
+ declare const DEFAULT_DELAY_OPTIONS: Required<Omit<DelayOptions, "labelSize" | "labelSizePixels">>;
2161
+ declare function createDelaySymbol(coordinates: Position[], options?: DelayOptions): FeatureCollection<MultiLineString | Point>;
2162
+ //#endregion
2163
+ //#region src/generators/cm34-mission-tasks/guard.d.ts
2164
+ type GuardOptions = SecurityTaskOptions;
2165
+ declare const DEFAULT_GUARD_OPTIONS: Required<Omit<SecurityTaskOptions, "labelSize" | "labelSizePixels">>;
2166
+ declare function createGuardSymbol(coordinates: Position[], options?: GuardOptions): FeatureCollection<MultiLineString | Point>;
2167
+ //#endregion
2168
+ //#region src/generators/cm34-mission-tasks/isolate.d.ts
2169
+ /**
2170
+ * Configuration options for the ISOLATE tactical mission task symbol.
2171
+ */
2172
+ interface IsolateOptions {
2173
+ /** Angular size of the opening on the friendly side, in degrees (default: 30). */
2174
+ openingAngle?: number;
2175
+ /** Number of inward-pointing arrowhead barbs spaced around the closed arc (default: 9). */
2176
+ barbCount?: number;
2177
+ /** Barb length as a ratio of the symbol radius (default: 0.18). */
2178
+ barbLengthRatio?: number;
2179
+ }
2180
+ /**
2181
+ * Generates a GeoJSON FeatureCollection for an ISOLATE mission task symbol (341500).
2182
+ *
2183
+ * A near-complete circle centered on PT. 1 whose radius reaches PT. 2. The arc
2184
+ * starts (bare) at PT. 2's bearing and sweeps clockwise around the closed
2185
+ * portion to a single arrow tip at the far end; the wedge-shaped gap (default
2186
+ * 30°) between that arrow tip and PT. 2 is the opening — the "friendly side".
2187
+ * Inward-pointing arrowhead barbs are spaced along the closed arc, set in from
2188
+ * both ends so they never touch PT. 2 or the arrow tip, conveying the
2189
+ * sealing-off of the enclosed force. Unlike the bracket mission tasks, isolate
2190
+ * carries no glyph label.
2191
+ *
2192
+ * Input Points:
2193
+ * - PT. 1: Center point
2194
+ * - PT. 2: Start point — fixes the radius and the bearing of the opening
2195
+ *
2196
+ * @param coordinates - [PT. 1, PT. 2] as Position arrays
2197
+ * @param options - Configuration options
2198
+ * @returns GeoJSON FeatureCollection containing a single MultiLineString feature
2199
+ */
2200
+ declare function createIsolateSymbol(coordinates: Position[], options?: IsolateOptions): FeatureCollection<MultiLineString>;
2201
+ //#endregion
2202
+ //#region src/generators/cm34-mission-tasks/screen.d.ts
2203
+ type ScreenOptions = SecurityTaskOptions;
2204
+ declare const DEFAULT_SCREEN_OPTIONS: Required<Omit<SecurityTaskOptions, "labelSize" | "labelSizePixels">>;
2205
+ declare function createScreenSymbol(coordinates: Position[], options?: ScreenOptions): FeatureCollection<MultiLineString | Point>;
2206
+ //#endregion
2207
+ //#region src/generators/cm29-protection-lines/antitankDitch.d.ts
2208
+ interface AntitankDitchOptions extends SmoothLineOptions, LineLabelOptions {
2209
+ /**
2210
+ * The tooth depth in meters. Target tooth spacing is roughly 1.15x this depth.
2211
+ * Ignored when toothHeightPixels is provided with metersPerPixel.
2212
+ * @default 50
2213
+ */
2214
+ toothHeight?: number;
2215
+ /**
2216
+ * The tooth depth in pixels. When provided with metersPerPixel, the meter
2217
+ * size is calculated dynamically to maintain a consistent visual size.
2218
+ * @default 10
2219
+ */
2220
+ toothHeightPixels?: number;
2221
+ /**
2222
+ * The target base span of each triangular tooth as a multiple of tooth depth.
2223
+ * Lower values make sharper, denser teeth; higher values make flatter teeth.
2224
+ * @default 1.15
2225
+ */
2226
+ toothWidthRatio?: number;
2227
+ /**
2228
+ * The meters-per-pixel ratio at the current zoom level and latitude. Required
2229
+ * when using toothHeightPixels for zoom-aware sizing.
2230
+ */
2231
+ metersPerPixel?: number;
2232
+ }
2233
+ declare const DEFAULT_ANTITANK_DITCH_OPTIONS: Required<Omit<AntitankDitchOptions, keyof LineLabelOptions>>;
2234
+ declare function createAntitankDitchUnderConstruction(positions: Position[], options?: AntitankDitchOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2235
+ declare function createAntitankDitchCompleted(positions: Position[], options?: AntitankDitchOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiPolygon | Point>;
2236
+ //#endregion
2237
+ //#region src/generators/cm29-protection-lines/antitankWall.d.ts
2238
+ interface AntitankWallOptions extends AntitankDitchOptions {
2239
+ /**
2240
+ * The total gap between consecutive tooth bases as a multiple of tooth base
2241
+ * width. Use 0 for touching teeth; higher values create wider gaps.
2242
+ * @default 1.35
2243
+ */
2244
+ toothSpacingRatio?: number;
2245
+ }
2246
+ declare const DEFAULT_ANTITANK_WALL_OPTIONS: Required<Omit<AntitankWallOptions, keyof LineLabelOptions>>;
2247
+ declare function createAntitankWall(positions: Position[], options?: AntitankWallOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2248
+ //#endregion
2249
+ //#region src/generators/cm29-protection-lines/fortifiedLine.d.ts
2250
+ /**
2251
+ * Configuration options for the Fortified Line geometry.
2252
+ */
2253
+ interface FortifiedLineOptions extends LineLabelOptions {
2254
+ /**
2255
+ * The size of the square teeth in meters.
2256
+ * This controls both the width and height of the castellated pattern.
2257
+ * This is ignored if toothSizePixels is provided along with metersPerPixel.
2258
+ * @default 50
2259
+ */
2260
+ toothSize?: number;
2261
+ /**
2262
+ * The size of the square teeth in pixels.
2263
+ * When provided along with metersPerPixel, the actual meter size is calculated
2264
+ * dynamically to maintain consistent visual size on screen.
2265
+ * Takes precedence over toothSize when metersPerPixel is also provided.
2266
+ * @default 10
2267
+ */
2268
+ toothSizePixels?: number;
2269
+ /**
2270
+ * The meters-per-pixel ratio at the current zoom level and latitude.
2271
+ * Required when using toothSizePixels for zoom-aware sizing.
2272
+ */
2273
+ metersPerPixel?: number;
2274
+ /**
2275
+ * Round the line's corners by curving the base path through the control
2276
+ * points (centripetal Catmull-Rom spline) before generating the castellated
2277
+ * teeth, matching the rounded shape option on the Fortified Area and Battle
2278
+ * Position measures. With fewer than three control points the path is left
2279
+ * unchanged (a single segment cannot be smoothed).
2280
+ * @default false
2281
+ */
2282
+ smooth?: boolean;
2283
+ /**
2284
+ * Number of samples per segment when `smooth` is enabled. Higher values yield
2285
+ * a denser, smoother curve.
2286
+ * @default 16
2287
+ */
2288
+ smoothResolution?: number;
2289
+ }
2290
+ /**
2291
+ * Default options for the Fortified Line graphic.
2292
+ */
2293
+ declare const DEFAULT_FORTIFIED_LINE_OPTIONS: Required<Omit<FortifiedLineOptions, keyof LineLabelOptions>>;
2294
+ /**
2295
+ * Creates a Fortified Line tactical graphic.
2296
+ *
2297
+ * Generates a castellated/square-wave line representing a fortified line.
2298
+ * The line consists of square "teeth" that project perpendicular to the base path.
2299
+ *
2300
+ * @param positions - Array of GeoJSON positions defining the base path
2301
+ * @param options - Configuration options for the graphic
2302
+ * @returns A GeoJSON FeatureCollection containing the castellated LineString
2303
+ */
2304
+ declare function createFortifiedLine(positions: Position[], options?: FortifiedLineOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<LineString | Point>;
2305
+ //#endregion
2306
+ //#region src/generators/cm15-maneuver-areas/fortifiedArea.d.ts
2307
+ /**
2308
+ * Configuration options for the Fortified Area. Inherits the Fortified Line
2309
+ * options (including `smooth`/`smoothResolution`) unchanged; the area applies
2310
+ * the smoothing as a closed Catmull-Rom ring rather than an open spline. Also
2311
+ * carries the shared {@link AreaLabelOptions} label placement (a plain
2312
+ * intersection, not a re-derivation, so the aliased
2313
+ * {@link DEFAULT_FORTIFIED_AREA_OPTIONS} default still typechecks unchanged —
2314
+ * `AreaLabelOptions`'s fields are all optional).
2315
+ */
2316
+ type FortifiedAreaOptions = FortifiedLineOptions & AreaLabelOptions;
2317
+ declare const DEFAULT_FORTIFIED_AREA_OPTIONS: FortifiedAreaOptions;
2318
+ /**
2319
+ * Creates a Fortified Area tactical graphic.
2320
+ *
2321
+ * Generates a polygon with a castellated/square-wave boundary representing a fortified area.
2322
+ * The boundary consists of square "teeth" that project perpendicular to the path.
2323
+ *
2324
+ * @param positions - Array of GeoJSON positions defining the area boundary.
2325
+ * The first and last positions should match to close the polygon,
2326
+ * or it will be closed automatically.
2327
+ * @param options - Configuration options for the graphic
2328
+ * @param textAmplifiers - Field T (bare, no prefix — "TANGO", not "FA TANGO")
2329
+ * plus Field H/W/W1, centered on the pre-teeth boundary ring (see
2330
+ * `boundaryInput` below), and an optional Field N "ENY" hostile marker on
2331
+ * that ring's west/east edges, masking the castellated boundary beneath it.
2332
+ * @param context - Persisted amplifier placements used to move or restore each
2333
+ * ENY cutout with its independently dragged label.
2334
+ * @returns A GeoJSON FeatureCollection containing the castellated boundary
2335
+ * (a Polygon normally, or a gapped MultiLineString with Field N) plus any
2336
+ * label Points
2337
+ */
2338
+ declare function createFortifiedArea(positions: Position[], options?: FortifiedAreaOptions, textAmplifiers?: CanonicalTextAmplifiers, context?: ControlMeasureGeneratorContext): FeatureCollection<Polygon | MultiLineString | Point>;
2339
+ //#endregion
2340
+ //#region src/generators/cm15-maneuver-areas/maneuver-arrow-task-shared.d.ts
2341
+ interface ManeuverArrowTaskOptions extends AttackOptions, LabelSizeOptions {
2342
+ /** Straight crossbar length as a multiple of the arrowhead base width. */
2343
+ crossbarLengthRatio?: number;
2344
+ /** Field T position along the shaft, from tail (0) to head (1). */
2345
+ labelPosition?: number;
2346
+ /** W/W1 position along the shaft, from tail (0) to head (1). */
2347
+ dtgPosition?: number;
2348
+ /** Extra W/W1 row spacing, in label heights. */
2349
+ labelPadding?: number;
2350
+ }
2351
+ //#endregion
2352
+ //#region src/generators/cm15-maneuver-areas/frontal-attack.d.ts
2353
+ type FrontalAttackOptions = ManeuverArrowTaskOptions;
2354
+ declare const DEFAULT_FRONTAL_ATTACK_OPTIONS: FrontalAttackOptions;
2355
+ declare function createFrontalAttack(coordinates: Position[], options?: FrontalAttackOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2356
+ //#endregion
2357
+ //#region src/generators/cm15-maneuver-areas/turning-movement.d.ts
2358
+ type TurningMovementOptions = ManeuverArrowTaskOptions;
2359
+ declare const DEFAULT_TURNING_MOVEMENT_OPTIONS: TurningMovementOptions;
2360
+ declare function createTurningMovement(coordinates: Position[], options?: TurningMovementOptions, textAmplifiers?: CanonicalTextAmplifiers): FeatureCollection<MultiLineString | Point>;
2361
+ //#endregion
2362
+ //#region src/generators/cm27-protection-areas/block.d.ts
2363
+ type BlockOptions = Record<never, never>;
2364
+ declare const DEFAULT_BLOCK_OPTIONS: BlockOptions;
2365
+ /**
2366
+ * Generates a GeoJSON FeatureCollection for a "Block" tactical symbol (T-shape).
2367
+ *
2368
+ * @param coordinates - An array of GeoJSON Positions (Lon/Lat).
2369
+ * Expects exactly 3 points:
2370
+ * - PT1 & PT2: Endpoints of the vertical line.
2371
+ * - PT3: Defines the endpoint of the horizontal line (stem).
2372
+ * @param options - Configuration options.
2373
+ * @returns A GeoJSON FeatureCollection containing a LineString.
2374
+ */
2375
+ declare function createBlock(coordinates: Position[], _options?: BlockOptions): FeatureCollection<LineString>;
2376
+ //#endregion
2377
+ //#region src/generators/cm27-protection-areas/disrupt.d.ts
2378
+ interface DisruptOptions {
2379
+ middleArrowLengthRatio?: number;
2380
+ bottomArrowLengthRatio?: number;
2381
+ shaftLengthRatio?: number;
2382
+ arrowheadLengthRatio?: number;
2383
+ arrowheadWidthRatio?: number;
2384
+ }
2385
+ declare const DEFAULT_DISRUPT_OPTIONS: Required<DisruptOptions>;
2386
+ /**
2387
+ * Generates a GeoJSON FeatureCollection for a DISRUPT tactical symbol.
2388
+ *
2389
+ * Input:
2390
+ * - PT1: Top endpoint of the vertical spine
2391
+ * - PT2: Bottom endpoint of the vertical spine
2392
+ * - PT3: Reference point used to determine the longest-arrow offset
2393
+ *
2394
+ * Geometry:
2395
+ * - Spine: PT1 -> PT2
2396
+ * - PT2 -> PT1 defines the baseline orientation; arrow direction is constrained to its perpendicular axis
2397
+ * - PT3 is decomposed and projected onto the perpendicular axis through PT1 to derive a valid longest-arrow tip
2398
+ * - Three arrows placed at PT1, midpoint(PT1, PT2), and PT2
2399
+ * - Center shaft extends opposite arrow direction from midpoint with the same length as the middle arrow
2400
+ * - Top arrow is longest
2401
+ * - Middle and bottom arrows are proportional to the longest arrow
2402
+ * - Arrow heads are returned as filled triangle polygons
2403
+ */
2404
+ declare function createDisrupt(coordinates: Position[], options?: DisruptOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2405
+ //#endregion
2406
+ //#region src/generators/cm27-protection-areas/fix.d.ts
2407
+ interface FixOptions {
2408
+ arrowheadAngle?: number;
2409
+ arrowheadLengthRatio?: number;
2410
+ endSegmentRatio?: number;
2411
+ }
2412
+ declare const DEFAULT_FIX_OPTIONS: Required<FixOptions>;
2413
+ /**
2414
+ * Generates a GeoJSON FeatureCollection for a FIX tactical symbol.
2415
+ *
2416
+ * Input:
2417
+ * - PT1: Arrow tip end
2418
+ * - PT2: Opposite end
2419
+ *
2420
+ * Notes:
2421
+ * - Requires exactly two points.
2422
+ * - Produces one MultiLineString feature containing the zigzag body and open arrowhead wings.
2423
+ */
2424
+ declare function createFix(coordinates: Position[], options?: FixOptions): FeatureCollection<MultiLineString>;
2425
+ //#endregion
2426
+ //#region src/generators/cm27-protection-areas/turn.d.ts
2427
+ interface TurnOptions {
2428
+ arrowheadLengthRatio?: number;
2429
+ arrowheadWidthRatio?: number;
2430
+ arcSegments?: number;
2431
+ }
2432
+ declare const DEFAULT_TURN_OPTIONS: Required<TurnOptions>;
2433
+ /**
2434
+ * Generates a quarter-circle shaft from PT2 (rear) to the arrowhead base.
2435
+ * The arrowhead continues tangent to the arc and places its tip at PT1.
2436
+ * PT3 selects which side of the PT2 -> PT1 chord contains the arc.
2437
+ */
2438
+ declare function createTurn(coordinates: Position[], options?: TurnOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2439
+ //#endregion
2440
+ //#region src/generators/cm27-protection-areas/obstacleBypassEasy.d.ts
2441
+ interface ObstacleBypassEasyOptions {
2442
+ arrowheadLengthRatio?: number;
2443
+ arrowheadWidthRatio?: number;
2444
+ defaultLengthRatio?: number;
2445
+ }
2446
+ declare const DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS: Required<ObstacleBypassEasyOptions>;
2447
+ /**
2448
+ * Generates a GeoJSON FeatureCollection for an "Obstacle Bypass Easy" symbol.
2449
+ *
2450
+ * Input:
2451
+ * - PT1 and PT2 define the tips of the two arrowheads (opening and symbol height)
2452
+ * - PT3 defines signed symbol length along the perpendicular axis through midpoint(PT1, PT2)
2453
+ *
2454
+ * Geometry:
2455
+ * - Rear line is parallel to opening(PT1-PT2) and has equal length
2456
+ * - Two side rails run from rear endpoints to the arrowheads and are parallel to each other
2457
+ * - Rear line is perpendicular to both side rails
2458
+ * - Arrow heads are filled triangle polygons at PT1 and PT2
2459
+ */
2460
+ declare function createObstacleBypassEasy(coordinates: Position[], options?: ObstacleBypassEasyOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2461
+ //#endregion
2462
+ //#region src/generators/cm27-protection-areas/obstacleBypassDifficult.d.ts
2463
+ interface ObstacleBypassDifficultOptions {
2464
+ arrowheadLengthRatio?: number;
2465
+ arrowheadWidthRatio?: number;
2466
+ defaultLengthRatio?: number;
2467
+ zigzagAmplitudeRatio?: number;
2468
+ zigzagSpacingRatio?: number;
2469
+ }
2470
+ declare const DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS: Required<ObstacleBypassDifficultOptions>;
2471
+ declare function createObstacleBypassDifficult(coordinates: Position[], options?: ObstacleBypassDifficultOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2472
+ //#endregion
2473
+ //#region src/generators/cm27-protection-areas/obstacleBypassImpossible.d.ts
2474
+ interface ObstacleBypassImpossibleOptions {
2475
+ arrowheadLengthRatio?: number;
2476
+ arrowheadWidthRatio?: number;
2477
+ defaultLengthRatio?: number;
2478
+ rearBarLengthRatio?: number;
2479
+ rearGapRatio?: number;
2480
+ }
2481
+ declare const DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS: Required<ObstacleBypassImpossibleOptions>;
2482
+ /**
2483
+ * Generates a GeoJSON FeatureCollection for an "Obstacle Bypass Impossible" symbol.
2484
+ *
2485
+ * Input:
2486
+ * - PT1 and PT2 define the tips of the two arrowheads (opening and symbol height)
2487
+ * - PT3 defines signed symbol length along the perpendicular axis through midpoint(PT1, PT2)
2488
+ *
2489
+ * Geometry:
2490
+ * - Same base as obstacle bypass easy
2491
+ * - Rear line has two short perpendicular bars on the rear side
2492
+ */
2493
+ declare function createObstacleBypassImpossible(coordinates: Position[], options?: ObstacleBypassImpossibleOptions): FeatureCollection<MultiLineString | MultiPolygon>;
2494
+ //#endregion
2495
+ //#region src/registry.d.ts
2496
+ /**
2497
+ * The single source of truth for the catalog: one **control measure
2498
+ * definition** record per measure, co-located with its generator and collected
2499
+ * here. The `ControlMeasureId` union, `OptionsByKind`, the generator dispatch,
2500
+ * the default options, and rule resolution are all *derived* from this map
2501
+ * rather than maintained as parallel tables. Adding a measure is a one-file
2502
+ * change plus one line here. See ADR-0013.
2503
+ */
2504
+ declare const DEFINITIONS: {
2505
+ boundary: ControlMeasureDefinition<"boundary", typeof createBoundary>;
2506
+ "light-line": ControlMeasureDefinition<"light-line", typeof createLightLine>;
2507
+ "engineer-work-line": ControlMeasureDefinition<"engineer-work-line", typeof createEngineerWorkLine>;
2508
+ "generic-c2-line": ControlMeasureDefinition<"generic-c2-line", typeof createGenericC2Line>;
2509
+ "battle-position": ControlMeasureDefinition<"battle-position", typeof createBattlePosition>;
2510
+ "strong-point": ControlMeasureDefinition<"strong-point", typeof createStrongPoint>;
2511
+ ambush: ControlMeasureDefinition<"ambush", (controlPoints: import("geojson").Position[], options?: AmbushOptions) => import("geojson").FeatureCollection<import("geojson").MultiLineString, Record<string, never>>>;
2512
+ "direction-of-attack-aviation": ControlMeasureDefinition<"direction-of-attack-aviation", typeof createDirectionOfAttackAviation>;
2513
+ "direction-of-main-attack": ControlMeasureDefinition<"direction-of-main-attack", typeof createDirectionOfMainAttack>;
2514
+ "direction-of-supporting-attack": ControlMeasureDefinition<"direction-of-supporting-attack", typeof createDirectionOfSupportingAttack>;
2515
+ "principal-direction-of-fire": ControlMeasureDefinition<"principal-direction-of-fire", typeof createPrincipalDirectionOfFire>;
2516
+ "final-protective-fire-left": ControlMeasureDefinition<"final-protective-fire-left", typeof createFinalProtectiveFireLeft>;
2517
+ "final-protective-fire-right": ControlMeasureDefinition<"final-protective-fire-right", typeof createFinalProtectiveFireRight>;
2518
+ "search-area": ControlMeasureDefinition<"search-area", (controlPoints: import("geojson").Position[], options?: TacticalArrowOptions) => import("geojson").FeatureCollection<import("geojson").MultiLineString | import("geojson").MultiPolygon, {
2519
+ part: "shaft" | "head";
2520
+ fill?: boolean;
2521
+ style?: StyleHints;
2522
+ }>>;
2523
+ encirclement: ControlMeasureDefinition<"encirclement", typeof createEncirclement>;
2524
+ area: ControlMeasureDefinition<"area", typeof createArea>;
2525
+ "area-defense": ControlMeasureDefinition<"area-defense", typeof createAreaDefense>;
2526
+ "assembly-area": ControlMeasureDefinition<"assembly-area", typeof createAssemblyArea>;
2527
+ "joint-tactical-action-area": ControlMeasureDefinition<"joint-tactical-action-area", typeof createJointTacticalActionArea>;
2528
+ "submarine-action-area": ControlMeasureDefinition<"submarine-action-area", typeof createSubmarineActionArea>;
2529
+ "submarine-generated-action-area": ControlMeasureDefinition<"submarine-generated-action-area", typeof createSubmarineGeneratedActionArea>;
2530
+ "drop-zone": ControlMeasureDefinition<"drop-zone", typeof createDropZone>;
2531
+ "extraction-zone": ControlMeasureDefinition<"extraction-zone", typeof createExtractionZone>;
2532
+ "landing-zone": ControlMeasureDefinition<"landing-zone", typeof createLandingZone>;
2533
+ "limited-access-area": ControlMeasureDefinition<"limited-access-area", typeof createLimitedAccessArea>;
2534
+ "no-fire-area-irregular": ControlMeasureDefinition<"no-fire-area-irregular", typeof createNoFireAreaIrregular>;
2535
+ "pickup-zone": ControlMeasureDefinition<"pickup-zone", typeof createPickupZone>;
2536
+ "assault-position": ControlMeasureDefinition<"assault-position", typeof createAssaultPosition>;
2537
+ "attack-position": ControlMeasureDefinition<"attack-position", typeof createAttackPosition>;
2538
+ "objective-area": ControlMeasureDefinition<"objective-area", typeof createObjectiveArea>;
2539
+ "area-of-operations": ControlMeasureDefinition<"area-of-operations", typeof createAreaOfOperations>;
2540
+ "named-area-of-interest": ControlMeasureDefinition<"named-area-of-interest", typeof createNamedAreaOfInterest>;
2541
+ "target-area-of-interest": ControlMeasureDefinition<"target-area-of-interest", typeof createTargetAreaOfInterest>;
2542
+ "airfield-zone": ControlMeasureDefinition<"airfield-zone", typeof createAirfieldZone>;
2543
+ "base-camp": ControlMeasureDefinition<"base-camp", typeof createBaseCamp>;
2544
+ "guerrilla-base": ControlMeasureDefinition<"guerrilla-base", typeof createGuerrillaBase>;
2545
+ "generic-c2-area": ControlMeasureDefinition<"generic-c2-area", typeof createGenericC2Area>;
2546
+ "main-attack": ControlMeasureDefinition<"main-attack", typeof createMainAttack>;
2547
+ "supporting-attack": ControlMeasureDefinition<"supporting-attack", typeof createSupportingAttack>;
2548
+ "classic-arrow": ControlMeasureDefinition<"classic-arrow", typeof createClassicArrow>;
2549
+ "block-arrow": ControlMeasureDefinition<"block-arrow", typeof createBlockArrow>;
2550
+ line: ControlMeasureDefinition<"line", typeof createGenericLine>;
2551
+ polygon: ControlMeasureDefinition<"polygon", typeof createGenericPolygon>;
2552
+ rectangle: ControlMeasureDefinition<"rectangle", typeof createGenericRectangle>;
2553
+ circle: ControlMeasureDefinition<"circle", typeof createGenericCircle>;
2554
+ text: ControlMeasureDefinition<"text", typeof createGenericText>;
2555
+ "airborne-attack": ControlMeasureDefinition<"airborne-attack", typeof createAirborneAttack>;
2556
+ "attack-helicopter": ControlMeasureDefinition<"attack-helicopter", typeof createAttackHelicopter>;
2557
+ "support-by-fire": ControlMeasureDefinition<"support-by-fire", typeof createSupportByFire>;
2558
+ "attack-by-fire": ControlMeasureDefinition<"attack-by-fire", typeof createAttackByFire>;
2559
+ flot: ControlMeasureDefinition<"flot", typeof createFLOT>;
2560
+ "phase-line": ControlMeasureDefinition<"phase-line", typeof createPhaseLine>;
2561
+ "handover-line": ControlMeasureDefinition<"handover-line", typeof createHandoverLine>;
2562
+ "battle-handover-line": ControlMeasureDefinition<"battle-handover-line", typeof createBattleHandoverLine>;
2563
+ "block-mission-task": ControlMeasureDefinition<"block-mission-task", typeof createBlockMissionTaskSymbol>;
2564
+ breach: ControlMeasureDefinition<"breach", typeof createBreachSymbol>;
2565
+ bypass: ControlMeasureDefinition<"bypass", typeof createBypassSymbol>;
2566
+ canalize: ControlMeasureDefinition<"canalize", typeof createCanalizeSymbol>;
2567
+ clear: ControlMeasureDefinition<"clear", typeof createClearSymbol>;
2568
+ cover: ControlMeasureDefinition<"cover", typeof createCoverSymbol>;
2569
+ delay: ControlMeasureDefinition<"delay", typeof createDelaySymbol>;
2570
+ guard: ControlMeasureDefinition<"guard", typeof createGuardSymbol>;
2571
+ isolate: ControlMeasureDefinition<"isolate", typeof createIsolateSymbol>;
2572
+ screen: ControlMeasureDefinition<"screen", typeof createScreenSymbol>;
2573
+ "antitank-ditch-under-construction": ControlMeasureDefinition<"antitank-ditch-under-construction", typeof createAntitankDitchUnderConstruction>;
2574
+ "antitank-ditch-completed": ControlMeasureDefinition<"antitank-ditch-completed", typeof createAntitankDitchCompleted>;
2575
+ "antitank-wall": ControlMeasureDefinition<"antitank-wall", typeof createAntitankWall>;
2576
+ "fortified-line": ControlMeasureDefinition<"fortified-line", typeof createFortifiedLine>;
2577
+ "fortified-area": ControlMeasureDefinition<"fortified-area", typeof createFortifiedArea>;
2578
+ "frontal-attack": ControlMeasureDefinition<"frontal-attack", typeof createFrontalAttack>;
2579
+ "turning-movement": ControlMeasureDefinition<"turning-movement", typeof createTurningMovement>;
2580
+ block: ControlMeasureDefinition<"block", typeof createBlock>;
2581
+ disrupt: ControlMeasureDefinition<"disrupt", typeof createDisrupt>;
2582
+ fix: ControlMeasureDefinition<"fix", typeof createFix>;
2583
+ turn: ControlMeasureDefinition<"turn", typeof createTurn>;
2584
+ "obstacle-bypass-easy": ControlMeasureDefinition<"obstacle-bypass-easy", typeof createObstacleBypassEasy>;
2585
+ "obstacle-bypass-difficult": ControlMeasureDefinition<"obstacle-bypass-difficult", typeof createObstacleBypassDifficult>;
2586
+ "obstacle-bypass-impossible": ControlMeasureDefinition<"obstacle-bypass-impossible", typeof createObstacleBypassImpossible>;
2587
+ };
2588
+ type Definitions = typeof DEFINITIONS;
2589
+ /** Stable string id of a control measure — the keys of {@link DEFINITIONS}. */
2590
+ type ControlMeasureId = keyof Definitions;
2591
+ /**
2592
+ * The discriminant for {@link ControlMeasure}. Identical to
2593
+ * {@link ControlMeasureId}; kept as a distinct name for the `<K extends
2594
+ * ControlMeasureKind>` generics threaded through rendering and edit sessions.
2595
+ */
2596
+ type ControlMeasureKind = ControlMeasureId;
2597
+ /** Strips the internal `validationMode` knob from a public options surface. */
2598
+ type PublicOptions<T> = Omit<T, "validationMode">;
2599
+ /**
2600
+ * The per-kind public options map, derived covariantly from each definition's
2601
+ * generator (see {@link OptsOf}). Empty-options kinds resolve to `{}` — exactly
2602
+ * as loose as the former hand-written table. See ADR-0013.
2603
+ */
2604
+ type OptionsByKind = { [K in keyof Definitions]: PublicOptions<OptsOf<Definitions[K]>> };
2605
+ /** Insertion-ordered list of every control-measure id. */
2606
+ declare const CONTROL_MEASURE_IDS: readonly ControlMeasureId[];
2607
+ declare const CONTROL_MEASURE_METADATA: Readonly<Record<ControlMeasureId, ControlMeasureMetadata>>;
2608
+ declare function listControlMeasureMetadata(): readonly ControlMeasureMetadata[];
2609
+ declare function getControlMeasureMetadata(id: ControlMeasureId): ControlMeasureMetadata;
2610
+ declare function getControlMeasureMetadataByValue(value: string): ControlMeasureMetadata | undefined;
2611
+ declare function getDefaultOptions<K extends ControlMeasureKind>(kind: K): OptionsByKind[K];
2612
+ //#endregion
2613
+ //#region src/instance.d.ts
2614
+ interface ControlMeasure<K extends ControlMeasureKind = ControlMeasureKind> {
2615
+ id: string;
2616
+ kind: K;
2617
+ controlPoints: Position[];
2618
+ options?: OptionsByKind[K];
2619
+ style?: ControlMeasureStyle;
2620
+ properties?: Record<string, unknown>;
2621
+ /** Free-text amplifier fields (MIL-STD-2525E Appendix L Table L-II); see `./text-amplifiers`. */
2622
+ textAmplifiers?: TextAmplifiers;
2623
+ /** Optional user-adjusted anchors for independently rendered text amplifiers. */
2624
+ amplifierPlacements?: AmplifierPlacements;
2625
+ schemaVersion?: 1;
2626
+ }
2627
+ declare function isKind<K extends ControlMeasureKind>(cm: ControlMeasure, kind: K): cm is ControlMeasure<K>;
2628
+ /**
2629
+ * Deep-clone a `ControlMeasure` so held references survive mutations to the
2630
+ * original (and vice versa). Used by the session façade to build the
2631
+ * `graphic` half of TacticalDraw's `GraphicSnapshot`. Nested values inside
2632
+ * `options`, `style`, `properties`, and `textAmplifiers` are cloned too —
2633
+ * `properties` is `Record<string, unknown>` and may carry arbitrary host
2634
+ * metadata, so a shallow copy would leak shared references.
2635
+ *
2636
+ * Backed by `structuredClone`: only structured-cloneable values are
2637
+ * supported (no functions, DOM nodes, class instances). Absent optional
2638
+ * fields stay absent on the clone.
2639
+ */
2640
+ declare function cloneControlMeasure<K extends ControlMeasureKind>(cm: ControlMeasure<K>): ControlMeasure<K>;
2641
+ //#endregion
2642
+ //#region src/renderControlMeasure.d.ts
2643
+ interface RenderOptions {
2644
+ validationMode?: ValidationMode;
2645
+ /**
2646
+ * Façade-level default style (third / lowest-priority layer). Merged
2647
+ * shallowly under `cm.style` and any per-feature generator hint. When
2648
+ * omitted, style resolution matches the prior two-layer behavior.
2649
+ */
2650
+ graphicsStyle?: ControlMeasureStyle;
2651
+ }
2652
+ /**
2653
+ * Pure render: `ControlMeasure` → `ControlMeasureRender` (a
2654
+ * `FeatureCollection` of `FeaturePartProps`-typed features). Per-feature
2655
+ * stable ids follow `${cm.id}:${part}:${index}`. Style is resolved from the
2656
+ * three layers (graphicsStyle, cm.style, generator hint) and stamped on
2657
+ * `properties.style` when non-empty.
2658
+ */
2659
+ declare function renderControlMeasure<K extends ControlMeasureKind>(cm: ControlMeasure<K>, opts?: RenderOptions): ControlMeasureRender;
2660
+ //#endregion
2661
+ //#region src/freeze-orientation.d.ts
2662
+ /**
2663
+ * Dispatches to a measure kind's `freezeOrientation` hook (see
2664
+ * {@link import("./define").ControlMeasureDefinition.freezeOrientation}),
2665
+ * pinning orientation-derived option defaults to their current concrete
2666
+ * values ahead of a rigid rotation of `controlPoints`. Returns `undefined`
2667
+ * when the kind declares no hook, or when the hook itself finds nothing to
2668
+ * freeze. Edit hosts call this when a rotate gesture starts (ADR-0023).
2669
+ */
2670
+ declare function freezeOrientationOptions<K extends ControlMeasureKind>(kind: K, controlPoints: Position[], options: OptionsByKind[K] | undefined): Partial<OptionsByKind[K]> | undefined;
2671
+ /**
2672
+ * Dispatches to a measure kind's `transformOptions` hook (see
2673
+ * {@link import("./define").ControlMeasureDefinition.transformOptions}), folding
2674
+ * a box transform gesture's `delta` (screen-space scale/rotation) into option
2675
+ * values for a graphic that persists orientation/size as options rather than in
2676
+ * geometry. Returns an options patch to merge, or `undefined` when the kind
2677
+ * declares no hook (or the hook finds nothing to fold). Edit hosts call this at
2678
+ * a rotate/scale gesture's commit (ADR-0017).
2679
+ */
2680
+ declare function applyBoxTransformOptions<K extends ControlMeasureKind>(kind: K, options: OptionsByKind[K] | undefined, delta: BoxTransformDelta): Partial<OptionsByKind[K]> | undefined;
2681
+ //#endregion
2682
+ //#region src/styleResolver.d.ts
2683
+ /**
2684
+ * Three-layer style precedence for `renderControlMeasure`.
2685
+ *
2686
+ * Lower-priority → higher-priority: `graphicsStyle` (façade default) →
2687
+ * `measureStyle` (`cm.style`) → `generatorStyle` (per-feature hint emitted
2688
+ * by a generator). Merge is shallow and per-property; higher-priority layers
2689
+ * win key by key. Explicit `null` / `undefined` in a higher-priority layer
2690
+ * is treated as "no opinion" and does not clear a lower-priority key.
2691
+ *
2692
+ * Returns `undefined` when all three layers are absent so the renderer can
2693
+ * omit `properties.style` entirely — keeps the no-style case byte-identical
2694
+ * to a property-less feature.
2695
+ *
2696
+ * Pure function: inputs are never mutated; the returned object is always a
2697
+ * fresh allocation when defined.
2698
+ */
2699
+ declare function resolveStyleHints(graphicsStyle: ControlMeasureStyle | undefined, measureStyle: ControlMeasureStyle | undefined, generatorStyle: StyleHints | undefined): StyleHints | undefined;
2700
+ //#endregion
2701
+ //#region src/toSimpleStyle.d.ts
2702
+ /**
2703
+ * simplestyle-spec properties (the subset this library can express), flat on
2704
+ * `properties`. All keys are optional.
2705
+ *
2706
+ * @see https://github.com/mapbox/simplestyle-spec
2707
+ */
2708
+ interface SimpleStyleProps extends FeaturePartProps {
2709
+ stroke?: string;
2710
+ "stroke-width"?: number;
2711
+ "stroke-opacity"?: number;
2712
+ fill?: string;
2713
+ "fill-opacity"?: number;
2714
+ }
2715
+ /**
2716
+ * A `FeatureCollection` whose features carry simplestyle-spec keys instead of
2717
+ * the nested `properties.style` slot. The `FeaturePartProps` stable-id
2718
+ * contract (`part`, `index`, `feature.id`) is preserved.
2719
+ */
2720
+ type SimpleStyleRender = FeatureCollection<Geometry, SimpleStyleProps>;
2721
+ /**
2722
+ * Lossy interop transform: `ControlMeasureRender` → a `FeatureCollection`
2723
+ * whose features carry simplestyle-spec keys. Operates on the already-resolved
2724
+ * per-feature `style`, so it composes after `renderControlMeasure`'s
2725
+ * three-layer merge and stays a pure post-processing step.
2726
+ *
2727
+ * Lossy mapping, by design:
2728
+ * - `strokeDash` and `fillPattern` have no simplestyle equivalent and are
2729
+ * dropped — dashed sub-lines and patterned fills render solid in
2730
+ * simplestyle consumers.
2731
+ * - colors must be hex or `rgb()/rgba()`; alpha becomes `*-opacity`. Other
2732
+ * color forms (named, `hsl()`) are omitted rather than guessed.
2733
+ */
2734
+ declare function toSimpleStyle(render: ControlMeasureRender): SimpleStyleRender;
2735
+ //#endregion
2736
+ //#region src/internal/graphics-utils.d.ts
2737
+ /**
2738
+ * Small value used to avoid division by zero and floating-point precision issues.
2739
+ */
2740
+ declare const EPSILON = 0.000001;
2741
+ /**
2742
+ * Rounds a number to a specified number of decimal places.
2743
+ */
2744
+ declare const roundToFixed: (v: number, precision?: number) => number;
2745
+ /**
2746
+ * Calculates the meters-per-pixel ratio at a given latitude and zoom level.
2747
+ *
2748
+ * This is essential for maintaining consistent visual sizes on the map
2749
+ * regardless of zoom level. The formula accounts for:
2750
+ * - The Web Mercator projection's tile-based structure
2751
+ * - The latitude-dependent scale distortion in Mercator projection
2752
+ *
2753
+ * @param latitude - The latitude in degrees (affects scale due to projection)
2754
+ * @param zoomLevel - The current map zoom level
2755
+ * @returns The number of meters represented by one pixel at the given location and zoom
2756
+ *
2757
+ * @example
2758
+ * ```typescript
2759
+ * // At zoom 10, latitude 45°
2760
+ * const mpp = getMetersPerPixel(45, 10);
2761
+ * // To get a 20-pixel radius in meters:
2762
+ * const radiusMeters = 20 * mpp;
2763
+ * ```
2764
+ */
2765
+ declare const getMetersPerPixel: (latitude: number, zoomLevel: number) => number;
2766
+ //#endregion
2767
+ //#region src/draw-rules/baseline-frame.d.ts
2768
+ type BaselineFrameOrigin = "p1" | "p2" | "midpoint";
2769
+ type BaselineFrameNormal = "right" | "left";
2770
+ interface BaselineFrameOptions {
2771
+ origin?: BaselineFrameOrigin;
2772
+ normal?: BaselineFrameNormal;
2773
+ }
2774
+ interface BaselineFrame {
2775
+ readonly p1: Point2D;
2776
+ readonly p2: Point2D;
2777
+ readonly origin: Point2D;
2778
+ readonly direction: Point2D;
2779
+ readonly normal: Point2D;
2780
+ readonly length: number;
2781
+ signedNormalDistance(point: Position): number;
2782
+ pointAtNormalDistance(distance: number): Position | null;
2783
+ }
2784
+ declare function createBaselineFrame(p1: Position, p2: Position, options?: BaselineFrameOptions): BaselineFrame | null;
2785
+ //#endregion
2786
+ //#region src/draw-rules/midpoint-perpendicular.d.ts
2787
+ interface MidpointPerpendicularDrawRuleOptions {
2788
+ id: string;
2789
+ defaultDistanceRatio?: number;
2790
+ /** User clicks required to commit. Defaults to `2` (the third point is auto-derived). */
2791
+ minimumUserPoints?: number;
2792
+ /** Raw points at which a live preview can be derived. See {@link ControlMeasureDrawRule}. */
2793
+ minimumPreviewPoints?: number;
2794
+ /** Allow a repeated last point to commit the early derived preview. */
2795
+ finishOnLastPointRepeat?: boolean;
2796
+ /**
2797
+ * Index of the slot whose point is constrained to the perpendicular axis
2798
+ * through the configured origin of the other two ("baseline") slots. Must be
2799
+ * `0` or `2`. Defaults to `2`.
2800
+ *
2801
+ * Area11 (Block) and Point12 (obstacle-bypass) use `2`: P1/P2 are the free
2802
+ * baseline endpoints and P3 is constrained. Area7 (Attack-By-Fire) uses `0`:
2803
+ * P1 is the constrained arrowhead tip and P2/P3 are the free back-line
2804
+ * endpoints.
2805
+ */
2806
+ constrainedIndex?: 0 | 2;
2807
+ /** Frame origin for the perpendicular axis. Defaults to `"midpoint"`. */
2808
+ origin?: BaselineFrameOrigin;
2809
+ /** Side the positive normal points to. Defaults to `"right"`. */
2810
+ normal?: BaselineFrameNormal;
2811
+ }
2812
+ declare function createMidpointPerpendicularDrawRule(options: MidpointPerpendicularDrawRuleOptions): ControlMeasureDrawRule;
2813
+ declare function computeDefaultMidpointPerpendicularPoint(p1: Position, p2: Position, distanceRatio?: number): Position | null;
2814
+ declare function getMidpointPerpendicularSignedDistance(p1: Position, p2: Position, controlPoint: Position): number | null;
2815
+ declare function pointOnMidpointPerpendicularAxis(p1: Position, p2: Position, distance: number | null): Position | null;
2816
+ declare function snapToMidpointPerpendicular(p1: Position, p2: Position, controlPoint: Position): Position | null;
2817
+ //#endregion
2818
+ //#region src/draw-rules/area11.d.ts
2819
+ declare const blockDrawRule: ControlMeasureDrawRule;
2820
+ //#endregion
2821
+ //#region src/draw-rules/area12.d.ts
2822
+ /**
2823
+ * Area12 anchor draw rule for Disrupt.
2824
+ *
2825
+ * P1/P2 are the free spine endpoints. P3 is the longest-arrow tip, constrained
2826
+ * to the perpendicular axis through P1 (not the baseline midpoint).
2827
+ */
2828
+ declare const disruptDrawRule: ControlMeasureDrawRule;
2829
+ //#endregion
2830
+ //#region src/draw-rules/area15.d.ts
2831
+ declare const centerRadiusDrawRule: ControlMeasureDrawRule;
2832
+ //#endregion
2833
+ //#region src/draw-rules/point12.d.ts
2834
+ /**
2835
+ * Point12 anchor draw rule for the obstacle-bypass family.
2836
+ *
2837
+ * Shared by `obstacle-bypass-easy`, `obstacle-bypass-difficult`, and
2838
+ * `obstacle-bypass-impossible`: P1/P2 are the arrowhead tips and define the
2839
+ * opening; P3 is constrained to the perpendicular axis through
2840
+ * `midpoint(P1, P2)` and defines the rear of the symbol. Rear-line decoration
2841
+ * (plain, zigzag, barrier marks) is a generator concern, not a draw-rule one.
2842
+ */
2843
+ declare const point12DrawRule: ControlMeasureDrawRule;
2844
+ //#endregion
2845
+ //#region src/draw-rules/area7.d.ts
2846
+ /**
2847
+ * Area7 anchor draw rule for Attack By Fire.
2848
+ *
2849
+ * P2/P3 are the free back-line endpoints; P1 (slot index 0) is the arrowhead
2850
+ * tip, constrained to the perpendicular axis through `midpoint(P2, P3)`.
2851
+ */
2852
+ declare const attackByFireDrawRule: ControlMeasureDrawRule;
2853
+ //#endregion
2854
+ //#region src/draw-rules/line29.d.ts
2855
+ /**
2856
+ * Line29 anchor draw rule for Ambush.
2857
+ *
2858
+ * P2/P3 are the free back-line endpoints; P1 (slot index 0) is the arrowhead
2859
+ * tip, constrained to the perpendicular axis through `midpoint(P2, P3)`.
2860
+ */
2861
+ declare const ambushDrawRule: ControlMeasureDrawRule;
2862
+ //#endregion
2863
+ //#region src/draw-rules/line1.d.ts
2864
+ declare const line1DrawRule: ControlMeasureDrawRule;
2865
+ //#endregion
2866
+ //#region src/draw-rules/line10.d.ts
2867
+ /**
2868
+ * Line10 — PT1 is the arrow tip, PT2 is the rear, and derived PT3 selects
2869
+ * which side of the PT2 -> PT1 chord contains the 90-degree arc.
2870
+ */
2871
+ declare const turnDrawRule: ControlMeasureDrawRule;
2872
+ //#endregion
2873
+ //#region src/draw-rules/line23.d.ts
2874
+ /**
2875
+ * Line23 anchor draw rule for the Clear mission task.
2876
+ *
2877
+ * P1/P2 are the endpoints of the symbol's vertical line (its height); P3 is
2878
+ * constrained to the perpendicular axis through `midpoint(P1, P2)` and defines
2879
+ * the rear of the symbol (the shaft length). Geometrically identical to the
2880
+ * obstacle-bypass `Point12` rule, but kept as its own spec id to match the
2881
+ * doctrinal draw rule for Clear.
2882
+ */
2883
+ declare const line23DrawRule: ControlMeasureDrawRule;
2884
+ //#endregion
2885
+ //#region src/draw-rules/line24.d.ts
2886
+ /**
2887
+ * Line24 anchor draw rule for the Delay mission task.
2888
+ *
2889
+ * PT. 1 and PT. 2 are the free straight-line endpoints. PT. 3 is constrained to
2890
+ * the perpendicular axis through PT. 2, where its signed distance from PT. 2
2891
+ * defines the semicircular arc diameter and side. Unlike the sibling Line23
2892
+ * (Clear) rule, the third point must be placed explicitly (three user clicks),
2893
+ * with a two-point live preview before commit.
2894
+ */
2895
+ declare const line24DrawRule: ControlMeasureDrawRule;
2896
+ //#endregion
2897
+ //#region src/draw-rules/line26.d.ts
2898
+ /**
2899
+ * Line26 anchor draw rule for the Cover, Guard, and Screen security tasks.
2900
+ *
2901
+ * PT. 1/PT. 4 are the outward arrow tips and PT. 2/PT. 3 bound the opening
2902
+ * reserved for the supported tactical symbol. All four anchors are free: the
2903
+ * two sides may independently touch the symbols that define the task limits.
2904
+ * During drawing, the cursor after PT. 1 supplies a provisional PT. 2 and the
2905
+ * rule mirrors that first leg across a temporary center opening, so the full
2906
+ * symbol is visible before PT. 2 is committed.
2907
+ */
2908
+ declare const line26DrawRule: ControlMeasureDrawRule;
2909
+ //#endregion
2910
+ //#region src/draw-rules/area8.d.ts
2911
+ declare const supportByFireDrawRule: ControlMeasureDrawRule;
2912
+ //#endregion
2913
+ //#region src/draw-rules/axis1.d.ts
2914
+ declare const axis1DrawRule: ControlMeasureDrawRule;
2915
+ //#endregion
2916
+ //#region src/draw-rules/rectangle.d.ts
2917
+ declare const rectangleDrawRule: ControlMeasureDrawRule;
2918
+ //#endregion
2919
+ //#region src/generators/cm14-maneuver-lines/ambush.d.ts
2920
+ /**
2921
+ * Configuration options for the Ambush tactical symbol.
2922
+ */
2923
+ interface AmbushOptions {
2924
+ /** Number of segments used to draw the quadratic curve (default: 30) */
2925
+ arcSegments?: number;
2926
+ /** Size of arrowhead relative to chord span (default: 0.15) */
2927
+ arrowheadLengthRatio?: number;
2928
+ /** Width of arrowhead wings relative to its length (default: 0.5) */
2929
+ arrowheadWidthRatio?: number;
2930
+ /** Length of parallel hatches relative to chord span (default: 0.15) */
2931
+ hatchLengthRatio?: number;
2932
+ /** Number of parallel hatches along the curve (default: 5) */
2933
+ hatchCount?: number;
2934
+ /** Depth of the curve toward PT 1 relative to chord span (default: 0.25) */
2935
+ curveDepthRatio?: number;
2936
+ }
2937
+ declare const DEFAULT_AMBUSH_OPTIONS: Required<AmbushOptions>;
2938
+ //#endregion
2939
+ export { DEFAULT_OBSTACLE_BYPASS_DIFFICULT_OPTIONS as $, DEFAULT_DIRECTION_OF_ATTACK_AVIATION_OPTIONS as $n, DEFAULT_SUPPORT_BY_FIRE_OPTIONS as $t, roundToFixed as A, PickupZoneOptions as An, CanonicalTextAmplifiers as Ar, DEFAULT_COVER_OPTIONS as At, cloneControlMeasure as B, EncirclementOptions as Bn, AnchorTransformEvent as Br, DEFAULT_BREACH_OPTIONS as Bt, BaselineFrame as C, DEFAULT_MAIN_ATTACK_OPTIONS as Cn, ControlMeasureGeometryType as Cr, DEFAULT_SCREEN_OPTIONS as Ct, createBaselineFrame as D, AreaOfOperationsOptions as Dn, TextAmplifierDescriptor as Dr, DEFAULT_DELAY_OPTIONS as Dt, BaselineFrameOrigin as E, computeInitialWidthPoint as En, ParamDescriptor as Er, GuardOptions as Et, applyBoxTransformOptions as F, AssemblyAreaOptions as Fn, TextAmplifierKey as Fr, CanalizeOptions as Ft, ControlMeasureKind as G, StyleHints as Gn, DEFAULT_HANDOVER_LINE_OPTIONS as Gt, CONTROL_MEASURE_IDS as H, FinalProtectiveFireOptions as Hn, DEFAULT_BLOCK_MISSION_TASK_OPTIONS as Ht, freezeOrientationOptions as I, DEFAULT_ASSEMBLY_AREA_OPTIONS as In, TextAmplifiers as Ir, DEFAULT_CANALIZE_OPTIONS as It, getControlMeasureMetadataByValue as J, PrincipalDirectionOfFireOptions as Jn, PhaseLineOptions as Jt, OptionsByKind as K, controlMeasureIdFromFeature as Kn, HandoverLineOptions as Kt, RenderOptions as L, AreaDefenseOptions as Ln, canonicalTextAmplifierKey as Lr, BypassOptions as Lt, SimpleStyleRender as M, LandingZoneOptions as Mn, LabelPlacementOverride as Mr, TacticalArrowOptions as Mt, toSimpleStyle as N, DEFAULT_JOINT_TACTICAL_ACTION_AREA_OPTIONS as Nn, TEXT_AMPLIFIER_FIELDS as Nr, ClearOptions as Nt, EPSILON as O, DEFAULT_AREA_OF_OPERATIONS_OPTIONS as On, AmplifierPlacement as Or, DelayOptions as Ot, resolveStyleHints as P, JointTacticalActionAreaOptions as Pn, TextAmplifierField as Pr, DEFAULT_CLEAR_OPTIONS as Pt, ObstacleBypassImpossibleOptions as Q, DirectionOfMainAttackOptions as Qn, DEFAULT_ATTACK_BY_FIRE_OPTIONS as Qt, renderControlMeasure as R, DEFAULT_AREA_DEFENSE_OPTIONS as Rn, normalizeTextAmplifiers as Rr, DEFAULT_BYPASS_OPTIONS as Rt, snapToMidpointPerpendicular as S, SupportingAttackOptions as Sn, ControlMeasureGeometry as Sr, DEFAULT_ANTITANK_DITCH_OPTIONS as St, BaselineFrameOptions as T, calculateMetrics as Tn, ControlMeasurePaintCapability as Tr, DEFAULT_GUARD_OPTIONS as Tt, CONTROL_MEASURE_METADATA as U, ControlMeasureRender as Un, BattleHandoverLineOptions as Ut, isKind as V, DEFAULT_FINAL_PROTECTIVE_FIRE_OPTIONS as Vn, ControlMeasureDrawRule as Vr, BlockMissionTaskOptions as Vt, ControlMeasureId as W, FeaturePartProps as Wn, DEFAULT_BATTLE_HANDOVER_LINE_OPTIONS as Wt, listControlMeasureMetadata as X, DirectionOfSupportingAttackOptions as Xn, FLOTOptions as Xt, getDefaultOptions as Y, DEFAULT_DIRECTION_OF_SUPPORTING_ATTACK_OPTIONS as Yn, DEFAULT_FLOT_OPTIONS as Yt, DEFAULT_OBSTACLE_BYPASS_IMPOSSIBLE_OPTIONS as Z, DEFAULT_DIRECTION_OF_MAIN_ATTACK_OPTIONS as Zn, AttackByFireOptions as Zt, MidpointPerpendicularDrawRuleOptions as _, DEFAULT_BLOCK_ARROW_OPTIONS as _n, unproject as _r, DEFAULT_FORTIFIED_LINE_OPTIONS as _t, supportByFireDrawRule as a, DEFAULT_GENERIC_TEXT_OPTIONS as an, ControlMeasureStyle as ar, DEFAULT_FIX_OPTIONS as at, getMidpointPerpendicularSignedDistance as b, DEFAULT_CLASSIC_ARROW_OPTIONS as bn, BoxTransformDelta as br, DEFAULT_ANTITANK_WALL_OPTIONS as bt, line23DrawRule as c, GenericCircleOptions as cn, GenericC2LineOptions as cr, DisruptOptions as ct, ambushDrawRule as d, DEFAULT_GENERIC_POLYGON_OPTIONS as dn, DEFAULT_LIGHT_LINE_OPTIONS as dr, DEFAULT_TURNING_MOVEMENT_OPTIONS as dt, SupportByFireOptions as en, DirectionOfAttackAviationOptions as er, ObstacleBypassDifficultOptions as et, attackByFireDrawRule as f, GenericPolygonOptions as fn, LightLineOptions as fr, TurningMovementOptions as ft, blockDrawRule as g, BlockArrowOptions as gn, project as gr, FortifiedAreaOptions as gt, disruptDrawRule as h, BlockArrowHeadStyle as hn, haversineDistance as hr, DEFAULT_FORTIFIED_AREA_OPTIONS as ht, axis1DrawRule as i, DEFAULT_AIRBORNE_ATTACK_OPTIONS as in, DEFAULT_BATTLE_POSITION_OPTIONS as ir, TurnOptions as it, SimpleStyleProps as j, DEFAULT_LANDING_ZONE_OPTIONS as jn, GeneratedLabelKey as jr, DEFAULT_TACTICAL_ARROW_OPTIONS as jt, getMetersPerPixel as k, DEFAULT_PICKUP_ZONE_OPTIONS as kn, AmplifierPlacements as kr, CoverOptions as kt, turnDrawRule as l, DEFAULT_GENERIC_RECTANGLE_OPTIONS as ln, DEFAULT_ENGINEER_WORK_LINE_OPTIONS as lr, BlockOptions as lt, centerRadiusDrawRule as m, GenericLineOptions as mn, Point2D as mr, FrontalAttackOptions as mt, DEFAULT_AMBUSH_OPTIONS as n, DEFAULT_ATTACK_HELICOPTER_OPTIONS as nn, StrongPointOptions as nr, ObstacleBypassEasyOptions as nt, line26DrawRule as o, GenericTextOptions as on, FillPattern as or, FixOptions as ot, point12DrawRule as p, DEFAULT_GENERIC_LINE_OPTIONS as pn, LabelSizeOptions as pr, DEFAULT_FRONTAL_ATTACK_OPTIONS as pt, getControlMeasureMetadata as q, DEFAULT_PRINCIPAL_DIRECTION_OF_FIRE_OPTIONS as qn, DEFAULT_PHASE_LINE_OPTIONS as qt, rectangleDrawRule as r, AirborneAttackOptions as rn, BattlePositionOptions as rr, DEFAULT_TURN_OPTIONS as rt, line24DrawRule as s, DEFAULT_GENERIC_CIRCLE_OPTIONS as sn, DEFAULT_GENERIC_C2_LINE_OPTIONS as sr, DEFAULT_DISRUPT_OPTIONS as st, AmbushOptions as t, AttackHelicopterOptions as tn, DEFAULT_STRONG_POINT_OPTIONS as tr, DEFAULT_OBSTACLE_BYPASS_EASY_OPTIONS as tt, line1DrawRule as u, GenericRectangleOptions as un, EngineerWorkLineOptions as ur, DEFAULT_BLOCK_OPTIONS as ut, computeDefaultMidpointPerpendicularPoint as v, ClassicArrowHeadStyle as vn, BoundaryOptions as vr, FortifiedLineOptions as vt, BaselineFrameNormal as w, MainAttackOptions as wn, ControlMeasureMetadata as wr, ScreenOptions as wt, pointOnMidpointPerpendicularAxis as x, DEFAULT_SUPPORTING_ATTACK_OPTIONS as xn, ControlMeasureFillCapability as xr, AntitankDitchOptions as xt, createMidpointPerpendicularDrawRule as y, ClassicArrowOptions as yn, DEFAULT_BOUNDARY_OPTIONS as yr, AntitankWallOptions as yt, ControlMeasure as z, DEFAULT_ENCIRCLEMENT_OPTIONS as zn, resolveAmplifierPlacement as zr, BreachOptions as zt };