@seatlayer/core 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1294,6 +1294,27 @@ declare class PickerController {
1294
1294
  private scheduleReconnect;
1295
1295
  }
1296
1296
 
1297
+ /**
1298
+ * Synthetic view-from-seat panorama, generated from chart geometry alone.
1299
+ *
1300
+ * Draws a 2048×1024 equirectangular texture of a dark hall with the stage
1301
+ * placed at the correct bearing and angular size for THIS seat — closer seats
1302
+ * see a bigger stage, off-center seats see it at an angle. Used whenever the
1303
+ * organizer hasn't uploaded a real photo/360 for the seat; both go through the
1304
+ * same viewer.
1305
+ *
1306
+ * Equirectangular mapping: x = (yaw + 180°)/360° · W, y = (90° − pitch)/180° · H,
1307
+ * where yaw 0 = the direction the camera faces by default.
1308
+ */
1309
+
1310
+ interface PanoramaResult {
1311
+ url: string;
1312
+ /** Meters from the stage, for the caption. */
1313
+ distanceM: number;
1314
+ }
1315
+ declare function generateSeatPanorama(seat: ExpandedSeat, focalPoint: Point, neighborSeats: ExpandedSeat[]): PanoramaResult;
1316
+ declare function generateSeatThumb(seat: ExpandedSeat, focalPoint: Point, _neighborSeats?: ExpandedSeat[]): PanoramaResult;
1317
+
1297
1318
  /**
1298
1319
  * i18n core — deliberately tiny and framework-free so the embed SDK can share
1299
1320
  * it without dragging in a runtime library (the 60KB-gzipped SDK budget is a
@@ -1366,4 +1387,4 @@ declare function formatMoney(amount: number, currency?: string, fractionDigits?:
1366
1387
  /** Bare symbol for input adornments ("€", "$", "₹"). */
1367
1388
  declare function currencySymbol(currency?: string): string;
1368
1389
 
1369
- export { ACCESSIBILITY_TYPES, type AccessibilityMeta, type AccessibilityType, type AvailabilityRule, type BoothObject, CHART_STORAGE_KEY, type Category, type CategoryTier, type ChartDoc, type ChartObject, type ChartTheme, DEFAULT_CURRENCY, type Dict, type ExpandedSeat, type Floor, type GAAreaObject, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, type ISeatmapRenderer, type Locale, type LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PickerCallbacks, PickerController, type PickerOptions, type PickerSeat, type PickerTransport, type Point, type RendererCallbacks, type RendererOptions, type RowObject, type RowSeatSlot, SUPPORTED_LOCALES, type SeatHoverDetails, type SeatOverride, type SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, type SectionObject, type SectionSummary, type SelectionLayer, type ShapeObject, type TableObject, type TextObject, UNGROUPED_ID, type ZoneDef, accessibilityMeta, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, floorObjects, floorsOf, formatDate, formatMoney, gaAreasOf, gaUnitLabel, gaUnitLabels, getLocale, hiddenObjectIds, isGaUnitLabel, isSectionHidden, layerOf, loadLocale, objectCenter, pointInPolygon, resolveLocale, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount };
1390
+ export { ACCESSIBILITY_TYPES, type AccessibilityMeta, type AccessibilityType, type AvailabilityRule, type BoothObject, CHART_STORAGE_KEY, type Category, type CategoryTier, type ChartDoc, type ChartObject, type ChartTheme, DEFAULT_CURRENCY, type Dict, type ExpandedSeat, type Floor, type GAAreaObject, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, type ISeatmapRenderer, type Locale, type LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PanoramaResult, type PickerCallbacks, PickerController, type PickerOptions, type PickerSeat, type PickerTransport, type Point, type RendererCallbacks, type RendererOptions, type RowObject, type RowSeatSlot, SUPPORTED_LOCALES, type SeatHoverDetails, type SeatOverride, type SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, type SectionObject, type SectionSummary, type SelectionLayer, type ShapeObject, type TableObject, type TextObject, UNGROUPED_ID, type ZoneDef, accessibilityMeta, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, floorObjects, floorsOf, formatDate, formatMoney, gaAreasOf, gaUnitLabel, gaUnitLabels, generateSeatPanorama, generateSeatThumb, getLocale, hiddenObjectIds, isGaUnitLabel, isSectionHidden, layerOf, loadLocale, objectCenter, pointInPolygon, resolveLocale, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount };
package/dist/index.d.ts CHANGED
@@ -1294,6 +1294,27 @@ declare class PickerController {
1294
1294
  private scheduleReconnect;
1295
1295
  }
1296
1296
 
1297
+ /**
1298
+ * Synthetic view-from-seat panorama, generated from chart geometry alone.
1299
+ *
1300
+ * Draws a 2048×1024 equirectangular texture of a dark hall with the stage
1301
+ * placed at the correct bearing and angular size for THIS seat — closer seats
1302
+ * see a bigger stage, off-center seats see it at an angle. Used whenever the
1303
+ * organizer hasn't uploaded a real photo/360 for the seat; both go through the
1304
+ * same viewer.
1305
+ *
1306
+ * Equirectangular mapping: x = (yaw + 180°)/360° · W, y = (90° − pitch)/180° · H,
1307
+ * where yaw 0 = the direction the camera faces by default.
1308
+ */
1309
+
1310
+ interface PanoramaResult {
1311
+ url: string;
1312
+ /** Meters from the stage, for the caption. */
1313
+ distanceM: number;
1314
+ }
1315
+ declare function generateSeatPanorama(seat: ExpandedSeat, focalPoint: Point, neighborSeats: ExpandedSeat[]): PanoramaResult;
1316
+ declare function generateSeatThumb(seat: ExpandedSeat, focalPoint: Point, _neighborSeats?: ExpandedSeat[]): PanoramaResult;
1317
+
1297
1318
  /**
1298
1319
  * i18n core — deliberately tiny and framework-free so the embed SDK can share
1299
1320
  * it without dragging in a runtime library (the 60KB-gzipped SDK budget is a
@@ -1366,4 +1387,4 @@ declare function formatMoney(amount: number, currency?: string, fractionDigits?:
1366
1387
  /** Bare symbol for input adornments ("€", "$", "₹"). */
1367
1388
  declare function currencySymbol(currency?: string): string;
1368
1389
 
1369
- export { ACCESSIBILITY_TYPES, type AccessibilityMeta, type AccessibilityType, type AvailabilityRule, type BoothObject, CHART_STORAGE_KEY, type Category, type CategoryTier, type ChartDoc, type ChartObject, type ChartTheme, DEFAULT_CURRENCY, type Dict, type ExpandedSeat, type Floor, type GAAreaObject, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, type ISeatmapRenderer, type Locale, type LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PickerCallbacks, PickerController, type PickerOptions, type PickerSeat, type PickerTransport, type Point, type RendererCallbacks, type RendererOptions, type RowObject, type RowSeatSlot, SUPPORTED_LOCALES, type SeatHoverDetails, type SeatOverride, type SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, type SectionObject, type SectionSummary, type SelectionLayer, type ShapeObject, type TableObject, type TextObject, UNGROUPED_ID, type ZoneDef, accessibilityMeta, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, floorObjects, floorsOf, formatDate, formatMoney, gaAreasOf, gaUnitLabel, gaUnitLabels, getLocale, hiddenObjectIds, isGaUnitLabel, isSectionHidden, layerOf, loadLocale, objectCenter, pointInPolygon, resolveLocale, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount };
1390
+ export { ACCESSIBILITY_TYPES, type AccessibilityMeta, type AccessibilityType, type AvailabilityRule, type BoothObject, CHART_STORAGE_KEY, type Category, type CategoryTier, type ChartDoc, type ChartObject, type ChartTheme, DEFAULT_CURRENCY, type Dict, type ExpandedSeat, type Floor, type GAAreaObject, type HoldConflict, type HoldInfo, type HoldSelectionRequest, type HoldServerItem, type ISeatmapRenderer, type Locale, type LodRung, MAX_EVENT_INVENTORY, MAX_GA_CAPACITY, type PanoramaResult, type PickerCallbacks, PickerController, type PickerOptions, type PickerSeat, type PickerTransport, type Point, type RendererCallbacks, type RendererOptions, type RowObject, type RowSeatSlot, SUPPORTED_LOCALES, type SeatHoverDetails, type SeatOverride, type SeatStatus, SeatmapRenderer, type SectionCategory, type SectionNode, type SectionObject, type SectionSummary, type SelectionLayer, type ShapeObject, type TableObject, type TextObject, UNGROUPED_ID, type ZoneDef, accessibilityMeta, allObjects, applyHidden, chartBounds, computeSections, createRenderer, currencySymbol, expandBooth, expandChart, expandRow, expandRowSlots, expandTable, floorObjects, floorsOf, formatDate, formatMoney, gaAreasOf, gaUnitLabel, gaUnitLabels, generateSeatPanorama, generateSeatThumb, getLocale, hiddenObjectIds, isGaUnitLabel, isSectionHidden, layerOf, loadLocale, objectCenter, pointInPolygon, resolveLocale, setLocale, setMoneyLocale, setStringOverrides, stackFloors, t, tCount };
package/dist/index.js CHANGED
@@ -3401,6 +3401,202 @@ var PickerController = class {
3401
3401
  }
3402
3402
  };
3403
3403
 
3404
+ // src/view/generatePanorama.ts
3405
+ var W = 2048;
3406
+ var H = 1024;
3407
+ var UNIT = 0.55 / 24;
3408
+ var yawToX = (yawDeg) => (yawDeg + 180) / 360 * W;
3409
+ var pitchToY = (pitchDeg) => (90 - pitchDeg) / 180 * H;
3410
+ function generateSeatPanorama(seat, focalPoint, neighborSeats) {
3411
+ const canvas = document.createElement("canvas");
3412
+ canvas.width = W;
3413
+ canvas.height = H;
3414
+ const ctx = canvas.getContext("2d");
3415
+ const dx = focalPoint.x - seat.x;
3416
+ const dy = focalPoint.y - seat.y;
3417
+ const distU = Math.hypot(dx, dy);
3418
+ const distM = Math.max(2, distU * UNIT);
3419
+ const sky = ctx.createLinearGradient(0, 0, 0, H);
3420
+ sky.addColorStop(0, "#05070c");
3421
+ sky.addColorStop(0.42, "#11172a");
3422
+ sky.addColorStop(0.5, "#1a2238");
3423
+ sky.addColorStop(0.56, "#10141f");
3424
+ sky.addColorStop(1, "#07090f");
3425
+ ctx.fillStyle = sky;
3426
+ ctx.fillRect(0, 0, W, H);
3427
+ const stageHalfYaw = Math.min(80, Math.atan2(4, distM) * 180 / Math.PI);
3428
+ const stageTopPitch = Math.min(45, Math.atan2(5, distM) * 180 / Math.PI);
3429
+ const stageBasePitch = Math.max(-30, -Math.atan2(1.1, distM) * 180 / Math.PI);
3430
+ const sx0 = yawToX(-stageHalfYaw);
3431
+ const sx1 = yawToX(stageHalfYaw);
3432
+ const sy0 = pitchToY(stageTopPitch);
3433
+ const sy1 = pitchToY(stageBasePitch);
3434
+ const glow = ctx.createRadialGradient(W / 2, (sy0 + sy1) / 2, 10, W / 2, (sy0 + sy1) / 2, (sx1 - sx0) * 1.1);
3435
+ glow.addColorStop(0, "rgba(129, 140, 248, 0.5)");
3436
+ glow.addColorStop(0.5, "rgba(99, 102, 241, 0.16)");
3437
+ glow.addColorStop(1, "rgba(99, 102, 241, 0)");
3438
+ ctx.fillStyle = glow;
3439
+ ctx.fillRect(sx0 - (sx1 - sx0) * 0.6, sy0 - (sy1 - sy0) * 1.2, (sx1 - sx0) * 2.2, (sy1 - sy0) * 3.4);
3440
+ ctx.fillStyle = "#242c44";
3441
+ ctx.fillRect(sx0, sy0, sx1 - sx0, sy1 - sy0);
3442
+ const backdrop = ctx.createLinearGradient(0, sy0, 0, sy1);
3443
+ backdrop.addColorStop(0, "#7c5cff");
3444
+ backdrop.addColorStop(0.5, "#e1447a");
3445
+ backdrop.addColorStop(1, "#f59e0b");
3446
+ ctx.globalAlpha = 0.75;
3447
+ ctx.fillStyle = backdrop;
3448
+ const inset = (sx1 - sx0) * 0.06;
3449
+ ctx.fillRect(sx0 + inset, sy0 + (sy1 - sy0) * 0.12, sx1 - sx0 - inset * 2, (sy1 - sy0) * 0.62);
3450
+ ctx.globalAlpha = 1;
3451
+ ctx.fillStyle = "#0d1119";
3452
+ ctx.fillRect(sx0, sy1 - (sy1 - sy0) * 0.1, sx1 - sx0, (sy1 - sy0) * 0.1);
3453
+ const performerH = (sy1 - sy0) * 0.45;
3454
+ ctx.fillStyle = "rgba(8, 10, 16, 0.85)";
3455
+ for (const fx of [0.35, 0.5, 0.65]) {
3456
+ const px = sx0 + (sx1 - sx0) * fx;
3457
+ const py = sy1 - (sy1 - sy0) * 0.12;
3458
+ ctx.beginPath();
3459
+ ctx.arc(px, py - performerH * 0.82, performerH * 0.16, 0, Math.PI * 2);
3460
+ ctx.fill();
3461
+ ctx.fillRect(px - performerH * 0.14, py - performerH * 0.68, performerH * 0.28, performerH * 0.68);
3462
+ }
3463
+ ctx.globalAlpha = 0.14;
3464
+ ctx.fillStyle = "#c7d2fe";
3465
+ for (const fx of [0.3, 0.5, 0.7]) {
3466
+ const bx = sx0 + (sx1 - sx0) * fx;
3467
+ ctx.beginPath();
3468
+ ctx.moveTo(bx - 8, pitchToY(Math.min(60, stageTopPitch + 25)));
3469
+ ctx.lineTo(bx - (sx1 - sx0) * 0.09, sy1);
3470
+ ctx.lineTo(bx + (sx1 - sx0) * 0.09, sy1);
3471
+ ctx.lineTo(bx + 8, pitchToY(Math.min(60, stageTopPitch + 25)));
3472
+ ctx.closePath();
3473
+ ctx.fill();
3474
+ }
3475
+ ctx.globalAlpha = 1;
3476
+ ctx.fillStyle = "rgba(199, 210, 254, 0.8)";
3477
+ for (let i = 0; i < 26; i++) {
3478
+ const x = i / 26 * W;
3479
+ const y = pitchToY(55 + i % 3 * 6);
3480
+ ctx.beginPath();
3481
+ ctx.arc(x, y, 3.2, 0, Math.PI * 2);
3482
+ ctx.fill();
3483
+ }
3484
+ const stageBearing = Math.atan2(dx, -dy);
3485
+ ctx.fillStyle = "rgba(16, 20, 30, 0.95)";
3486
+ for (const other of neighborSeats) {
3487
+ if (other.id === seat.id) continue;
3488
+ const ox = other.x - seat.x;
3489
+ const oy = other.y - seat.y;
3490
+ const d = Math.hypot(ox, oy) * UNIT;
3491
+ if (d < 0.3 || d > 14) continue;
3492
+ const bearing = Math.atan2(ox, -oy) - stageBearing;
3493
+ const yaw = (bearing * 180 / Math.PI + 540) % 360 - 180;
3494
+ const headPitch = -Math.atan2(0.35, d) * 180 / Math.PI;
3495
+ const headR = Math.min(46, 260 / (d / UNIT / 24 + 1.2) / 4);
3496
+ const hx = yawToX(yaw);
3497
+ const hy = pitchToY(headPitch);
3498
+ ctx.beginPath();
3499
+ ctx.arc(hx, hy, headR, 0, Math.PI * 2);
3500
+ ctx.fill();
3501
+ ctx.beginPath();
3502
+ ctx.ellipse(hx, hy + headR * 1.4, headR * 1.7, headR * 0.9, 0, Math.PI, 0, true);
3503
+ ctx.fill();
3504
+ }
3505
+ const poleFade = ctx.createLinearGradient(0, 0, 0, H);
3506
+ poleFade.addColorStop(0, "rgba(0,0,0,0.85)");
3507
+ poleFade.addColorStop(0.12, "rgba(0,0,0,0)");
3508
+ poleFade.addColorStop(0.88, "rgba(0,0,0,0)");
3509
+ poleFade.addColorStop(1, "rgba(0,0,0,0.85)");
3510
+ ctx.fillStyle = poleFade;
3511
+ ctx.fillRect(0, 0, W, H);
3512
+ return { url: canvas.toDataURL("image/jpeg", 0.82), distanceM: Math.round(distM) };
3513
+ }
3514
+ var TW = 480;
3515
+ var TH = 270;
3516
+ var HALF_HFOV = 50;
3517
+ var HALF_VFOV = 30;
3518
+ var yawToTX = (yawDeg) => (yawDeg + HALF_HFOV) / (2 * HALF_HFOV) * TW;
3519
+ var pitchToTY = (pitchDeg) => (HALF_VFOV - pitchDeg) / (2 * HALF_VFOV) * TH;
3520
+ function generateSeatThumb(seat, focalPoint, _neighborSeats) {
3521
+ const canvas = document.createElement("canvas");
3522
+ canvas.width = TW;
3523
+ canvas.height = TH;
3524
+ const ctx = canvas.getContext("2d");
3525
+ const dx = focalPoint.x - seat.x;
3526
+ const dy = focalPoint.y - seat.y;
3527
+ const distM = Math.max(2, Math.hypot(dx, dy) * UNIT);
3528
+ const sky = ctx.createLinearGradient(0, 0, 0, TH);
3529
+ sky.addColorStop(0, "#05070c");
3530
+ sky.addColorStop(0.44, "#141b30");
3531
+ sky.addColorStop(0.5, "#1b2440");
3532
+ sky.addColorStop(0.58, "#10141f");
3533
+ sky.addColorStop(1, "#070910");
3534
+ ctx.fillStyle = sky;
3535
+ ctx.fillRect(0, 0, TW, TH);
3536
+ const stageHalfYaw = Math.min(HALF_HFOV - 2, Math.atan2(4, distM) * 180 / Math.PI);
3537
+ const stageTopPitch = Math.min(HALF_VFOV - 2, Math.atan2(5, distM) * 180 / Math.PI);
3538
+ const stageBasePitch = Math.max(-HALF_VFOV + 2, -Math.atan2(1.1, distM) * 180 / Math.PI);
3539
+ const sx0 = yawToTX(-stageHalfYaw);
3540
+ const sx1 = yawToTX(stageHalfYaw);
3541
+ const sy0 = pitchToTY(stageTopPitch);
3542
+ const sy1 = pitchToTY(stageBasePitch);
3543
+ const sw = sx1 - sx0;
3544
+ const sh = sy1 - sy0;
3545
+ const glow = ctx.createRadialGradient(TW / 2, (sy0 + sy1) / 2, 4, TW / 2, (sy0 + sy1) / 2, sw * 1.1);
3546
+ glow.addColorStop(0, "rgba(129,140,248,0.5)");
3547
+ glow.addColorStop(0.5, "rgba(99,102,241,0.15)");
3548
+ glow.addColorStop(1, "rgba(99,102,241,0)");
3549
+ ctx.fillStyle = glow;
3550
+ ctx.fillRect(sx0 - sw * 0.6, sy0 - sh * 1.2, sw * 2.2, sh * 3.4);
3551
+ ctx.fillStyle = "#242c44";
3552
+ ctx.fillRect(sx0, sy0, sw, sh);
3553
+ const backdrop = ctx.createLinearGradient(0, sy0, 0, sy1);
3554
+ backdrop.addColorStop(0, "#7c5cff");
3555
+ backdrop.addColorStop(0.5, "#e1447a");
3556
+ backdrop.addColorStop(1, "#f59e0b");
3557
+ ctx.globalAlpha = 0.78;
3558
+ ctx.fillStyle = backdrop;
3559
+ const inset = sw * 0.06;
3560
+ ctx.fillRect(sx0 + inset, sy0 + sh * 0.12, sw - inset * 2, sh * 0.62);
3561
+ ctx.globalAlpha = 1;
3562
+ ctx.fillStyle = "#0d1119";
3563
+ ctx.fillRect(sx0, sy1 - sh * 0.1, sw, sh * 0.1);
3564
+ const ph = sh * 0.45;
3565
+ ctx.fillStyle = "rgba(8,10,16,0.85)";
3566
+ for (const fx of [0.35, 0.5, 0.65]) {
3567
+ const px = sx0 + sw * fx;
3568
+ const py = sy1 - sh * 0.12;
3569
+ ctx.beginPath();
3570
+ ctx.arc(px, py - ph * 0.82, ph * 0.16, 0, Math.PI * 2);
3571
+ ctx.fill();
3572
+ ctx.fillRect(px - ph * 0.14, py - ph * 0.68, ph * 0.28, ph * 0.68);
3573
+ }
3574
+ ctx.globalAlpha = 0.15;
3575
+ ctx.fillStyle = "#c7d2fe";
3576
+ for (const fx of [0.3, 0.5, 0.7]) {
3577
+ const bx = sx0 + sw * fx;
3578
+ ctx.beginPath();
3579
+ ctx.moveTo(bx - 5, pitchToTY(Math.min(HALF_VFOV, stageTopPitch + 18)));
3580
+ ctx.lineTo(bx - sw * 0.09, sy1);
3581
+ ctx.lineTo(bx + sw * 0.09, sy1);
3582
+ ctx.lineTo(bx + 5, pitchToTY(Math.min(HALF_VFOV, stageTopPitch + 18)));
3583
+ ctx.closePath();
3584
+ ctx.fill();
3585
+ }
3586
+ ctx.globalAlpha = 1;
3587
+ ctx.fillStyle = "rgba(199,210,254,0.75)";
3588
+ for (let i = 0; i < 8; i++) {
3589
+ ctx.beginPath();
3590
+ ctx.arc((i + 0.5) / 8 * TW, pitchToTY(HALF_VFOV - 4 - i % 2 * 3), 2.2, 0, Math.PI * 2);
3591
+ ctx.fill();
3592
+ }
3593
+ ctx.fillStyle = "rgba(10,13,20,0.9)";
3594
+ ctx.fillRect(0, TH - 26, TW, 26);
3595
+ ctx.fillStyle = "rgba(30,37,54,0.9)";
3596
+ for (let i = 0; i < 9; i++) ctx.fillRect(i * (TW / 9) + 6, TH - 22, TW / 9 - 12, 14);
3597
+ return { url: canvas.toDataURL("image/jpeg", 0.8), distanceM: Math.round(distM) };
3598
+ }
3599
+
3404
3600
  // src/i18n/bundles.ts
3405
3601
  var LOADERS = {
3406
3602
  es: () => import("./es-SKJTYKLL.js").then((m) => ({ default: m.es })),
@@ -3453,6 +3649,8 @@ export {
3453
3649
  gaAreasOf,
3454
3650
  gaUnitLabel,
3455
3651
  gaUnitLabels,
3652
+ generateSeatPanorama,
3653
+ generateSeatThumb,
3456
3654
  getLocale,
3457
3655
  hiddenObjectIds,
3458
3656
  isGaUnitLabel,