@seatlayer/core 0.53.0 → 0.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +2 -2
  2. package/dist/categoryInventory-BwarniiK.d.ts +109 -0
  3. package/dist/categoryInventory-D3qPwfKz.d.cts +109 -0
  4. package/dist/chunk-55NOSZK5.js +1 -0
  5. package/dist/chunk-6VTTBC5F.js +1 -0
  6. package/dist/chunk-6XJN4REG.js +1 -0
  7. package/dist/chunk-7PT7OQUO.js +1 -0
  8. package/dist/chunk-AQKYUJBX.js +1 -0
  9. package/dist/chunk-CXF32VPG.js +1 -0
  10. package/dist/chunk-DNGP2HDT.js +1 -0
  11. package/dist/chunk-EQM4FFN5.js +1 -0
  12. package/dist/chunk-HHM3PB66.js +1 -0
  13. package/dist/chunk-PXWKSYCK.js +1 -0
  14. package/dist/chunk-VDZ24QVV.js +1 -0
  15. package/dist/chunk-VI2CLV3Y.js +1 -0
  16. package/dist/core/chart-ops/index.cjs +1 -0
  17. package/dist/core/chart-ops/index.d.cts +1235 -0
  18. package/dist/core/chart-ops/index.d.ts +1235 -0
  19. package/dist/core/chart-ops/index.js +1 -0
  20. package/dist/core/color.cjs +1 -0
  21. package/dist/core/color.d.cts +192 -0
  22. package/dist/core/color.d.ts +192 -0
  23. package/dist/core/color.js +1 -0
  24. package/dist/core/inventory/index.cjs +1 -0
  25. package/dist/core/inventory/index.d.cts +209 -0
  26. package/dist/core/inventory/index.d.ts +209 -0
  27. package/dist/core/inventory/index.js +1 -0
  28. package/dist/core/layout/index.cjs +1 -0
  29. package/dist/core/layout/index.d.cts +376 -0
  30. package/dist/core/layout/index.d.ts +376 -0
  31. package/dist/core/layout/index.js +1 -0
  32. package/dist/core/quality/index.cjs +1 -0
  33. package/dist/core/quality/index.d.cts +132 -0
  34. package/dist/core/quality/index.d.ts +132 -0
  35. package/dist/core/quality/index.js +1 -0
  36. package/dist/core/render-assets/index.cjs +1 -0
  37. package/dist/core/render-assets/index.d.cts +99 -0
  38. package/dist/core/render-assets/index.d.ts +99 -0
  39. package/dist/core/render-assets/index.js +1 -0
  40. package/dist/core/seatConfidence.cjs +1 -1
  41. package/dist/core/seatConfidence.d.cts +1 -1
  42. package/dist/core/seatConfidence.d.ts +1 -1
  43. package/dist/core/seatConfidence.js +1 -1
  44. package/dist/core/sections/index.cjs +1 -0
  45. package/dist/core/sections/index.d.cts +346 -0
  46. package/dist/core/sections/index.d.ts +346 -0
  47. package/dist/core/sections/index.js +1 -0
  48. package/dist/{de-75NWRKC5.js → de-WPX4D3SY.js} +1 -1
  49. package/dist/{es-BM7EJ7PW.js → es-6KAJQVVX.js} +1 -1
  50. package/dist/{fr-HPXQHIB4.js → fr-5DTMRBN5.js} +1 -1
  51. package/dist/index.cjs +1 -1
  52. package/dist/index.d.cts +85 -534
  53. package/dist/index.d.ts +85 -534
  54. package/dist/index.js +1 -1
  55. package/dist/labeling-BmCzW50y.d.ts +90 -0
  56. package/dist/labeling-VfJBEOn0.d.cts +90 -0
  57. package/dist/layout-ClQkmixY.d.ts +181 -0
  58. package/dist/layout-Dlv5bIf2.d.cts +181 -0
  59. package/dist/renderedQuality-B3jgdgPO.d.ts +113 -0
  60. package/dist/renderedQuality-bDkUOyBL.d.cts +113 -0
  61. package/dist/renderer-B_g-W_QB.d.ts +534 -0
  62. package/dist/renderer-DySMcKAR.d.cts +534 -0
  63. package/dist/sections-DIzgtDjF.d.ts +123 -0
  64. package/dist/sections-Dna1nZgR.d.cts +123 -0
  65. package/dist/segmentedRowModel-BNXEUeHp.d.cts +75 -0
  66. package/dist/segmentedRowModel-COXw4GCh.d.ts +75 -0
  67. package/dist/ticketRestrictions-CzchbX_o.d.cts +72 -0
  68. package/dist/ticketRestrictions-DaYOCpEw.d.ts +72 -0
  69. package/dist/{types-tLOunI-B.d.cts → types-DTSG6_Hq.d.cts} +238 -761
  70. package/dist/{types-tLOunI-B.d.ts → types-DTSG6_Hq.d.ts} +238 -761
  71. package/dist/view3d/crossfade/panorama.d.cts +1 -1
  72. package/dist/view3d/crossfade/panorama.d.ts +1 -1
  73. package/dist/view3d/index.cjs +27 -27
  74. package/dist/view3d/index.d.cts +109 -2
  75. package/dist/view3d/index.d.ts +109 -2
  76. package/dist/view3d/index.js +26 -26
  77. package/package.json +94 -5
  78. package/dist/chunk-54A7LIL5.js +0 -1
@@ -0,0 +1,376 @@
1
+ import { P as Point, r as CubicPath, s as TextObject } from '../../types-DTSG6_Hq.cjs';
2
+ export { E as ExpandChartOptions, R as RowSeatSlot, T as TableSeatSlot, a as allObjects, c as chartBounds, e as expandBooth, b as expandChart, d as expandRow, f as expandRowSlots, g as expandTable, h as expandTableSlots, i as floorObjects, j as floorOverviewTranslations, k as floorsOf, l as layoutFloorOverview, o as objectCenter, m as owningSectionForObject, p as pointInPolygon, n as pointInPolygonWithHoles, q as polygonLabelPoint, r as rowInventoryCount, s as rowSeatPositions, t as stackFloors, u as tableInventoryCount, v as tableSeatCountsBySide, w as translateObject } from '../../layout-Dlv5bIf2.cjs';
3
+ export { a as SegmentedRowComponent, S as SegmentedRowPlacement, r as resolveSegmentedRowGroups, s as segmentedRowComponentSeats, b as segmentedRowComponents, c as segmentedRowSeatTotal } from '../../segmentedRowModel-BNXEUeHp.cjs';
4
+ import { E as ExpandedSeat } from '../../renderer-DySMcKAR.cjs';
5
+
6
+ type SectionShellMode = 'auto' | 'rectangle' | 'tapered' | 'bezier';
7
+ declare function cubicPoint(path: CubicPath, t: number): Point;
8
+ /**
9
+ * Build a predictable single-bend cubic whose midpoint passes exactly through
10
+ * `middle`. At t=.5 a cubic weighs both controls by 3/8, so moving both
11
+ * controls together by 4/3 of the requested midpoint offset makes the visible
12
+ * curve pass through the point the author dragged to.
13
+ *
14
+ * Lives here rather than in the Designer because two features need the same
15
+ * answer: the row bend handle (`renderRowPathHandles`) and the row curvature
16
+ * operations in `controller/rowOpsFacet`.
17
+ */
18
+ declare function smoothCubicThroughMiddle(start: Point, end: Point, middle: Point): CubicPath;
19
+ /** Equal-arc-length points on a cubic path, including both endpoints. */
20
+ declare function distributeAlongCubic(path: CubicPath, count: number, resolution?: number): Point[];
21
+ /**
22
+ * Convert a server-mapped rectangle into an editable complex shell. The four
23
+ * corners must be clockwise. No caller-supplied control points are accepted.
24
+ */
25
+ declare function buildSectionShell(corners: Point[], focal: Point, requested: SectionShellMode): {
26
+ mode: Exclude<SectionShellMode, 'auto'>;
27
+ outline: Point[];
28
+ };
29
+ /** Server-owned straight aisle cutouts spanning the near/far edges. */
30
+ declare function buildAisleHoles(corners: Point[], focal: Point, count: number, mode: Exclude<SectionShellMode, 'auto'>): Point[][];
31
+
32
+ /** Axis-aligned chart bounds used to derive a stable, document-relative camera. */
33
+ interface PerspectiveBounds {
34
+ x: number;
35
+ y: number;
36
+ width: number;
37
+ height: number;
38
+ }
39
+ /**
40
+ * A deterministic pinhole camera for the projected 2.5D buyer/Designer views.
41
+ * Coordinates stay in chart units so the ordinary Stage camera (pan/zoom) can
42
+ * remain the only screen-space transform.
43
+ */
44
+ interface PerspectiveCamera {
45
+ target: Point;
46
+ /** Horizontal distance from target to camera, in chart units. */
47
+ distance: number;
48
+ /** Camera height above the chart datum, in chart units. */
49
+ height: number;
50
+ /** Pinhole focal length, in chart units. */
51
+ focalLength: number;
52
+ /** Small plan rotation which keeps the venue from reading as a flat elevation. */
53
+ yawRad: number;
54
+ }
55
+ /** Canvas/Konva affine: x' = a·x + c·y + e; y' = b·x + d·y + f. */
56
+ interface Affine2D {
57
+ a: number;
58
+ b: number;
59
+ c: number;
60
+ d: number;
61
+ e: number;
62
+ f: number;
63
+ }
64
+ interface PerspectivePoint extends Point {
65
+ /** Positive camera-space distance; larger values are farther away. */
66
+ depth: number;
67
+ /** Perspective size multiplier at this point (1 at the camera target). */
68
+ scale: number;
69
+ }
70
+ /**
71
+ * Choose a camera from venue bounds rather than fixed pixels. The camera rises
72
+ * above the tallest authored surface, so even the (deliberately generous)
73
+ * 120-m validation ceiling cannot cross the near plane.
74
+ */
75
+ declare function createPerspectiveCamera(bounds: PerspectiveBounds, maxSurfaceHeightWorld?: number): PerspectiveCamera;
76
+ /** Project one 3D chart point through the pinhole camera. */
77
+ declare function projectPerspectivePoint(camera: PerspectiveCamera, point: Point, heightWorld?: number): PerspectivePoint;
78
+ declare function applyAffine(affine: Affine2D, point: Point): Point;
79
+ declare function invertAffine(affine: Affine2D): Affine2D;
80
+ /** Return `left(right(point))`. */
81
+ declare function composeAffine(left: Affine2D, right: Affine2D): Affine2D;
82
+ /**
83
+ * First-order projection around one object/section anchor. The height callback
84
+ * may describe a raked surface; sampling one chart unit along x/y captures its
85
+ * local slope. Per-section tangents are the intentional shell-performance
86
+ * contract. Buyer seat anchors are projected exactly by `projectPerspectivePoint`;
87
+ * only non-interactive section surfaces use this bounded approximation.
88
+ */
89
+ declare function perspectiveTangentAffine(camera: PerspectiveCamera, anchor: Point, heightAt?: (point: Point) => number): Affine2D;
90
+ /** Parameters accepted by Konva's rotation/scale/skew decomposition. */
91
+ declare function decomposeAffineLinear(affine: Affine2D): {
92
+ rotationDeg: number;
93
+ scaleX: number;
94
+ scaleY: number;
95
+ skewX: number;
96
+ };
97
+
98
+ /**
99
+ * Where a label belongs inside a polygon.
100
+ *
101
+ * A polygon's average-of-vertices centroid is not a label anchor. Two things
102
+ * break it on real venue geometry:
103
+ *
104
+ * - Concavity. An L-shaped concourse block, a C-shaped bowl tier, or a wedge
105
+ * with an aisle cut out can have its centroid land in the notch — outside
106
+ * the shape entirely.
107
+ * - Vertex density. A traced contour samples a curved outer arc with dozens of
108
+ * points and the two straight radial edges with two. The average is dragged
109
+ * onto the arc, so the label sits hard against the boundary and its pill
110
+ * spills into the neighbouring section.
111
+ *
112
+ * The right anchor is the *pole of inaccessibility*: the interior point
113
+ * furthest from every edge — the centre of the largest circle that fits inside
114
+ * the polygon. That is the fattest part of the shape, which is exactly where a
115
+ * label has room. This is the Mapbox `polylabel` algorithm: subdivide the
116
+ * bounding box into cells, keep the cell whose optimistic upper bound is best,
117
+ * and stop once no cell can beat the incumbent by more than `precision`.
118
+ *
119
+ * The returned `radius` is as useful as the point: it is the half-width of the
120
+ * room available, so a caller can shrink a label to fit — or decide it never
121
+ * will — without measuring glyphs.
122
+ */
123
+ interface InscribedAnchor {
124
+ /** Interior point furthest from every ring (outer boundary and holes). */
125
+ point: Point;
126
+ /** Distance from `point` to the nearest edge — the inscribed circle radius. */
127
+ radius: number;
128
+ }
129
+ /** Distance from `p` to the closest edge of any ring (unsigned). */
130
+ declare function distanceToRings(p: Point, rings: readonly (readonly Point[])[]): number;
131
+ /** Area of a ring (absolute, shoelace). */
132
+ declare function polygonArea(ring: readonly Point[]): number;
133
+ /** Net area of a polygon with holes — the space a section actually occupies. */
134
+ declare function polygonNetArea(outer: readonly Point[], holes?: readonly (readonly Point[])[]): number;
135
+ /**
136
+ * Largest-inscribed-circle anchor for a polygon (with optional holes).
137
+ *
138
+ * Deterministic: no randomness, no dependence on vertex order or winding, so
139
+ * the same geometry always produces the same anchor. Callers can therefore
140
+ * memoize on geometry alone.
141
+ */
142
+ declare function polygonInscribedAnchor(outer: readonly Point[], holes?: readonly (readonly Point[])[]): InscribedAnchor;
143
+
144
+ /**
145
+ * Pure-TypeScript spatial index for seat hit-testing.
146
+ *
147
+ * WHY THIS EXISTS
148
+ * ---------------
149
+ * `src/engine/SeatmapRenderer.ts` currently leans on Konva's built-in hit graph
150
+ * (the `listening` property, ~58 call sites) for "which seat did the pointer
151
+ * land on". No other renderer we care about ships an equivalent: React Native
152
+ * Skia has nothing at all, and Flutter / SwiftUI / Compose canvases all expect
153
+ * the app to own hit-testing. So the index has to exist on every path — and on
154
+ * the web it additionally lets us drop Konva's hit graph, which is a real win at
155
+ * 5k–13k seats (no per-seat hit-canvas rasterisation, no hit-graph traversal).
156
+ *
157
+ * This module is deliberately DEPENDENCY-FREE: no DOM, no Konva, no browser
158
+ * globals. It runs unchanged in a Web Worker, in workerd, and under React
159
+ * Native. All coordinates are WORLD space — converting screen→world is the
160
+ * caller's job, exactly as `SeatmapRenderer.screenToWorld` does today.
161
+ *
162
+ * STRUCTURE: uniform grid, not a quadtree
163
+ * ---------------------------------------
164
+ * Seats in a venue chart are close to uniformly dense by construction — they sit
165
+ * in rows on a near-regular pitch. That is the single case a uniform grid is
166
+ * optimal for, and it beats a quadtree on every axis that matters here:
167
+ * O(n) build with no rebalancing, flat typed-array storage (one contiguous
168
+ * scan per query, no pointer chasing), and O(1) expected candidates per point
169
+ * query. A quadtree only starts to pay when density varies by orders of
170
+ * magnitude across the extent, which a seating chart does not do. If a future
171
+ * chart shape ever breaks that assumption, `gridStats()` exposes the occupancy
172
+ * numbers needed to prove it before reaching for a tree.
173
+ *
174
+ * Each seat is inserted into EVERY cell its axis-aligned bounding box overlaps
175
+ * (not just the cell holding its centre). That is what makes {@link hitTest}
176
+ * examine exactly one cell: any seat whose shape contains a point also has an
177
+ * AABB containing that point, so it is guaranteed to be registered in that
178
+ * point's cell.
179
+ */
180
+
181
+ /**
182
+ * Default seat radius in world units. Mirrors `SEAT_RADIUS` in
183
+ * `SeatmapRenderer.ts` and `DesignerController.ts` (both 9). The renderer scales
184
+ * this by `theme.seatScale` clamped to [0.7, 1.6]; callers that do the same must
185
+ * pass the scaled value via {@link BuildOptions.seatRadius} so the index agrees
186
+ * with what is actually drawn.
187
+ */
188
+ declare const DEFAULT_SEAT_RADIUS = 9;
189
+ /**
190
+ * Hit geometry for one seat. Real seats are circles; trade-show booths render as
191
+ * rotated rounded rects whose dimensions live on the booth object in the
192
+ * ChartDoc, not on `ExpandedSeat` — so the caller supplies them through
193
+ * {@link BuildOptions.shapeOf} rather than this module reaching for the doc.
194
+ */
195
+ type SeatShape = {
196
+ kind: 'circle';
197
+ r: number;
198
+ } | {
199
+ kind: 'rect';
200
+ width: number;
201
+ height: number;
202
+ rotation?: number;
203
+ };
204
+ interface BuildOptions {
205
+ /** Radius for circular seats when {@link shapeOf} is absent. Default {@link DEFAULT_SEAT_RADIUS}. */
206
+ seatRadius?: number;
207
+ /**
208
+ * Per-seat hit geometry. Return `null`/`undefined` to fall back to a circle of
209
+ * `seatRadius`. Called exactly once per seat during construction.
210
+ */
211
+ shapeOf?: (seat: ExpandedSeat) => SeatShape | null | undefined;
212
+ /**
213
+ * Upper bound on grid cells, to stop a chart with one far-flung stray object
214
+ * from allocating a huge sparse grid. Default `max(64, 4 * seats.length)`.
215
+ * When the natural cell size would exceed this, cells are grown until it fits.
216
+ */
217
+ maxCells?: number;
218
+ }
219
+ interface QueryOptions {
220
+ /**
221
+ * Restrict results to seats this predicate accepts — used to reproduce the
222
+ * renderer's `isSelectable(id) || selection.has(id)` gate. Kept as a query
223
+ * argument rather than build state on purpose: seat statuses change on every
224
+ * websocket tick, and the geometry does not.
225
+ */
226
+ filter?: (id: string, seat: ExpandedSeat) => boolean;
227
+ }
228
+ interface Rect {
229
+ x: number;
230
+ y: number;
231
+ width: number;
232
+ height: number;
233
+ }
234
+ interface RectQueryOptions extends QueryOptions {
235
+ /**
236
+ * `'center'` (default) keeps a seat when its CENTRE falls inside the rect,
237
+ * bounds inclusive. This is what `SeatmapRenderer.finishMarquee` does today,
238
+ * so it is the default in order to be a drop-in replacement.
239
+ *
240
+ * `'overlap'` keeps a seat when its hit SHAPE intersects the rect at all —
241
+ * the right mode for "which seats are on screen" viewport culling and
242
+ * label-rendering passes, where a partially visible seat still counts.
243
+ */
244
+ mode?: 'center' | 'overlap';
245
+ }
246
+ interface IndexedSeat {
247
+ seat: ExpandedSeat;
248
+ shape: SeatShape;
249
+ /** Half-extents of the shape's axis-aligned bounding box (rotation applied). */
250
+ hx: number;
251
+ hy: number;
252
+ }
253
+ interface SeatIndex {
254
+ readonly seats: readonly ExpandedSeat[];
255
+ /** @internal */
256
+ readonly entries: readonly IndexedSeat[];
257
+ /** @internal */
258
+ readonly minX: number;
259
+ /** @internal */
260
+ readonly minY: number;
261
+ /** @internal */
262
+ readonly cell: number;
263
+ /** @internal */
264
+ readonly cols: number;
265
+ /** @internal */
266
+ readonly rows: number;
267
+ /** @internal Prefix-sum offsets into {@link items}; length cols*rows+1. */
268
+ readonly cellStart: Int32Array;
269
+ /** @internal Seat indices grouped by cell. */
270
+ readonly items: Int32Array;
271
+ /** @internal Per-seat visit stamps, for dedup across multi-cell scans. */
272
+ readonly stamp: Int32Array;
273
+ /** @internal Monotonically increasing stamp epoch. */
274
+ epoch: number;
275
+ }
276
+ /**
277
+ * Build a uniform-grid index over `seats`. O(n) in time and memory.
278
+ *
279
+ * CELL SIZE
280
+ * ---------
281
+ * The nominal cell is `4 × maxHalfExtent`, i.e. twice the largest seat's
282
+ * bounding-box width. Two properties fall out of that choice:
283
+ *
284
+ * - A seat's AABB is at most half a cell across, so it lands in at most 2×2 = 4
285
+ * cells. Build stays O(n) with a small constant, and the index does not blow
286
+ * up in memory from duplicated references.
287
+ * - For the default 9px seat radius the cell is 36 world units, versus a real
288
+ * row/seat pitch of roughly 20–26. That works out to ~1–2 seats per occupied
289
+ * cell, so a point query examines about one or two candidates. Halving the
290
+ * cell would quadruple cell count to shave a fraction of a candidate;
291
+ * doubling it would put ~6 seats in every cell. 4× the half-extent is the
292
+ * flat part of that curve.
293
+ *
294
+ * The one pathological input is a chart whose bounds are enormous relative to
295
+ * its seat count — a single stray object parked far from the venue. `maxCells`
296
+ * caps the grid and grows the cell size until it fits, trading query sharpness
297
+ * for bounded memory. Real charts never hit it.
298
+ */
299
+ declare function buildSeatIndex(seats: readonly ExpandedSeat[], opts?: BuildOptions): SeatIndex;
300
+ /**
301
+ * The seat whose hit shape contains `p`, or null.
302
+ *
303
+ * On overlap — seats drawn close enough that their circles intersect — the seat
304
+ * whose CENTRE is nearest to `p` wins. That matches what a user perceives (you
305
+ * hit the thing you aimed at) and, unlike Konva, is order-independent: Konva's
306
+ * hit graph resolves overlap by draw order, returning the topmost/last-added
307
+ * node regardless of how far off-centre the pointer was.
308
+ */
309
+ declare function hitTest(index: SeatIndex, p: Point, opts?: QueryOptions): string | null;
310
+ /**
311
+ * Nearest seat CENTRE strictly within `radius` world units of `p`, or null.
312
+ *
313
+ * This is the near-miss rescue from `SeatmapRenderer.nearestSeatToScreen`,
314
+ * lifted verbatim. The caller computes the radius the same way the renderer
315
+ * does today:
316
+ *
317
+ * const reachWorld = seatR + slopPx / stageScale; // SEAT_TAP_SLOP_PX = 14
318
+ * nearestWithin(index, screenToWorld(pointer), reachWorld, { filter });
319
+ *
320
+ * Note the comparison is STRICTLY less-than, mirroring the renderer's
321
+ * `bestD = reachWorld; ... if (d < bestD)` loop: a seat centre sitting exactly
322
+ * `reachWorld` away does not qualify. Distance is measured to the seat centre,
323
+ * not the shape edge — so for the default circle, "centre within seatR + slop"
324
+ * is identical to "edge within slop", which is what the renderer's docstring
325
+ * describes.
326
+ */
327
+ declare function nearestWithin(index: SeatIndex, p: Point, radius: number, opts?: QueryOptions): string | null;
328
+ /**
329
+ * Seat ids inside a world-space rect. Negative width/height are normalised, so a
330
+ * marquee dragged up-and-left works without the caller sorting the corners.
331
+ *
332
+ * Default `mode: 'center'` reproduces `SeatmapRenderer.finishMarquee` exactly:
333
+ * a seat is kept when its centre is within the rect, bounds INCLUSIVE. Use
334
+ * `mode: 'overlap'` for viewport culling, where a seat straddling the edge
335
+ * should still be drawn.
336
+ *
337
+ * Results come back in ascending seat-array order, so the output is stable
338
+ * across calls regardless of grid layout.
339
+ */
340
+ declare function queryRect(index: SeatIndex, rect: Rect, opts?: RectQueryOptions): string[];
341
+ /**
342
+ * Occupancy stats for the built grid. Diagnostic only — this is the evidence to
343
+ * check before anyone argues the uniform grid has stopped being good enough and
344
+ * a tree is warranted.
345
+ */
346
+ declare function gridStats(index: SeatIndex): {
347
+ cell: number;
348
+ cols: number;
349
+ rows: number;
350
+ cells: number;
351
+ occupiedCells: number;
352
+ refs: number;
353
+ maxPerCell: number;
354
+ meanPerOccupiedCell: number;
355
+ };
356
+
357
+ declare const TEXT_WIDTH_MIN = 40;
358
+ declare const TEXT_WIDTH_MAX = 1200;
359
+ declare const TEXT_LINE_HEIGHT_MIN = 0.8;
360
+ declare const TEXT_LINE_HEIGHT_MAX = 3;
361
+ declare const TEXT_LETTER_SPACING_MIN = -2;
362
+ declare const TEXT_LETTER_SPACING_MAX = 20;
363
+ declare const TEXT_OPACITY_MIN = 0.1;
364
+ declare const TEXT_BACKGROUND_PADDING_MAX = 40;
365
+ declare const TEXT_BACKGROUND_RADIUS_MAX = 40;
366
+ interface TextLayoutMetrics {
367
+ width: number;
368
+ height: number;
369
+ lineCount: number;
370
+ padding: number;
371
+ }
372
+ /** Conservative renderer-independent box used by chart bounds, quality and
373
+ * collision checks. Konva remains authoritative for exact glyph metrics. */
374
+ declare function textLayoutMetrics(text: TextObject): TextLayoutMetrics;
375
+
376
+ export { type Affine2D, type BuildOptions, DEFAULT_SEAT_RADIUS, type InscribedAnchor, type PerspectiveBounds, type PerspectiveCamera, type PerspectivePoint, type QueryOptions, type Rect, type RectQueryOptions, type SeatIndex, type SeatShape, type SectionShellMode, TEXT_BACKGROUND_PADDING_MAX, TEXT_BACKGROUND_RADIUS_MAX, TEXT_LETTER_SPACING_MAX, TEXT_LETTER_SPACING_MIN, TEXT_LINE_HEIGHT_MAX, TEXT_LINE_HEIGHT_MIN, TEXT_OPACITY_MIN, TEXT_WIDTH_MAX, TEXT_WIDTH_MIN, type TextLayoutMetrics, applyAffine, buildAisleHoles, buildSeatIndex, buildSectionShell, composeAffine, createPerspectiveCamera, cubicPoint, decomposeAffineLinear, distanceToRings, distributeAlongCubic, gridStats, hitTest, invertAffine, nearestWithin, perspectiveTangentAffine, polygonArea, polygonInscribedAnchor, polygonNetArea, projectPerspectivePoint, queryRect, smoothCubicThroughMiddle, textLayoutMetrics };