@glassly/engine 0.3.1-dev.548 → 0.3.1-dev.558

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 (57) hide show
  1. package/build/generated/releaseMetadata.js +3 -3
  2. package/build/generated/releaseMetadata.js.map +1 -1
  3. package/build/index.d.ts +1 -1
  4. package/build/index.d.ts.map +1 -1
  5. package/build/index.js +1 -1
  6. package/build/index.js.map +1 -1
  7. package/build/services/DisplayProcessor.d.ts.map +1 -1
  8. package/build/services/DisplayProcessor.js +2 -1
  9. package/build/services/DisplayProcessor.js.map +1 -1
  10. package/build/services/effectiveCapabilities.d.ts.map +1 -1
  11. package/build/services/effectiveCapabilities.js +7 -4
  12. package/build/services/effectiveCapabilities.js.map +1 -1
  13. package/build/services/pages/pageEligibility.d.ts +6 -2
  14. package/build/services/pages/pageEligibility.d.ts.map +1 -1
  15. package/build/services/pages/pageEligibility.js +11 -4
  16. package/build/services/pages/pageEligibility.js.map +1 -1
  17. package/build/types/capabilities/rayneo-io.d.ts +14 -0
  18. package/build/types/capabilities/rayneo-io.d.ts.map +1 -0
  19. package/build/types/capabilities/rayneo-io.js +84 -0
  20. package/build/types/capabilities/rayneo-io.js.map +1 -0
  21. package/build/types/enums.d.ts +2 -1
  22. package/build/types/enums.d.ts.map +1 -1
  23. package/build/types/enums.js +1 -0
  24. package/build/types/enums.js.map +1 -1
  25. package/build/types/hardware.d.ts +2 -1
  26. package/build/types/hardware.d.ts.map +1 -1
  27. package/build/types/hardware.js +3 -2
  28. package/build/types/hardware.js.map +1 -1
  29. package/build/types/index.d.ts +1 -1
  30. package/build/types/index.d.ts.map +1 -1
  31. package/build/types/index.js +1 -1
  32. package/build/types/index.js.map +1 -1
  33. package/build/utils/display/index.d.ts +1 -0
  34. package/build/utils/display/index.d.ts.map +1 -1
  35. package/build/utils/display/index.js +2 -0
  36. package/build/utils/display/index.js.map +1 -1
  37. package/build/utils/display/profiles/index.d.ts +1 -0
  38. package/build/utils/display/profiles/index.d.ts.map +1 -1
  39. package/build/utils/display/profiles/index.js +2 -0
  40. package/build/utils/display/profiles/index.js.map +1 -1
  41. package/build/utils/display/profiles/rayneo-io.d.ts +2 -0
  42. package/build/utils/display/profiles/rayneo-io.d.ts.map +1 -0
  43. package/build/utils/display/profiles/rayneo-io.js +3 -0
  44. package/build/utils/display/profiles/rayneo-io.js.map +1 -0
  45. package/package.json +7 -7
  46. package/src/generated/releaseMetadata.ts +3 -3
  47. package/src/index.ts +1 -0
  48. package/src/services/DisplayProcessor.ts +2 -0
  49. package/src/services/effectiveCapabilities.ts +6 -3
  50. package/src/services/pages/pageEligibility.ts +12 -3
  51. package/src/types/capabilities/rayneo-io.ts +101 -0
  52. package/src/types/enums.ts +1 -0
  53. package/src/types/hardware.ts +3 -2
  54. package/src/types/index.ts +1 -0
  55. package/src/utils/display/index.ts +3 -0
  56. package/src/utils/display/profiles/index.ts +3 -0
  57. package/src/utils/display/profiles/rayneo-io.ts +2 -0
@@ -1,9 +1,9 @@
1
1
  export const ENGINE_RELEASE_METADATA = Object.freeze({
2
2
  "schemaVersion": 1,
3
3
  "familyBaseVersion": "0.3.1",
4
- "releaseIdentity": "0.3.1-dev.548",
5
- "releaseSetId": "glassly-0.3.1-dev.548",
6
- "sourceCommit": "8de673988aed75061b39b243d324fcf0b5050224",
4
+ "releaseIdentity": "0.3.1-dev.558",
5
+ "releaseSetId": "glassly-0.3.1-dev.558",
6
+ "sourceCommit": "34ac11d489d7bea0de60e4d4f25ff0a2121827cd",
7
7
  "otaManifestUrl": null,
8
8
  "otaManifestSha256": null
9
9
  });
@@ -1 +1 @@
1
- {"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,uBAAuB,GAAoC,MAAM,CAAC,MAAM,CAAC;IACpF,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,eAAe;IAClC,cAAc,EAAE,uBAAuB;IACvC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,IAAI;IACtB,mBAAmB,EAAE,IAAI;CAC1B,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface EngineReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"0.3.1\",\n \"releaseIdentity\": \"0.3.1-dev.548\",\n \"releaseSetId\": \"glassly-0.3.1-dev.548\",\n \"sourceCommit\": \"8de673988aed75061b39b243d324fcf0b5050224\",\n \"otaManifestUrl\": null,\n \"otaManifestSha256\": null\n})\n"]}
1
+ {"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,uBAAuB,GAAoC,MAAM,CAAC,MAAM,CAAC;IACpF,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,eAAe;IAClC,cAAc,EAAE,uBAAuB;IACvC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,IAAI;IACtB,mBAAmB,EAAE,IAAI;CAC1B,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface EngineReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"0.3.1\",\n \"releaseIdentity\": \"0.3.1-dev.558\",\n \"releaseSetId\": \"glassly-0.3.1-dev.558\",\n \"sourceCommit\": \"34ac11d489d7bea0de60e4d4f25ff0a2121827cd\",\n \"otaManifestUrl\": null,\n \"otaManifestSha256\": null\n})\n"]}
package/build/index.d.ts CHANGED
@@ -48,6 +48,6 @@ export { DUMMY_APPLET, saveAppsOrder, getAppsOrder, sortAppsByPackageNamePriorit
48
48
  export { decideDevLaunchRoute, type DecideDevLaunchOptions, type DevLaunchResult, type DevManifest, } from "./utils/devMiniappLaunch";
49
49
  export { HardwareCompatibility, type CompatibilityResult } from "./utils/hardware";
50
50
  export { BgTimer, throttle, debounce } from "./utils/timers";
51
- export { HardwareType, HardwareRequirementLevel, DeviceTypes, ControllerTypes, HARDWARE_CAPABILITIES, getModelCapabilities, simulatedGlasses, evenRealitiesG1, evenRealitiesG2, mentraLive, nimo, vuzixZ100, mentraDisplay, } from "./types";
51
+ export { HardwareType, HardwareRequirementLevel, DeviceTypes, ControllerTypes, HARDWARE_CAPABILITIES, getModelCapabilities, simulatedGlasses, evenRealitiesG1, evenRealitiesG2, mentraLive, nimo, rayneoIO, vuzixZ100, mentraDisplay, } from "./types";
52
52
  export type { HardwareRequirement, CameraCapabilities, DisplayCapabilities, MicrophoneCapabilities, SpeakerCapabilities, IMUCapabilities, ButtonCapabilities, LightCapabilities, PowerCapabilities, Capabilities, AppletType, AppPermissionType, AppletPermission, AppletInterface, ClientApp, } from "./types";
53
53
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/build/index.js CHANGED
@@ -48,5 +48,5 @@ export { decideDevLaunchRoute, } from "./utils/devMiniappLaunch";
48
48
  export { HardwareCompatibility } from "./utils/hardware";
49
49
  export { BgTimer, throttle, debounce } from "./utils/timers";
50
50
  // Hardware types and capability profiles.
51
- export { HardwareType, HardwareRequirementLevel, DeviceTypes, ControllerTypes, HARDWARE_CAPABILITIES, getModelCapabilities, simulatedGlasses, evenRealitiesG1, evenRealitiesG2, mentraLive, nimo, vuzixZ100, mentraDisplay, } from "./types";
51
+ export { HardwareType, HardwareRequirementLevel, DeviceTypes, ControllerTypes, HARDWARE_CAPABILITIES, getModelCapabilities, simulatedGlasses, evenRealitiesG1, evenRealitiesG2, mentraLive, nimo, rayneoIO, vuzixZ100, mentraDisplay, } from "./types";
52
52
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,2EAA2E;AAC3E,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAA;AAY/B,OAAO,EAAC,uBAAuB,EAAE,iBAAiB,EAAE,eAAe,EAAC,MAAM,wBAAwB,CAAA;AAelG,2EAA2E;AAC3E,6EAA6E;AAC7E,yEAAyE;AACzE,qEAAqE;AACrE,kDAAkD;AAClD,OAAO,EAAC,QAAQ,EAAE,UAAU,EAAE,uBAAuB,EAAC,MAAM,mBAAmB,CAAA;AAC/E,OAAO,EAAC,oBAAoB,EAAE,yBAAyB,EAAC,MAAM,kCAAkC,CAAA;AAEhG,4EAA4E;AAC5E,yEAAyE;AACzE,6EAA6E;AAC7E,OAAO,EAAC,QAAQ,EAAE,kBAAkB,EAAE,gBAAgB,EAAC,MAAM,6BAA6B,CAAA;AAS1F,OAAO,EAAC,wBAAwB,EAAE,gCAAgC,EAAC,MAAM,+BAA+B,CAAA;AAExG,8CAA8C;AAC9C,OAAO,EAAC,oBAAoB,EAAC,MAAM,kBAAkB,CAAA;AAGrD,2DAA2D;AAC3D,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,mBAAmB,GAGpB,MAAM,6BAA6B,CAAA;AACpC,yEAAyE;AACzE,OAAO,EACL,eAAe,EACf,yBAAyB,GAI1B,MAAM,kCAAkC,CAAA;AAazC,uEAAuE;AACvE,2DAA2D;AAC3D,OAAO,EACL,wBAAwB,EACxB,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAA;AAW7D,OAAO,EACL,iBAAiB,EACjB,8BAA8B,EAC9B,oBAAoB,EACpB,uBAAuB,EACvB,kCAAkC,EAClC,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,mCAAmC,GACpC,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,uCAAuC,EACvC,yCAAyC,GAC1C,MAAM,4BAA4B,CAAA;AAMnC,OAAO,EAAC,uBAAuB,EAAC,MAAM,6CAA6C,CAAA;AACnF,OAAO,EAAC,wBAAwB,EAAC,MAAM,wCAAwC,CAAA;AAe/E,+EAA+E;AAC/E,OAAO,EAAC,eAAe,EAAC,MAAM,qBAAqB,CAAA;AAEnD,yEAAyE;AACzE,6CAA6C;AAC7C,OAAO,EACL,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,6BAA6B,EAC7B,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,OAAO,EACP,QAAQ,EACR,OAAO,EACP,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,4BAA4B,EAC5B,gBAAgB,GAGjB,MAAM,eAAe,CAAA;AAEtB,4EAA4E;AAC5E,OAAO,EACL,oBAAoB,GAIrB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,qBAAqB,EAA2B,MAAM,kBAAkB,CAAA;AAChF,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAC,MAAM,gBAAgB,CAAA;AAE1D,0CAA0C;AAC1C,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,WAAW,EACX,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,UAAU,EACV,IAAI,EACJ,SAAS,EACT,aAAa,GACd,MAAM,SAAS,CAAA","sourcesContent":["/**\n * `@glassly/engine` — the OEM-facing main entry.\n *\n * The `engine` namespace (configure/start/stop + typed domain facades), the\n * public contract/read-model types, and the pure helpers host UI legitimately\n * renders with (decision functions, sort/order helpers, policy constants,\n * capability tables, timers). Judgment rule: read models, commands, pure\n * functions and types belong here; anything that mutates runtime state or\n * exposes a raw store/service remains private to the Glassly host.\n * See cloud-v2/docs/issues/020-glasses-status-boundary/integration-review.md §D.\n */\n\n// The namespaced OEM-facing engine API (the \"(A) host API\"). See ./engine.\nexport {engine} from \"./engine\"\nexport type {\n ReportAttachmentInput,\n ReportContext,\n ReportDetails,\n ReportStatus,\n ReportTrigger,\n ReportSubmitResult,\n EngineSubmitReportInput,\n} from \"./facades/reports\"\nexport type {IslandNotification, IslandNotificationKind} from \"./facades/notifications\"\nexport type {PresentationOwner} from \"./services/notifications/notificationPolicy\"\nexport {DEFAULT_HIDDEN_PACKAGES, isGatedByDevTools, isSystemMiniapp} from \"./stores/appVisibility\"\nexport type {WifiSearchResult} from \"./facades/glassesWifi\"\nexport type {IdentitySnapshot} from \"./services/PairingIdentity\"\nexport type {DisplayMirrorEvent} from \"./facades/displayMirror\"\nexport type {\n IslandConfigureOptions,\n IslandAuth,\n IslandConfigValues,\n IslandAnalytics,\n IslandUiSeams,\n ScanQrOptions,\n ScanQrResult,\n SubjectTokenType,\n} from \"./runtime/bootstrap\"\n\n// Settings contract: the typed key registry (schema descriptors — the same\n// surface engine.settings.descriptor()/keys() reads), the per-key React hook\n// (the hook layer, same precedent as the apps hooks below), and the pure\n// device-model key helpers. The raw useSettingsStore stays internal;\n// imperative access goes through engine.settings.\nexport {SETTINGS, useSetting, AI_DATA_CONSENT_VERSION} from \"./stores/settings\"\nexport {isCfwFirmwareVersion, isCustomDashboardEligible} from \"./services/pages/pageEligibility\"\n\n// AI tier registry: the curated per-tier model dropdown options and helpers\n// the Settings > AI Models screen renders. Resolution itself runs inside\n// LocalMiniappRuntime; the screen only reads/writes the ai_model_* settings.\nexport {AI_TIERS, TIER_MODEL_OPTIONS, parseTierSetting} from \"./services/AiTierResolution\"\nexport type {AiTier, AiTierProvider, TierModelOption} from \"./services/AiTierResolution\"\n\n// Shared user memory timeline (engine.memory / Settings > Memory). Entry and\n// session shapes are canonical in @glassly/miniapp (the session.memory\n// surface); the stats read model is engine-side.\nexport type {MemoryStats} from \"./services/MemoryStore\"\nexport type {SpeakerProfile} from \"./services/SpeakerProfileStore\"\nexport type {EnrollOutcome} from \"./facades/speakers\"\nexport {MENTRA_LIVE_SETTING_KEYS, getBluetoothSettingKeysForDevice} from \"./stores/bluetoothSettingKeys\"\n\n// Runtime-shared constants and contract DTOs.\nexport {ISLAND_SETTINGS_KEYS} from \"./runtime/config\"\nexport type {CloudClientStatusSnapshot, MiniappAuthToken, InteropAuditEvent, TtsSynthesisResult} from \"./runtime/config\"\n\n// Pure readiness predicates over glasses connection state.\nexport {\n isGlassesConnected,\n isGlassesReady,\n isGlassesLinkLayerBusy,\n waitForGlassesReady,\n type GlassesConnectionStatus,\n type WaitForGlassesReadyOptions,\n} from \"./services/GlassesReadiness\"\n// Pure connect/reconnect decision helpers (host UI renders the outcome).\nexport {\n decideReconnect,\n decideConnectButtonAction,\n type ReconnectDecision,\n type ReconnectDecisionInput,\n type ConnectButtonAction,\n} from \"./services/ConnectionCoordinator\"\n\n// OTA read-model types for host OTA UI (progress screen, error mapping,\n// progress section) — the check/install machinery itself is internal.\nexport type {\n VersionInfo,\n MtkPatch,\n BesFirmware,\n VersionJson,\n OtaCheckResult,\n OtaCheckCurrentGlassesResult,\n OtaCheckCurrentGlassesOptions,\n} from \"./services/OtaUpdateCheckService\"\n// OTA install policy (watchdog timings + failure copy) + display-state\n// derivation, consumed by the OTA screens and their tests.\nexport {\n MINIMUM_OTA_STATUS_BUILD,\n MAX_RETRIES,\n RETRY_INTERVAL_MS,\n PROGRESS_TIMEOUT_MS,\n DOWNLOAD_STUCK_TIMEOUT_MS,\n MTK_INSTALL_TIMEOUT_MS,\n GLOBAL_OTA_TIMEOUT_MS,\n PING_INTERVAL_MS,\n QUERY_REPLY_TIMEOUT_MS,\n BES_RESTART_TIMEOUT_MS,\n OtaProgressMessages,\n} from \"./services/otaInstallPolicy\"\nexport {deriveDisplayState} from \"./services/otaDisplayState\"\nexport type {DisplayState} from \"./services/otaDisplayState\"\nexport type {\n OtaProgress,\n OtaProgressStatus,\n OtaStatus,\n OtaUpdateInfo,\n ReleaseChangelog,\n OtaSnapshot,\n OtaInstallSnapshot,\n} from \"./facades/ota\"\nexport {\n beginOtaAutoChain,\n clearOtaAutoChainReconnectWait,\n isOtaAutoChainActive,\n otaAutoChainFingerprint,\n otaAutoChainReconnectWaitRemaining,\n stopOtaAutoChain,\n tryAdvanceOtaAutoChain,\n MAX_OTA_AUTO_CHAIN_PASSES,\n OTA_AUTO_CHAIN_RECONNECT_TIMEOUT_MS,\n} from \"./services/OtaAutoChain\"\nexport type {OtaAutoChainAdvanceResult} from \"./services/OtaAutoChain\"\nexport {\n BES_INSTALL_RESTART_MESSAGE,\n getOtaErrorMessage,\n shouldRequireGlassesRebootForBesFailure,\n shouldShowChangeWifiForOtaDownloadFailure,\n} from \"./services/OtaErrorMapping\"\n\n// Gallery read models: engine.gallery.onNotice payload types, the media\n// permission helper + display-name derivation host gallery UI uses, and the\n// glasses-camera DTO types (re-exported through the host @/types/asg shim).\nexport type {GalleryNotice, GalleryNoticeCode} from \"./services/asg/galleryNotices\"\nexport {MediaLibraryPermissions} from \"./utils/permissions/MediaLibraryPermissions\"\nexport {deriveGalleryDisplayName} from \"./utils/permissions/galleryDisplayName\"\nexport type {\n PhotoInfo,\n CaptureFile,\n CaptureGroup,\n GalleryResponse,\n ServerStatus,\n HealthResponse,\n GalleryEvent,\n} from \"./types/asg\"\n\n// Bluetooth SDK event types host UI subscribes to via engine facades (the\n// BluetoothSdk singleton passthrough itself is internal).\nexport type {PairFailureEvent, GlassesNotReadyEvent} from \"@glassly/bluetooth-sdk\"\n\n// Cloud connection status enum (read model; the connection store is internal).\nexport {WebSocketStatus} from \"./stores/connection\"\n\n// App-list hook layer + pure list helpers (the raw useAppStatusStore and\n// installAppStoreHooks wiring are internal).\nexport {\n DUMMY_APPLET,\n saveAppsOrder,\n getAppsOrder,\n sortAppsByPackageNamePriority,\n saveLastOpenTime,\n getLastOpenTime,\n sortAppsByLastOpenTime,\n useApps,\n useStart,\n useStop,\n useSetForeground,\n useClearForeground,\n useRefresh,\n useStopAll,\n useInstall,\n useUninstall,\n useActiveApps,\n useRunningAlwaysOnApps,\n useActiveBackgroundApps,\n useBackgroundApps,\n useActiveForegroundApp,\n useForegroundApp,\n useActiveBackgroundAppsCount,\n useLocalMiniApps,\n type StartOptions,\n type OrderMap,\n} from \"./stores/apps\"\n\n// Pure dev-miniapp launch-route decision (registration itself is internal).\nexport {\n decideDevLaunchRoute,\n type DecideDevLaunchOptions,\n type DevLaunchResult,\n type DevManifest,\n} from \"./utils/devMiniappLaunch\"\nexport {HardwareCompatibility, type CompatibilityResult} from \"./utils/hardware\"\nexport {BgTimer, throttle, debounce} from \"./utils/timers\"\n\n// Hardware types and capability profiles.\nexport {\n HardwareType,\n HardwareRequirementLevel,\n DeviceTypes,\n ControllerTypes,\n HARDWARE_CAPABILITIES,\n getModelCapabilities,\n simulatedGlasses,\n evenRealitiesG1,\n evenRealitiesG2,\n mentraLive,\n nimo,\n vuzixZ100,\n mentraDisplay,\n} from \"./types\"\nexport type {\n HardwareRequirement,\n CameraCapabilities,\n DisplayCapabilities,\n MicrophoneCapabilities,\n SpeakerCapabilities,\n IMUCapabilities,\n ButtonCapabilities,\n LightCapabilities,\n PowerCapabilities,\n Capabilities,\n AppletType,\n AppPermissionType,\n AppletPermission,\n AppletInterface,\n ClientApp,\n} from \"./types\"\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `@glassly/engine` — the OEM-facing main entry.\n *\n * The `engine` namespace (configure/start/stop + typed domain facades), the\n * public contract/read-model types, and the pure helpers host UI legitimately\n * renders with (decision functions, sort/order helpers, policy constants,\n * capability tables, timers). Judgment rule: read models, commands, pure\n * functions and types belong here; anything that mutates runtime state or\n * exposes a raw store/service remains private to the Glassly host.\n * See cloud-v2/docs/issues/020-glasses-status-boundary/integration-review.md §D.\n */\n\n// The namespaced OEM-facing engine API (the \"(A) host API\"). See ./engine.\nexport {engine} from \"./engine\"\nexport type {\n ReportAttachmentInput,\n ReportContext,\n ReportDetails,\n ReportStatus,\n ReportTrigger,\n ReportSubmitResult,\n EngineSubmitReportInput,\n} from \"./facades/reports\"\nexport type {IslandNotification, IslandNotificationKind} from \"./facades/notifications\"\nexport type {PresentationOwner} from \"./services/notifications/notificationPolicy\"\nexport {DEFAULT_HIDDEN_PACKAGES, isGatedByDevTools, isSystemMiniapp} from \"./stores/appVisibility\"\nexport type {WifiSearchResult} from \"./facades/glassesWifi\"\nexport type {IdentitySnapshot} from \"./services/PairingIdentity\"\nexport type {DisplayMirrorEvent} from \"./facades/displayMirror\"\nexport type {\n IslandConfigureOptions,\n IslandAuth,\n IslandConfigValues,\n IslandAnalytics,\n IslandUiSeams,\n ScanQrOptions,\n ScanQrResult,\n SubjectTokenType,\n} from \"./runtime/bootstrap\"\n\n// Settings contract: the typed key registry (schema descriptors — the same\n// surface engine.settings.descriptor()/keys() reads), the per-key React hook\n// (the hook layer, same precedent as the apps hooks below), and the pure\n// device-model key helpers. The raw useSettingsStore stays internal;\n// imperative access goes through engine.settings.\nexport {SETTINGS, useSetting, AI_DATA_CONSENT_VERSION} from \"./stores/settings\"\nexport {isCfwFirmwareVersion, isCustomDashboardEligible} from \"./services/pages/pageEligibility\"\n\n// AI tier registry: the curated per-tier model dropdown options and helpers\n// the Settings > AI Models screen renders. Resolution itself runs inside\n// LocalMiniappRuntime; the screen only reads/writes the ai_model_* settings.\nexport {AI_TIERS, TIER_MODEL_OPTIONS, parseTierSetting} from \"./services/AiTierResolution\"\nexport type {AiTier, AiTierProvider, TierModelOption} from \"./services/AiTierResolution\"\n\n// Shared user memory timeline (engine.memory / Settings > Memory). Entry and\n// session shapes are canonical in @glassly/miniapp (the session.memory\n// surface); the stats read model is engine-side.\nexport type {MemoryStats} from \"./services/MemoryStore\"\nexport type {SpeakerProfile} from \"./services/SpeakerProfileStore\"\nexport type {EnrollOutcome} from \"./facades/speakers\"\nexport {MENTRA_LIVE_SETTING_KEYS, getBluetoothSettingKeysForDevice} from \"./stores/bluetoothSettingKeys\"\n\n// Runtime-shared constants and contract DTOs.\nexport {ISLAND_SETTINGS_KEYS} from \"./runtime/config\"\nexport type {CloudClientStatusSnapshot, MiniappAuthToken, InteropAuditEvent, TtsSynthesisResult} from \"./runtime/config\"\n\n// Pure readiness predicates over glasses connection state.\nexport {\n isGlassesConnected,\n isGlassesReady,\n isGlassesLinkLayerBusy,\n waitForGlassesReady,\n type GlassesConnectionStatus,\n type WaitForGlassesReadyOptions,\n} from \"./services/GlassesReadiness\"\n// Pure connect/reconnect decision helpers (host UI renders the outcome).\nexport {\n decideReconnect,\n decideConnectButtonAction,\n type ReconnectDecision,\n type ReconnectDecisionInput,\n type ConnectButtonAction,\n} from \"./services/ConnectionCoordinator\"\n\n// OTA read-model types for host OTA UI (progress screen, error mapping,\n// progress section) — the check/install machinery itself is internal.\nexport type {\n VersionInfo,\n MtkPatch,\n BesFirmware,\n VersionJson,\n OtaCheckResult,\n OtaCheckCurrentGlassesResult,\n OtaCheckCurrentGlassesOptions,\n} from \"./services/OtaUpdateCheckService\"\n// OTA install policy (watchdog timings + failure copy) + display-state\n// derivation, consumed by the OTA screens and their tests.\nexport {\n MINIMUM_OTA_STATUS_BUILD,\n MAX_RETRIES,\n RETRY_INTERVAL_MS,\n PROGRESS_TIMEOUT_MS,\n DOWNLOAD_STUCK_TIMEOUT_MS,\n MTK_INSTALL_TIMEOUT_MS,\n GLOBAL_OTA_TIMEOUT_MS,\n PING_INTERVAL_MS,\n QUERY_REPLY_TIMEOUT_MS,\n BES_RESTART_TIMEOUT_MS,\n OtaProgressMessages,\n} from \"./services/otaInstallPolicy\"\nexport {deriveDisplayState} from \"./services/otaDisplayState\"\nexport type {DisplayState} from \"./services/otaDisplayState\"\nexport type {\n OtaProgress,\n OtaProgressStatus,\n OtaStatus,\n OtaUpdateInfo,\n ReleaseChangelog,\n OtaSnapshot,\n OtaInstallSnapshot,\n} from \"./facades/ota\"\nexport {\n beginOtaAutoChain,\n clearOtaAutoChainReconnectWait,\n isOtaAutoChainActive,\n otaAutoChainFingerprint,\n otaAutoChainReconnectWaitRemaining,\n stopOtaAutoChain,\n tryAdvanceOtaAutoChain,\n MAX_OTA_AUTO_CHAIN_PASSES,\n OTA_AUTO_CHAIN_RECONNECT_TIMEOUT_MS,\n} from \"./services/OtaAutoChain\"\nexport type {OtaAutoChainAdvanceResult} from \"./services/OtaAutoChain\"\nexport {\n BES_INSTALL_RESTART_MESSAGE,\n getOtaErrorMessage,\n shouldRequireGlassesRebootForBesFailure,\n shouldShowChangeWifiForOtaDownloadFailure,\n} from \"./services/OtaErrorMapping\"\n\n// Gallery read models: engine.gallery.onNotice payload types, the media\n// permission helper + display-name derivation host gallery UI uses, and the\n// glasses-camera DTO types (re-exported through the host @/types/asg shim).\nexport type {GalleryNotice, GalleryNoticeCode} from \"./services/asg/galleryNotices\"\nexport {MediaLibraryPermissions} from \"./utils/permissions/MediaLibraryPermissions\"\nexport {deriveGalleryDisplayName} from \"./utils/permissions/galleryDisplayName\"\nexport type {\n PhotoInfo,\n CaptureFile,\n CaptureGroup,\n GalleryResponse,\n ServerStatus,\n HealthResponse,\n GalleryEvent,\n} from \"./types/asg\"\n\n// Bluetooth SDK event types host UI subscribes to via engine facades (the\n// BluetoothSdk singleton passthrough itself is internal).\nexport type {PairFailureEvent, GlassesNotReadyEvent} from \"@glassly/bluetooth-sdk\"\n\n// Cloud connection status enum (read model; the connection store is internal).\nexport {WebSocketStatus} from \"./stores/connection\"\n\n// App-list hook layer + pure list helpers (the raw useAppStatusStore and\n// installAppStoreHooks wiring are internal).\nexport {\n DUMMY_APPLET,\n saveAppsOrder,\n getAppsOrder,\n sortAppsByPackageNamePriority,\n saveLastOpenTime,\n getLastOpenTime,\n sortAppsByLastOpenTime,\n useApps,\n useStart,\n useStop,\n useSetForeground,\n useClearForeground,\n useRefresh,\n useStopAll,\n useInstall,\n useUninstall,\n useActiveApps,\n useRunningAlwaysOnApps,\n useActiveBackgroundApps,\n useBackgroundApps,\n useActiveForegroundApp,\n useForegroundApp,\n useActiveBackgroundAppsCount,\n useLocalMiniApps,\n type StartOptions,\n type OrderMap,\n} from \"./stores/apps\"\n\n// Pure dev-miniapp launch-route decision (registration itself is internal).\nexport {\n decideDevLaunchRoute,\n type DecideDevLaunchOptions,\n type DevLaunchResult,\n type DevManifest,\n} from \"./utils/devMiniappLaunch\"\nexport {HardwareCompatibility, type CompatibilityResult} from \"./utils/hardware\"\nexport {BgTimer, throttle, debounce} from \"./utils/timers\"\n\n// Hardware types and capability profiles.\nexport {\n HardwareType,\n HardwareRequirementLevel,\n DeviceTypes,\n ControllerTypes,\n HARDWARE_CAPABILITIES,\n getModelCapabilities,\n simulatedGlasses,\n evenRealitiesG1,\n evenRealitiesG2,\n mentraLive,\n nimo,\n rayneoIO,\n vuzixZ100,\n mentraDisplay,\n} from \"./types\"\nexport type {\n HardwareRequirement,\n CameraCapabilities,\n DisplayCapabilities,\n MicrophoneCapabilities,\n SpeakerCapabilities,\n IMUCapabilities,\n ButtonCapabilities,\n LightCapabilities,\n PowerCapabilities,\n Capabilities,\n AppletType,\n AppPermissionType,\n AppletPermission,\n AppletInterface,\n ClientApp,\n} from \"./types\"\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"DisplayProcessor.d.ts","sourceRoot":"","sources":["../../src/services/DisplayProcessor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DisplayProcessor.d.ts","sourceRoot":"","sources":["../../src/services/DisplayProcessor.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@
12
12
  *
13
13
  * @see notes/miniapp-display-api-redesign.md for the current display design
14
14
  */
15
- import { createDisplayToolkit, G1_PROFILE, G2_PROFILE, Z100_PROFILE, NEX_PROFILE, ColumnComposer, } from "../utils/display";
15
+ import { createDisplayToolkit, G1_PROFILE, G2_PROFILE, Z100_PROFILE, NEX_PROFILE, RAYNEO_IO_PROFILE, ColumnComposer, } from "../utils/display";
16
16
  import { ISLAND_SETTINGS_KEYS } from "../runtime/config";
17
17
  import { useGlassesStore } from "../stores/glasses";
18
18
  import { useSettingsStore } from "../stores/settings";
@@ -79,6 +79,7 @@ const DEVICE_PROFILES = {
79
79
  [DeviceTypes.Z100]: Z100_PROFILE,
80
80
  [DeviceTypes.NEX]: NEX_PROFILE,
81
81
  [DeviceTypes.MACH1]: Z100_PROFILE, // Mach1 uses same hardware as Vuzix Z100
82
+ [DeviceTypes.RAYNEO_IO]: RAYNEO_IO_PROFILE,
82
83
  };
83
84
  // =============================================================================
84
85
  // DisplayProcessor Class
@@ -1 +1 @@
1
- {"version":3,"file":"DisplayProcessor.js","sourceRoot":"","sources":["../../src/services/DisplayProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * DisplayProcessor\n *\n * Processes display events with pixel-accurate text wrapping using the same\n * Engine display utilities. This ensures the mobile preview matches exactly\n * what is shown on the glasses.\n *\n * Key responsibilities:\n * 1. Intercept display events before sending to native SGC\n * 2. Wrap text using the correct device profile (G1, etc.)\n * 3. Ensure GlassesDisplayMirror shows exactly what glasses will show\n *\n * @see notes/miniapp-display-api-redesign.md for the current display design\n */\n\nimport {\n createDisplayToolkit,\n G1_PROFILE,\n G2_PROFILE,\n Z100_PROFILE,\n NEX_PROFILE,\n TextMeasurer,\n TextWrapper,\n ColumnComposer,\n type DisplayProfile,\n type WrapOptions,\n type BreakMode,\n} from \"../utils/display\"\n\nimport {ISLAND_SETTINGS_KEYS} from \"../runtime/config\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {useSettingsStore} from \"../stores/settings\"\nimport {DeviceTypes} from \"../types/enums\"\nimport {isGlassesConnected} from \"./GlassesReadiness\"\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Display event types that we process\n */\nexport type DisplayLayoutType =\n | \"text_wall\"\n | \"text_line\"\n | \"text_rows\"\n | \"reference_card\"\n | \"double_text_wall\"\n | \"bitmap_view\"\n\n/**\n * Raw display event from the cloud/WebSocket\n */\nexport interface DisplayEvent {\n view: \"main\" | \"dashboard\"\n layoutType?: DisplayLayoutType\n layout?: {\n layoutType: DisplayLayoutType\n text?: string | string[] // string for text_wall/text_line, string[] for text_rows\n title?: string\n topText?: string\n bottomText?: string\n breakMode?: BreakMode\n data?: string // For bitmap_view\n x?: number // bitmap_view container position/size (forwarded to native, used by G2)\n y?: number\n width?: number\n height?: number\n [key: string]: unknown\n }\n text?: string | string[]\n title?: string\n topText?: string\n bottomText?: string\n breakMode?: BreakMode\n [key: string]: unknown\n}\n\n/**\n * Processed display event with guaranteed wrapped text\n */\nexport interface ProcessedDisplayEvent extends DisplayEvent {\n /** Marks this event as processed */\n _processed: true\n /** The device profile used for processing */\n _profile: string\n /** Pre-split lines for text_wall/text_line (for easy rendering) */\n _lines?: string[]\n /** Original layout type before processing (e.g., double_text_wall -> text_wall) */\n _originalLayoutType?: DisplayLayoutType\n /** Column composition metadata for double_text_wall */\n _composedColumns?: {\n leftLines: string[]\n rightLines: string[]\n config: {\n leftColumnWidthPx: number\n rightColumnStartPx: number\n rightColumnWidthPx: number\n maxLines: number\n leftMarginSpaces?: number\n }\n }\n}\n\n/**\n * Options for the DisplayProcessor\n */\nexport interface DisplayProcessorOptions {\n /** Default break mode for text wrapping */\n breakMode?: BreakMode\n /** Whether to log processing details */\n debug?: boolean\n}\n\n// =============================================================================\n// Placeholder Replacement\n// =============================================================================\n\n/**\n * Placeholder values that can be replaced in display text.\n * These match the placeholders used in CoreManager.kt/CoreManager.swift\n */\ninterface PlaceholderValues {\n /** Current time in 12-hour format (e.g., \"2:30 PM\") */\n TIME12: string\n /** Current time in 24-hour format (e.g., \"14:30\") */\n TIME24: string\n /** Current date (e.g., \"1/22\") */\n DATE: string\n /** Glasses battery level (e.g., \"85%\" or \"\" if unknown) */\n GBATT: string\n /** Connection status */\n CONNECTION_STATUS: string\n}\n\n/**\n * Get current placeholder values from device state\n */\nfunction getPlaceholderValues(): PlaceholderValues {\n const now = new Date()\n\n // Format time in 12-hour format\n const hours12 = now.getHours() % 12 || 12\n const minutes = now.getMinutes().toString().padStart(2, \"0\")\n const ampm = now.getHours() >= 12 ? \"PM\" : \"AM\"\n const TIME12 = `${hours12}:${minutes} ${ampm}`\n\n // Format time in 24-hour format\n const hours24 = now.getHours().toString().padStart(2, \"0\")\n const TIME24 = `${hours24}:${minutes}`\n\n // Format date\n const month = now.getMonth() + 1\n const day = now.getDate()\n const DATE = `${month}/${day}`\n\n // Battery + connection read from the engine glasses store directly (was a host\n // glassesStatus hook).\n const batteryLevel = useGlassesStore.getState().batteryLevel ?? -1\n const GBATT = batteryLevel === -1 ? \"\" : `${batteryLevel}%`\n\n // Connection status\n const connected = isGlassesConnected(useGlassesStore.getState().connection)\n const CONNECTION_STATUS = connected ? \"Connected\" : \"\"\n\n return {TIME12, TIME24, DATE, GBATT, CONNECTION_STATUS}\n}\n\n/**\n * Replace placeholders in text with actual values.\n * Placeholders are in format $NAME$ (e.g., $GBATT$, $TIME12$)\n *\n * @param text - Text containing placeholders\n * @returns Text with placeholders replaced\n */\nfunction replacePlaceholders(text: string): string {\n if (!text || !text.includes(\"$\")) {\n return text\n }\n\n const values = getPlaceholderValues()\n\n return text\n .replace(/\\$TIME12\\$/g, values.TIME12)\n .replace(/\\$TIME24\\$/g, values.TIME24)\n .replace(/\\$DATE\\$/g, values.DATE)\n .replace(/\\$GBATT\\$/g, values.GBATT)\n .replace(/\\$CONNECTION_STATUS\\$/g, values.CONNECTION_STATUS)\n .replace(/\\$no_datetime\\$/g, `${values.DATE}, ${values.TIME12}`)\n}\n\nfunction isBreakMode(value: unknown): value is BreakMode {\n return value === \"character\" || value === \"character-no-hyphen\" || value === \"word\" || value === \"strict-word\"\n}\n\n// =============================================================================\n// Device Profile Mapping\n// =============================================================================\n\n/**\n * Map device model names to display profiles\n */\nconst DEVICE_PROFILES: Partial<Record<DeviceTypes, DisplayProfile>> = {\n [DeviceTypes.G1]: G1_PROFILE,\n [DeviceTypes.G2]: G2_PROFILE,\n [DeviceTypes.Z100]: Z100_PROFILE,\n [DeviceTypes.NEX]: NEX_PROFILE,\n [DeviceTypes.MACH1]: Z100_PROFILE, // Mach1 uses same hardware as Vuzix Z100\n}\n\n// =============================================================================\n// DisplayProcessor Class\n// =============================================================================\n\n/**\n * Processes display events with pixel-accurate text wrapping.\n *\n * Usage:\n * ```typescript\n * const processor = DisplayProcessor.getInstance()\n *\n * // When glasses connect\n * processor.setDeviceModel(DeviceTypes.G1)\n *\n * // Process display events\n * const processed = processor.processDisplayEvent(rawEvent)\n * ```\n */\nexport class DisplayProcessor {\n private static instance: DisplayProcessor | null = null\n\n private measurer: TextMeasurer\n private wrapper: TextWrapper\n private composer: ColumnComposer\n private profile: DisplayProfile\n private deviceModel: DeviceTypes = DeviceTypes.NONE\n private options: DisplayProcessorOptions\n\n private runtimeAttached = false\n private unsubscribeGlassesStatus: (() => void) | null = null\n\n private constructor(options: DisplayProcessorOptions = {}) {\n this.options = {\n breakMode: \"character-no-hyphen\",\n debug: false,\n ...options,\n }\n\n // Initialize with default G1 profile\n const engine = createDisplayToolkit(G1_PROFILE, {\n breakMode: this.options.breakMode,\n })\n\n this.measurer = engine.measurer\n this.wrapper = engine.wrapper\n this.composer = new ColumnComposer(engine.profile, this.options.breakMode)\n this.profile = engine.profile\n\n // Engine stores may not be hydrated yet at module-load time; attachToRuntime()\n // is called again by the host after app services start.\n this.attachToRuntime()\n }\n\n /**\n * Read the current default wearable and subscribe to engine glasses-status changes.\n * Idempotent — safe to call again after app services start.\n */\n public attachToRuntime(): void {\n if (this.runtimeAttached) {\n return\n }\n\n // Seed the device profile from the saved default wearable, read off the engine\n // settings store directly (was a host settings hook).\n const defaultWearable = useSettingsStore.getState().getSetting(ISLAND_SETTINGS_KEYS.defaultWearable) as\n | string\n | undefined\n if (defaultWearable) {\n this.setDeviceModel(defaultWearable)\n console.log(`DISPLAY_PROCESSOR: Initialized DisplayProcessor with default wearable: ${defaultWearable}`)\n }\n\n // Track device-model changes off the engine glasses store directly (was a host\n // subscribeGlassesStatus hook).\n this.unsubscribeGlassesStatus = useGlassesStore.subscribe(\n (s) => s.deviceModel,\n (deviceModel) => {\n if (deviceModel) this.setDeviceModel(String(deviceModel))\n },\n )\n\n this.runtimeAttached = true\n }\n\n /** Detach runtime subscriptions installed by attachToRuntime(). */\n public detachFromRuntime(): void {\n this.unsubscribeGlassesStatus?.()\n this.unsubscribeGlassesStatus = null\n this.runtimeAttached = false\n }\n\n /**\n * Get the singleton instance\n */\n public static getInstance(options?: DisplayProcessorOptions): DisplayProcessor {\n if (!DisplayProcessor.instance) {\n DisplayProcessor.instance = new DisplayProcessor(options)\n }\n return DisplayProcessor.instance\n }\n\n /**\n * Reset the singleton (useful for testing)\n */\n public static resetInstance(): void {\n DisplayProcessor.instance?.detachFromRuntime()\n DisplayProcessor.instance = null\n }\n\n // ===========================================================================\n // Device Profile Management\n // ===========================================================================\n\n /**\n * Set the device model and update the display profile accordingly.\n * Call this when glasses connect.\n *\n * @param modelName - The model name from the connected glasses (e.g., \"Even Realities G1\")\n */\n public setDeviceModel(modelName: string | null | undefined): void {\n const model = Object.values(DeviceTypes).find((deviceType) => deviceType === modelName) ?? DeviceTypes.NONE\n\n if (model === this.deviceModel) {\n return // No change needed\n }\n\n this.deviceModel = model\n const newProfile = DEVICE_PROFILES[model] ?? G1_PROFILE\n\n if (newProfile !== this.profile) {\n this.updateProfile(newProfile)\n }\n\n if (this.options.debug) {\n console.log(`[DisplayProcessor] Device model set to: ${model} (from: ${modelName})`)\n }\n }\n\n /**\n * Update the display profile and recreate engine\n */\n private updateProfile(newProfile: DisplayProfile): void {\n const engine = createDisplayToolkit(newProfile, {\n breakMode: this.options.breakMode,\n })\n\n this.measurer = engine.measurer\n this.wrapper = engine.wrapper\n this.composer = new ColumnComposer(newProfile, this.options.breakMode)\n this.profile = engine.profile\n\n if (this.options.debug) {\n console.log(`[DisplayProcessor] Profile updated to: ${newProfile.id}`)\n }\n }\n\n /**\n * Get the current device model\n */\n public getDeviceModel(): DeviceTypes {\n return this.deviceModel\n }\n\n /**\n * Get the current display profile\n */\n public getProfile(): DisplayProfile {\n return this.profile\n }\n\n // ===========================================================================\n // Display Event Processing\n // ===========================================================================\n\n /**\n * Process a display event, wrapping text as needed.\n *\n * @param event - Raw display event from WebSocket\n * @returns Processed event with wrapped text\n */\n public processDisplayEvent(event: DisplayEvent): ProcessedDisplayEvent {\n // Already processed? Return as-is\n if ((event as ProcessedDisplayEvent)._processed) {\n return event as ProcessedDisplayEvent\n }\n\n // Get layout type from either root or nested layout object\n const layoutType = event.layoutType || event.layout?.layoutType\n const layout = event.layout || event\n\n if (!layoutType) {\n // No layout type - pass through\n return {\n ...event,\n _processed: true,\n _profile: this.profile.id,\n }\n }\n\n switch (layoutType) {\n case \"text_wall\":\n case \"text_line\":\n return this.processTextWall(event, layout)\n\n case \"text_rows\":\n return this.processTextRows(event, layout)\n\n case \"reference_card\":\n return this.processReferenceCard(event, layout)\n\n case \"double_text_wall\":\n return this.processDoubleTextWall(event, layout)\n\n case \"bitmap_view\":\n // Bitmap views don't need text processing\n return {\n ...event,\n _processed: true,\n _profile: this.profile.id,\n }\n\n default:\n // Unknown layout type - pass through\n if (this.options.debug) {\n console.log(`[DisplayProcessor] Unknown layout type: ${layoutType}`)\n }\n return {\n ...event,\n _processed: true,\n _profile: this.profile.id,\n }\n }\n }\n\n /**\n * Process text_wall or text_line layout\n */\n private processTextWall(\n event: DisplayEvent,\n layout: DisplayEvent | NonNullable<DisplayEvent[\"layout\"]>,\n ): ProcessedDisplayEvent {\n // text_wall/text_line always have string text, not string[]\n const rawText = layout.text\n const text = typeof rawText === \"string\" ? rawText : \"\"\n\n // Replace placeholders BEFORE wrapping (so we measure actual content)\n const textWithPlaceholders = replacePlaceholders(text)\n const breakMode = this.getEventBreakMode(event, layout)\n\n // Wrap the text\n const lines = this.wrapText(textWithPlaceholders, breakMode ? {breakMode} : undefined)\n const wrappedText = lines.join(\"\\n\")\n\n // Update both root and nested layout if present\n const processedLayout = event.layout\n ? {\n ...event.layout,\n text: wrappedText,\n }\n : undefined\n\n return {\n ...event,\n // Store original text with placeholders for debugging\n _originalText: text,\n text: wrappedText,\n layout: processedLayout,\n _processed: true,\n _profile: this.profile.id,\n _lines: lines,\n }\n }\n\n /**\n * Process text_rows layout\n */\n private processTextRows(\n event: DisplayEvent,\n layout: DisplayEvent | NonNullable<DisplayEvent[\"layout\"]>,\n ): ProcessedDisplayEvent {\n const textField = layout.text\n const rows: string[] = Array.isArray(textField) ? textField : []\n\n // Replace placeholders and wrap each row\n const breakMode = this.getEventBreakMode(event, layout)\n const wrappedRows = rows.map((row: string) => {\n const rowWithPlaceholders = replacePlaceholders(row)\n const lines = this.wrapText(rowWithPlaceholders, breakMode ? {breakMode} : undefined)\n return lines.join(\"\\n\")\n })\n\n const processedLayout = event.layout\n ? {\n ...event.layout,\n text: wrappedRows as string | string[],\n }\n : undefined\n\n return {\n ...event,\n text: wrappedRows as string | string[],\n layout: processedLayout,\n _processed: true,\n _profile: this.profile.id,\n }\n }\n\n /**\n * Process reference_card layout\n */\n private processReferenceCard(\n event: DisplayEvent,\n layout: DisplayEvent | NonNullable<DisplayEvent[\"layout\"]>,\n ): ProcessedDisplayEvent {\n const title = layout.title || \"\"\n // reference_card text is always string, not string[]\n const rawText = layout.text\n const text = typeof rawText === \"string\" ? rawText : \"\"\n\n // Replace placeholders BEFORE wrapping\n const titleWithPlaceholders = replacePlaceholders(title)\n const textWithPlaceholders = replacePlaceholders(text)\n const breakMode = this.getEventBreakMode(event, layout)\n\n // Wrap title and text separately\n // Title typically gets 1 line, text gets remaining lines\n const wrappedTitle = this.wrapText(titleWithPlaceholders, {maxLines: 1, ...(breakMode ? {breakMode} : {})})\n const wrappedText = this.wrapText(textWithPlaceholders, {\n maxLines: this.profile.maxLines - 1,\n ...(breakMode ? {breakMode} : {}),\n })\n\n const processedLayout = event.layout\n ? {\n ...event.layout,\n title: wrappedTitle.join(\"\\n\"),\n text: wrappedText.join(\"\\n\"),\n }\n : undefined\n\n return {\n ...event,\n title: wrappedTitle.join(\"\\n\"),\n text: wrappedText.join(\"\\n\"),\n layout: processedLayout,\n _processed: true,\n _profile: this.profile.id,\n }\n }\n\n /**\n * Process double_text_wall layout\n *\n * Uses ColumnComposer to create a fully composed string with both columns\n * merged line-by-line with pixel-precise space alignment. This is the single\n * source of truth for double_text_wall composition, replacing duplicate\n * implementations in native iOS (G1Text.swift) and Android (G1Text.kt).\n *\n * The composed text is sent to native as a regular text_wall - native just\n * chunks and sends it without any re-wrapping or column composition.\n */\n private processDoubleTextWall(\n event: DisplayEvent,\n layout: DisplayEvent | NonNullable<DisplayEvent[\"layout\"]>,\n ): ProcessedDisplayEvent {\n const leftText = layout.topText || \"\"\n const rightText = layout.bottomText || \"\"\n\n // Replace placeholders BEFORE composition (so we measure actual content)\n const leftTextWithPlaceholders = replacePlaceholders(leftText)\n const rightTextWithPlaceholders = replacePlaceholders(rightText)\n const breakMode = this.getEventBreakMode(event, layout)\n const composer =\n breakMode && breakMode !== this.options.breakMode ? new ColumnComposer(this.profile, breakMode) : this.composer\n\n // Use ColumnComposer for pixel-precise column composition\n const result = composer.composeDoubleTextWall(leftTextWithPlaceholders, rightTextWithPlaceholders)\n\n if (this.options.debug) {\n console.log(`[DisplayProcessor] double_text_wall composed:`)\n console.log(` Left lines: ${result.leftLines.length}`)\n console.log(` Right lines: ${result.rightLines.length}`)\n console.log(` Config: ${JSON.stringify(result.config)}`)\n }\n\n // The composed text is a single string with both columns merged\n // Native will receive this as a text_wall and just chunk & send it\n const processedLayout = event.layout\n ? {\n ...event.layout,\n // Keep original topText/bottomText for reference but add composed text\n topText: leftTextWithPlaceholders,\n bottomText: rightTextWithPlaceholders,\n // The composed text is what native should actually display\n _composedText: result.composedText,\n }\n : undefined\n\n return {\n ...event,\n // Override the layout type to text_wall since we've pre-composed the columns\n // This tells native to use sendTextWall instead of sendDoubleTextWall\n layoutType: \"text_wall\" as DisplayLayoutType,\n text: result.composedText,\n // Keep original values for debugging/preview (with placeholders replaced)\n topText: leftTextWithPlaceholders,\n bottomText: rightTextWithPlaceholders,\n // Store original values with placeholders for debugging\n _originalTopText: leftText,\n _originalBottomText: rightText,\n layout: processedLayout\n ? {\n ...processedLayout,\n layoutType: \"text_wall\" as DisplayLayoutType,\n text: result.composedText,\n }\n : undefined,\n _processed: true,\n _profile: this.profile.id,\n _originalLayoutType: \"double_text_wall\",\n _composedColumns: {\n leftLines: result.leftLines,\n rightLines: result.rightLines,\n config: result.config,\n },\n }\n }\n\n // ===========================================================================\n // Text Wrapping Utilities\n // ===========================================================================\n\n /**\n * Wrap text using the current profile\n *\n * @param text - Text to wrap\n * @param options - Optional override options\n * @returns Array of wrapped lines\n */\n public wrapText(text: string, options?: WrapOptions): string[] {\n if (!text) return [\"\"]\n\n const result = this.wrapper.wrap(text, options)\n return result.lines\n }\n\n private getEventBreakMode(\n event: DisplayEvent,\n layout: DisplayEvent | NonNullable<DisplayEvent[\"layout\"]>,\n ): BreakMode | undefined {\n const breakMode = layout.breakMode ?? event.breakMode\n return isBreakMode(breakMode) ? breakMode : undefined\n }\n\n /**\n * Measure the pixel width of text\n *\n * @param text - Text to measure\n * @returns Width in pixels\n */\n public measureText(text: string): number {\n return this.measurer.measureText(text)\n }\n\n /** Rendered advance of one character on the current device's font, in canvas px. */\n public measureChar(char: string): number {\n return this.measurer.measureChar(char)\n }\n\n /**\n * Check if text fits on a single line\n *\n * @param text - Text to check\n * @returns true if text fits without wrapping\n */\n public fitsOnSingleLine(text: string): boolean {\n return this.measurer.measureText(text) <= this.profile.displayWidthPx\n }\n\n /**\n * Get the display width in pixels\n */\n public getDisplayWidth(): number {\n return this.profile.displayWidthPx\n }\n\n /**\n * Get the maximum number of lines\n */\n public getMaxLines(): number {\n return this.profile.maxLines\n }\n\n /**\n * Get detailed text measurement\n */\n public measureTextDetailed(text: string) {\n return this.measurer.measureTextDetailed(text)\n }\n\n // ===========================================================================\n // Break Mode Control\n // ===========================================================================\n\n /**\n * Set the break mode for text wrapping\n *\n * @param breakMode - 'character' | 'word' | 'strict-word'\n */\n public setBreakMode(breakMode: BreakMode): void {\n if (this.options.breakMode === breakMode) return\n\n this.options.breakMode = breakMode\n this.updateProfile(this.profile) // Recreate wrapper with new break mode\n\n if (this.options.debug) {\n console.log(`[DisplayProcessor] Break mode set to: ${breakMode}`)\n }\n }\n\n /**\n * Get the current break mode\n */\n public getBreakMode(): BreakMode {\n return this.options.breakMode || \"character\"\n }\n}\n\nexport const displayProcessor = DisplayProcessor.getInstance()\nexport default displayProcessor\n"]}
1
+ {"version":3,"file":"DisplayProcessor.js","sourceRoot":"","sources":["../../src/services/DisplayProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * DisplayProcessor\n *\n * Processes display events with pixel-accurate text wrapping using the same\n * Engine display utilities. This ensures the mobile preview matches exactly\n * what is shown on the glasses.\n *\n * Key responsibilities:\n * 1. Intercept display events before sending to native SGC\n * 2. Wrap text using the correct device profile (G1, etc.)\n * 3. Ensure GlassesDisplayMirror shows exactly what glasses will show\n *\n * @see notes/miniapp-display-api-redesign.md for the current display design\n */\n\nimport {\n createDisplayToolkit,\n G1_PROFILE,\n G2_PROFILE,\n Z100_PROFILE,\n NEX_PROFILE,\n RAYNEO_IO_PROFILE,\n TextMeasurer,\n TextWrapper,\n ColumnComposer,\n type DisplayProfile,\n type WrapOptions,\n type BreakMode,\n} from \"../utils/display\"\n\nimport {ISLAND_SETTINGS_KEYS} from \"../runtime/config\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {useSettingsStore} from \"../stores/settings\"\nimport {DeviceTypes} from \"../types/enums\"\nimport {isGlassesConnected} from \"./GlassesReadiness\"\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Display event types that we process\n */\nexport type DisplayLayoutType =\n | \"text_wall\"\n | \"text_line\"\n | \"text_rows\"\n | \"reference_card\"\n | \"double_text_wall\"\n | \"bitmap_view\"\n\n/**\n * Raw display event from the cloud/WebSocket\n */\nexport interface DisplayEvent {\n view: \"main\" | \"dashboard\"\n layoutType?: DisplayLayoutType\n layout?: {\n layoutType: DisplayLayoutType\n text?: string | string[] // string for text_wall/text_line, string[] for text_rows\n title?: string\n topText?: string\n bottomText?: string\n breakMode?: BreakMode\n data?: string // For bitmap_view\n x?: number // bitmap_view container position/size (forwarded to native, used by G2)\n y?: number\n width?: number\n height?: number\n [key: string]: unknown\n }\n text?: string | string[]\n title?: string\n topText?: string\n bottomText?: string\n breakMode?: BreakMode\n [key: string]: unknown\n}\n\n/**\n * Processed display event with guaranteed wrapped text\n */\nexport interface ProcessedDisplayEvent extends DisplayEvent {\n /** Marks this event as processed */\n _processed: true\n /** The device profile used for processing */\n _profile: string\n /** Pre-split lines for text_wall/text_line (for easy rendering) */\n _lines?: string[]\n /** Original layout type before processing (e.g., double_text_wall -> text_wall) */\n _originalLayoutType?: DisplayLayoutType\n /** Column composition metadata for double_text_wall */\n _composedColumns?: {\n leftLines: string[]\n rightLines: string[]\n config: {\n leftColumnWidthPx: number\n rightColumnStartPx: number\n rightColumnWidthPx: number\n maxLines: number\n leftMarginSpaces?: number\n }\n }\n}\n\n/**\n * Options for the DisplayProcessor\n */\nexport interface DisplayProcessorOptions {\n /** Default break mode for text wrapping */\n breakMode?: BreakMode\n /** Whether to log processing details */\n debug?: boolean\n}\n\n// =============================================================================\n// Placeholder Replacement\n// =============================================================================\n\n/**\n * Placeholder values that can be replaced in display text.\n * These match the placeholders used in CoreManager.kt/CoreManager.swift\n */\ninterface PlaceholderValues {\n /** Current time in 12-hour format (e.g., \"2:30 PM\") */\n TIME12: string\n /** Current time in 24-hour format (e.g., \"14:30\") */\n TIME24: string\n /** Current date (e.g., \"1/22\") */\n DATE: string\n /** Glasses battery level (e.g., \"85%\" or \"\" if unknown) */\n GBATT: string\n /** Connection status */\n CONNECTION_STATUS: string\n}\n\n/**\n * Get current placeholder values from device state\n */\nfunction getPlaceholderValues(): PlaceholderValues {\n const now = new Date()\n\n // Format time in 12-hour format\n const hours12 = now.getHours() % 12 || 12\n const minutes = now.getMinutes().toString().padStart(2, \"0\")\n const ampm = now.getHours() >= 12 ? \"PM\" : \"AM\"\n const TIME12 = `${hours12}:${minutes} ${ampm}`\n\n // Format time in 24-hour format\n const hours24 = now.getHours().toString().padStart(2, \"0\")\n const TIME24 = `${hours24}:${minutes}`\n\n // Format date\n const month = now.getMonth() + 1\n const day = now.getDate()\n const DATE = `${month}/${day}`\n\n // Battery + connection read from the engine glasses store directly (was a host\n // glassesStatus hook).\n const batteryLevel = useGlassesStore.getState().batteryLevel ?? -1\n const GBATT = batteryLevel === -1 ? \"\" : `${batteryLevel}%`\n\n // Connection status\n const connected = isGlassesConnected(useGlassesStore.getState().connection)\n const CONNECTION_STATUS = connected ? \"Connected\" : \"\"\n\n return {TIME12, TIME24, DATE, GBATT, CONNECTION_STATUS}\n}\n\n/**\n * Replace placeholders in text with actual values.\n * Placeholders are in format $NAME$ (e.g., $GBATT$, $TIME12$)\n *\n * @param text - Text containing placeholders\n * @returns Text with placeholders replaced\n */\nfunction replacePlaceholders(text: string): string {\n if (!text || !text.includes(\"$\")) {\n return text\n }\n\n const values = getPlaceholderValues()\n\n return text\n .replace(/\\$TIME12\\$/g, values.TIME12)\n .replace(/\\$TIME24\\$/g, values.TIME24)\n .replace(/\\$DATE\\$/g, values.DATE)\n .replace(/\\$GBATT\\$/g, values.GBATT)\n .replace(/\\$CONNECTION_STATUS\\$/g, values.CONNECTION_STATUS)\n .replace(/\\$no_datetime\\$/g, `${values.DATE}, ${values.TIME12}`)\n}\n\nfunction isBreakMode(value: unknown): value is BreakMode {\n return value === \"character\" || value === \"character-no-hyphen\" || value === \"word\" || value === \"strict-word\"\n}\n\n// =============================================================================\n// Device Profile Mapping\n// =============================================================================\n\n/**\n * Map device model names to display profiles\n */\nconst DEVICE_PROFILES: Partial<Record<DeviceTypes, DisplayProfile>> = {\n [DeviceTypes.G1]: G1_PROFILE,\n [DeviceTypes.G2]: G2_PROFILE,\n [DeviceTypes.Z100]: Z100_PROFILE,\n [DeviceTypes.NEX]: NEX_PROFILE,\n [DeviceTypes.MACH1]: Z100_PROFILE, // Mach1 uses same hardware as Vuzix Z100\n [DeviceTypes.RAYNEO_IO]: RAYNEO_IO_PROFILE,\n}\n\n// =============================================================================\n// DisplayProcessor Class\n// =============================================================================\n\n/**\n * Processes display events with pixel-accurate text wrapping.\n *\n * Usage:\n * ```typescript\n * const processor = DisplayProcessor.getInstance()\n *\n * // When glasses connect\n * processor.setDeviceModel(DeviceTypes.G1)\n *\n * // Process display events\n * const processed = processor.processDisplayEvent(rawEvent)\n * ```\n */\nexport class DisplayProcessor {\n private static instance: DisplayProcessor | null = null\n\n private measurer: TextMeasurer\n private wrapper: TextWrapper\n private composer: ColumnComposer\n private profile: DisplayProfile\n private deviceModel: DeviceTypes = DeviceTypes.NONE\n private options: DisplayProcessorOptions\n\n private runtimeAttached = false\n private unsubscribeGlassesStatus: (() => void) | null = null\n\n private constructor(options: DisplayProcessorOptions = {}) {\n this.options = {\n breakMode: \"character-no-hyphen\",\n debug: false,\n ...options,\n }\n\n // Initialize with default G1 profile\n const engine = createDisplayToolkit(G1_PROFILE, {\n breakMode: this.options.breakMode,\n })\n\n this.measurer = engine.measurer\n this.wrapper = engine.wrapper\n this.composer = new ColumnComposer(engine.profile, this.options.breakMode)\n this.profile = engine.profile\n\n // Engine stores may not be hydrated yet at module-load time; attachToRuntime()\n // is called again by the host after app services start.\n this.attachToRuntime()\n }\n\n /**\n * Read the current default wearable and subscribe to engine glasses-status changes.\n * Idempotent — safe to call again after app services start.\n */\n public attachToRuntime(): void {\n if (this.runtimeAttached) {\n return\n }\n\n // Seed the device profile from the saved default wearable, read off the engine\n // settings store directly (was a host settings hook).\n const defaultWearable = useSettingsStore.getState().getSetting(ISLAND_SETTINGS_KEYS.defaultWearable) as\n | string\n | undefined\n if (defaultWearable) {\n this.setDeviceModel(defaultWearable)\n console.log(`DISPLAY_PROCESSOR: Initialized DisplayProcessor with default wearable: ${defaultWearable}`)\n }\n\n // Track device-model changes off the engine glasses store directly (was a host\n // subscribeGlassesStatus hook).\n this.unsubscribeGlassesStatus = useGlassesStore.subscribe(\n (s) => s.deviceModel,\n (deviceModel) => {\n if (deviceModel) this.setDeviceModel(String(deviceModel))\n },\n )\n\n this.runtimeAttached = true\n }\n\n /** Detach runtime subscriptions installed by attachToRuntime(). */\n public detachFromRuntime(): void {\n this.unsubscribeGlassesStatus?.()\n this.unsubscribeGlassesStatus = null\n this.runtimeAttached = false\n }\n\n /**\n * Get the singleton instance\n */\n public static getInstance(options?: DisplayProcessorOptions): DisplayProcessor {\n if (!DisplayProcessor.instance) {\n DisplayProcessor.instance = new DisplayProcessor(options)\n }\n return DisplayProcessor.instance\n }\n\n /**\n * Reset the singleton (useful for testing)\n */\n public static resetInstance(): void {\n DisplayProcessor.instance?.detachFromRuntime()\n DisplayProcessor.instance = null\n }\n\n // ===========================================================================\n // Device Profile Management\n // ===========================================================================\n\n /**\n * Set the device model and update the display profile accordingly.\n * Call this when glasses connect.\n *\n * @param modelName - The model name from the connected glasses (e.g., \"Even Realities G1\")\n */\n public setDeviceModel(modelName: string | null | undefined): void {\n const model = Object.values(DeviceTypes).find((deviceType) => deviceType === modelName) ?? DeviceTypes.NONE\n\n if (model === this.deviceModel) {\n return // No change needed\n }\n\n this.deviceModel = model\n const newProfile = DEVICE_PROFILES[model] ?? G1_PROFILE\n\n if (newProfile !== this.profile) {\n this.updateProfile(newProfile)\n }\n\n if (this.options.debug) {\n console.log(`[DisplayProcessor] Device model set to: ${model} (from: ${modelName})`)\n }\n }\n\n /**\n * Update the display profile and recreate engine\n */\n private updateProfile(newProfile: DisplayProfile): void {\n const engine = createDisplayToolkit(newProfile, {\n breakMode: this.options.breakMode,\n })\n\n this.measurer = engine.measurer\n this.wrapper = engine.wrapper\n this.composer = new ColumnComposer(newProfile, this.options.breakMode)\n this.profile = engine.profile\n\n if (this.options.debug) {\n console.log(`[DisplayProcessor] Profile updated to: ${newProfile.id}`)\n }\n }\n\n /**\n * Get the current device model\n */\n public getDeviceModel(): DeviceTypes {\n return this.deviceModel\n }\n\n /**\n * Get the current display profile\n */\n public getProfile(): DisplayProfile {\n return this.profile\n }\n\n // ===========================================================================\n // Display Event Processing\n // ===========================================================================\n\n /**\n * Process a display event, wrapping text as needed.\n *\n * @param event - Raw display event from WebSocket\n * @returns Processed event with wrapped text\n */\n public processDisplayEvent(event: DisplayEvent): ProcessedDisplayEvent {\n // Already processed? Return as-is\n if ((event as ProcessedDisplayEvent)._processed) {\n return event as ProcessedDisplayEvent\n }\n\n // Get layout type from either root or nested layout object\n const layoutType = event.layoutType || event.layout?.layoutType\n const layout = event.layout || event\n\n if (!layoutType) {\n // No layout type - pass through\n return {\n ...event,\n _processed: true,\n _profile: this.profile.id,\n }\n }\n\n switch (layoutType) {\n case \"text_wall\":\n case \"text_line\":\n return this.processTextWall(event, layout)\n\n case \"text_rows\":\n return this.processTextRows(event, layout)\n\n case \"reference_card\":\n return this.processReferenceCard(event, layout)\n\n case \"double_text_wall\":\n return this.processDoubleTextWall(event, layout)\n\n case \"bitmap_view\":\n // Bitmap views don't need text processing\n return {\n ...event,\n _processed: true,\n _profile: this.profile.id,\n }\n\n default:\n // Unknown layout type - pass through\n if (this.options.debug) {\n console.log(`[DisplayProcessor] Unknown layout type: ${layoutType}`)\n }\n return {\n ...event,\n _processed: true,\n _profile: this.profile.id,\n }\n }\n }\n\n /**\n * Process text_wall or text_line layout\n */\n private processTextWall(\n event: DisplayEvent,\n layout: DisplayEvent | NonNullable<DisplayEvent[\"layout\"]>,\n ): ProcessedDisplayEvent {\n // text_wall/text_line always have string text, not string[]\n const rawText = layout.text\n const text = typeof rawText === \"string\" ? rawText : \"\"\n\n // Replace placeholders BEFORE wrapping (so we measure actual content)\n const textWithPlaceholders = replacePlaceholders(text)\n const breakMode = this.getEventBreakMode(event, layout)\n\n // Wrap the text\n const lines = this.wrapText(textWithPlaceholders, breakMode ? {breakMode} : undefined)\n const wrappedText = lines.join(\"\\n\")\n\n // Update both root and nested layout if present\n const processedLayout = event.layout\n ? {\n ...event.layout,\n text: wrappedText,\n }\n : undefined\n\n return {\n ...event,\n // Store original text with placeholders for debugging\n _originalText: text,\n text: wrappedText,\n layout: processedLayout,\n _processed: true,\n _profile: this.profile.id,\n _lines: lines,\n }\n }\n\n /**\n * Process text_rows layout\n */\n private processTextRows(\n event: DisplayEvent,\n layout: DisplayEvent | NonNullable<DisplayEvent[\"layout\"]>,\n ): ProcessedDisplayEvent {\n const textField = layout.text\n const rows: string[] = Array.isArray(textField) ? textField : []\n\n // Replace placeholders and wrap each row\n const breakMode = this.getEventBreakMode(event, layout)\n const wrappedRows = rows.map((row: string) => {\n const rowWithPlaceholders = replacePlaceholders(row)\n const lines = this.wrapText(rowWithPlaceholders, breakMode ? {breakMode} : undefined)\n return lines.join(\"\\n\")\n })\n\n const processedLayout = event.layout\n ? {\n ...event.layout,\n text: wrappedRows as string | string[],\n }\n : undefined\n\n return {\n ...event,\n text: wrappedRows as string | string[],\n layout: processedLayout,\n _processed: true,\n _profile: this.profile.id,\n }\n }\n\n /**\n * Process reference_card layout\n */\n private processReferenceCard(\n event: DisplayEvent,\n layout: DisplayEvent | NonNullable<DisplayEvent[\"layout\"]>,\n ): ProcessedDisplayEvent {\n const title = layout.title || \"\"\n // reference_card text is always string, not string[]\n const rawText = layout.text\n const text = typeof rawText === \"string\" ? rawText : \"\"\n\n // Replace placeholders BEFORE wrapping\n const titleWithPlaceholders = replacePlaceholders(title)\n const textWithPlaceholders = replacePlaceholders(text)\n const breakMode = this.getEventBreakMode(event, layout)\n\n // Wrap title and text separately\n // Title typically gets 1 line, text gets remaining lines\n const wrappedTitle = this.wrapText(titleWithPlaceholders, {maxLines: 1, ...(breakMode ? {breakMode} : {})})\n const wrappedText = this.wrapText(textWithPlaceholders, {\n maxLines: this.profile.maxLines - 1,\n ...(breakMode ? {breakMode} : {}),\n })\n\n const processedLayout = event.layout\n ? {\n ...event.layout,\n title: wrappedTitle.join(\"\\n\"),\n text: wrappedText.join(\"\\n\"),\n }\n : undefined\n\n return {\n ...event,\n title: wrappedTitle.join(\"\\n\"),\n text: wrappedText.join(\"\\n\"),\n layout: processedLayout,\n _processed: true,\n _profile: this.profile.id,\n }\n }\n\n /**\n * Process double_text_wall layout\n *\n * Uses ColumnComposer to create a fully composed string with both columns\n * merged line-by-line with pixel-precise space alignment. This is the single\n * source of truth for double_text_wall composition, replacing duplicate\n * implementations in native iOS (G1Text.swift) and Android (G1Text.kt).\n *\n * The composed text is sent to native as a regular text_wall - native just\n * chunks and sends it without any re-wrapping or column composition.\n */\n private processDoubleTextWall(\n event: DisplayEvent,\n layout: DisplayEvent | NonNullable<DisplayEvent[\"layout\"]>,\n ): ProcessedDisplayEvent {\n const leftText = layout.topText || \"\"\n const rightText = layout.bottomText || \"\"\n\n // Replace placeholders BEFORE composition (so we measure actual content)\n const leftTextWithPlaceholders = replacePlaceholders(leftText)\n const rightTextWithPlaceholders = replacePlaceholders(rightText)\n const breakMode = this.getEventBreakMode(event, layout)\n const composer =\n breakMode && breakMode !== this.options.breakMode ? new ColumnComposer(this.profile, breakMode) : this.composer\n\n // Use ColumnComposer for pixel-precise column composition\n const result = composer.composeDoubleTextWall(leftTextWithPlaceholders, rightTextWithPlaceholders)\n\n if (this.options.debug) {\n console.log(`[DisplayProcessor] double_text_wall composed:`)\n console.log(` Left lines: ${result.leftLines.length}`)\n console.log(` Right lines: ${result.rightLines.length}`)\n console.log(` Config: ${JSON.stringify(result.config)}`)\n }\n\n // The composed text is a single string with both columns merged\n // Native will receive this as a text_wall and just chunk & send it\n const processedLayout = event.layout\n ? {\n ...event.layout,\n // Keep original topText/bottomText for reference but add composed text\n topText: leftTextWithPlaceholders,\n bottomText: rightTextWithPlaceholders,\n // The composed text is what native should actually display\n _composedText: result.composedText,\n }\n : undefined\n\n return {\n ...event,\n // Override the layout type to text_wall since we've pre-composed the columns\n // This tells native to use sendTextWall instead of sendDoubleTextWall\n layoutType: \"text_wall\" as DisplayLayoutType,\n text: result.composedText,\n // Keep original values for debugging/preview (with placeholders replaced)\n topText: leftTextWithPlaceholders,\n bottomText: rightTextWithPlaceholders,\n // Store original values with placeholders for debugging\n _originalTopText: leftText,\n _originalBottomText: rightText,\n layout: processedLayout\n ? {\n ...processedLayout,\n layoutType: \"text_wall\" as DisplayLayoutType,\n text: result.composedText,\n }\n : undefined,\n _processed: true,\n _profile: this.profile.id,\n _originalLayoutType: \"double_text_wall\",\n _composedColumns: {\n leftLines: result.leftLines,\n rightLines: result.rightLines,\n config: result.config,\n },\n }\n }\n\n // ===========================================================================\n // Text Wrapping Utilities\n // ===========================================================================\n\n /**\n * Wrap text using the current profile\n *\n * @param text - Text to wrap\n * @param options - Optional override options\n * @returns Array of wrapped lines\n */\n public wrapText(text: string, options?: WrapOptions): string[] {\n if (!text) return [\"\"]\n\n const result = this.wrapper.wrap(text, options)\n return result.lines\n }\n\n private getEventBreakMode(\n event: DisplayEvent,\n layout: DisplayEvent | NonNullable<DisplayEvent[\"layout\"]>,\n ): BreakMode | undefined {\n const breakMode = layout.breakMode ?? event.breakMode\n return isBreakMode(breakMode) ? breakMode : undefined\n }\n\n /**\n * Measure the pixel width of text\n *\n * @param text - Text to measure\n * @returns Width in pixels\n */\n public measureText(text: string): number {\n return this.measurer.measureText(text)\n }\n\n /** Rendered advance of one character on the current device's font, in canvas px. */\n public measureChar(char: string): number {\n return this.measurer.measureChar(char)\n }\n\n /**\n * Check if text fits on a single line\n *\n * @param text - Text to check\n * @returns true if text fits without wrapping\n */\n public fitsOnSingleLine(text: string): boolean {\n return this.measurer.measureText(text) <= this.profile.displayWidthPx\n }\n\n /**\n * Get the display width in pixels\n */\n public getDisplayWidth(): number {\n return this.profile.displayWidthPx\n }\n\n /**\n * Get the maximum number of lines\n */\n public getMaxLines(): number {\n return this.profile.maxLines\n }\n\n /**\n * Get detailed text measurement\n */\n public measureTextDetailed(text: string) {\n return this.measurer.measureTextDetailed(text)\n }\n\n // ===========================================================================\n // Break Mode Control\n // ===========================================================================\n\n /**\n * Set the break mode for text wrapping\n *\n * @param breakMode - 'character' | 'word' | 'strict-word'\n */\n public setBreakMode(breakMode: BreakMode): void {\n if (this.options.breakMode === breakMode) return\n\n this.options.breakMode = breakMode\n this.updateProfile(this.profile) // Recreate wrapper with new break mode\n\n if (this.options.debug) {\n console.log(`[DisplayProcessor] Break mode set to: ${breakMode}`)\n }\n }\n\n /**\n * Get the current break mode\n */\n public getBreakMode(): BreakMode {\n return this.options.breakMode || \"character\"\n }\n}\n\nexport const displayProcessor = DisplayProcessor.getInstance()\nexport default displayProcessor\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"effectiveCapabilities.d.ts","sourceRoot":"","sources":["../../src/services/effectiveCapabilities.ts"],"names":[],"mappings":"AAcA,OAAO,EAAqB,WAAW,EAAwB,KAAK,YAAY,EAAC,MAAM,UAAU,CAAA;AAOjG,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAI3D;AAMD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CA6BzE"}
1
+ {"version":3,"file":"effectiveCapabilities.d.ts","sourceRoot":"","sources":["../../src/services/effectiveCapabilities.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAqB,WAAW,EAAwB,KAAK,YAAY,EAAC,MAAM,UAAU,CAAA;AAOjG,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAI3D;AAMD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CA8BzE"}
@@ -2,7 +2,9 @@
2
2
  * Effective device capabilities — the static model profile plus what the
3
3
  * connected firmware reports at runtime. The runtime override is the scene
4
4
  * canvas: Glassly CFW on the G2 rasterizes scenes phone-side straight into
5
- * the 640×480 panel, so the drawable canvas grows past stock's 576×288.
5
+ * the 640×480 panel, so the drawable canvas grows past stock's 576×288; on
6
+ * the RayNeo iO it opens a 540×180 page that stock firmware has no
7
+ * equivalent of. Any model whose profile declares `hasCustomFirmware` reads it.
6
8
  * Native publishes the canvas into the glasses status (0 = none). Because
7
9
  * that path is phone-side rasterization, the stock firmware's container
8
10
  * pools (6 text / 4 image) don't bound a CFW frame either — element caps are
@@ -12,7 +14,7 @@
12
14
  */
13
15
  import { useGlassesStore } from "../stores/glasses";
14
16
  import { SETTINGS, useSettingsStore } from "../stores/settings";
15
- import { ALL_DISPLAY_SHAPES, DeviceTypes, getModelCapabilities } from "../types";
17
+ import { ALL_DISPLAY_SHAPES, getModelCapabilities } from "../types";
16
18
  import { resolveNativeNavigation } from "./nativeNavigationGate";
17
19
  const CFW_MAX_TEXT_ELEMENTS = 24;
18
20
  const CFW_MAX_IMAGE_ELEMENTS = 16;
@@ -28,8 +30,9 @@ function forceNativeNavigationOnCfw() {
28
30
  }
29
31
  export function getEffectiveCapabilities(model) {
30
32
  const base = getModelCapabilities(model);
31
- // Only G2 CFW publishes a canvas; never let a stale value reshape another model.
32
- const canvas = model === DeviceTypes.G2 ? runtimeSceneCanvas() : null;
33
+ // Only models with a Glassly CFW publish a canvas; never let a stale value
34
+ // reshape another model.
35
+ const canvas = base.hasCustomFirmware ? runtimeSceneCanvas() : null;
33
36
  if (!base.display || !canvas)
34
37
  return base;
35
38
  // Glassly CFW supports the complete vector contract, including SVG and rotation.
@@ -1 +1 @@
1
- {"version":3,"file":"effectiveCapabilities.js","sourceRoot":"","sources":["../../src/services/effectiveCapabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAC,QAAQ,EAAE,gBAAgB,EAAC,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAC,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAoB,MAAM,UAAU,CAAA;AACjG,OAAO,EAAC,uBAAuB,EAAC,MAAM,wBAAwB,CAAA;AAE9D,MAAM,qBAAqB,GAAG,EAAE,CAAA;AAChC,MAAM,sBAAsB,GAAG,EAAE,CAAA;AACjC,MAAM,uBAAuB,GAAG,GAAG,CAAA;AAOnC,MAAM,UAAU,kBAAkB;IAChC,MAAM,EAAC,gBAAgB,EAAE,iBAAiB,EAAC,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAA;IACxE,IAAI,CAAC,gBAAgB,IAAI,CAAC,iBAAiB,IAAI,gBAAgB,IAAI,CAAC,IAAI,iBAAiB,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3G,OAAO,EAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,iBAAiB,EAAC,CAAA;AAC7D,CAAC;AAED,SAAS,0BAA0B;IACjC,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,IAAI,CAAA;AAC5F,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAkB;IACzD,MAAM,IAAI,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;IACxC,iFAAiF;IACjF,MAAM,MAAM,GAAG,KAAK,KAAK,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IACrE,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACzC,iFAAiF;IACjF,qEAAqE;IACrE,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC,WAAW,KAAK,IAAI,CAAA;IAC9D,OAAO;QACL,GAAG,IAAI;QACP,mBAAmB,EAAE,uBAAuB,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC;QAC1G,OAAO,EAAE;YACP,GAAG,IAAI,CAAC,OAAO;YACf,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,eAAe,EAAE,IAAI,CAAC,GAAG,CACvB,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,EACjC,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,qBAAqB,CACzD;YACD,0EAA0E;YAC1E,gBAAgB,EAAE,IAAI,CAAC,GAAG,CACxB,IAAI,CAAC,OAAO,CAAC,gBAAgB,IAAI,CAAC,EAClC,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,sBAAsB,CAC1D;YACD,GAAG,CAAC,MAAM;gBACR,CAAC,CAAC,EAAC,MAAM,EAAE,CAAC,GAAG,kBAAkB,EAAE,KAAc,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAC;gBACjG,CAAC,CAAC,EAAE,CAAC;SACR;KACF,CAAA;AACH,CAAC","sourcesContent":["/**\n * Effective device capabilities — the static model profile plus what the\n * connected firmware reports at runtime. The runtime override is the scene\n * canvas: Glassly CFW on the G2 rasterizes scenes phone-side straight into\n * the 640×480 panel, so the drawable canvas grows past stock's 576×288.\n * Native publishes the canvas into the glasses status (0 = none). Because\n * that path is phone-side rasterization, the stock firmware's container\n * pools (6 text / 4 image) don't bound a CFW frame either — element caps are\n * lifted alongside the canvas, bounded only to keep frames sane. Firmware\n * that draws vector shapes keeps 128 scene slots, so shape-heavy frames\n * (a game board, a chart) get a larger shared text/shape budget.\n */\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {SETTINGS, useSettingsStore} from \"../stores/settings\"\nimport {ALL_DISPLAY_SHAPES, DeviceTypes, getModelCapabilities, type Capabilities} from \"../types\"\nimport {resolveNativeNavigation} from \"./nativeNavigationGate\"\n\nconst CFW_MAX_TEXT_ELEMENTS = 24\nconst CFW_MAX_IMAGE_ELEMENTS = 16\nconst CFW_VECTOR_MAX_ELEMENTS = 120\n\nexport interface SceneCanvasSize {\n width: number\n height: number\n}\n\nexport function runtimeSceneCanvas(): SceneCanvasSize | null {\n const {sceneCanvasWidth, sceneCanvasHeight} = useGlassesStore.getState()\n if (!sceneCanvasWidth || !sceneCanvasHeight || sceneCanvasWidth <= 0 || sceneCanvasHeight <= 0) return null\n return {width: sceneCanvasWidth, height: sceneCanvasHeight}\n}\n\nfunction forceNativeNavigationOnCfw(): boolean {\n return useSettingsStore.getState().getSetting(SETTINGS.cfw_native_navigation.key) === true\n}\n\nexport function getEffectiveCapabilities(model: DeviceTypes): Capabilities {\n const base = getModelCapabilities(model)\n // Only G2 CFW publishes a canvas; never let a stale value reshape another model.\n const canvas = model === DeviceTypes.G2 ? runtimeSceneCanvas() : null\n if (!base.display || !canvas) return base\n // Glassly CFW supports the complete vector contract, including SVG and rotation.\n // Upstream g2flash publishes a raster canvas with sceneVector=false.\n const vector = useGlassesStore.getState().sceneVector === true\n return {\n ...base,\n hasNativeNavigation: resolveNativeNavigation(base.hasNativeNavigation, true, forceNativeNavigationOnCfw()),\n display: {\n ...base.display,\n width: canvas.width,\n height: canvas.height,\n maxTextElements: Math.max(\n base.display.maxTextElements ?? 0,\n vector ? CFW_VECTOR_MAX_ELEMENTS : CFW_MAX_TEXT_ELEMENTS,\n ),\n // Vector firmware draws an image as one cached slot, the same as a shape.\n maxImageElements: Math.max(\n base.display.maxImageElements ?? 0,\n vector ? CFW_VECTOR_MAX_ELEMENTS : CFW_MAX_IMAGE_ELEMENTS,\n ),\n ...(vector\n ? {shapes: [...ALL_DISPLAY_SHAPES, \"svg\" as const], animation: true, rotation: true, depth: true}\n : {}),\n },\n }\n}\n"]}
1
+ {"version":3,"file":"effectiveCapabilities.js","sourceRoot":"","sources":["../../src/services/effectiveCapabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAC,QAAQ,EAAE,gBAAgB,EAAC,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAC,kBAAkB,EAAe,oBAAoB,EAAoB,MAAM,UAAU,CAAA;AACjG,OAAO,EAAC,uBAAuB,EAAC,MAAM,wBAAwB,CAAA;AAE9D,MAAM,qBAAqB,GAAG,EAAE,CAAA;AAChC,MAAM,sBAAsB,GAAG,EAAE,CAAA;AACjC,MAAM,uBAAuB,GAAG,GAAG,CAAA;AAOnC,MAAM,UAAU,kBAAkB;IAChC,MAAM,EAAC,gBAAgB,EAAE,iBAAiB,EAAC,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAA;IACxE,IAAI,CAAC,gBAAgB,IAAI,CAAC,iBAAiB,IAAI,gBAAgB,IAAI,CAAC,IAAI,iBAAiB,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3G,OAAO,EAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,iBAAiB,EAAC,CAAA;AAC7D,CAAC;AAED,SAAS,0BAA0B;IACjC,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,IAAI,CAAA;AAC5F,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAkB;IACzD,MAAM,IAAI,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;IACxC,2EAA2E;IAC3E,yBAAyB;IACzB,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IACnE,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACzC,iFAAiF;IACjF,qEAAqE;IACrE,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC,WAAW,KAAK,IAAI,CAAA;IAC9D,OAAO;QACL,GAAG,IAAI;QACP,mBAAmB,EAAE,uBAAuB,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC;QAC1G,OAAO,EAAE;YACP,GAAG,IAAI,CAAC,OAAO;YACf,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,eAAe,EAAE,IAAI,CAAC,GAAG,CACvB,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,EACjC,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,qBAAqB,CACzD;YACD,0EAA0E;YAC1E,gBAAgB,EAAE,IAAI,CAAC,GAAG,CACxB,IAAI,CAAC,OAAO,CAAC,gBAAgB,IAAI,CAAC,EAClC,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,sBAAsB,CAC1D;YACD,GAAG,CAAC,MAAM;gBACR,CAAC,CAAC,EAAC,MAAM,EAAE,CAAC,GAAG,kBAAkB,EAAE,KAAc,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAC;gBACjG,CAAC,CAAC,EAAE,CAAC;SACR;KACF,CAAA;AACH,CAAC","sourcesContent":["/**\n * Effective device capabilities — the static model profile plus what the\n * connected firmware reports at runtime. The runtime override is the scene\n * canvas: Glassly CFW on the G2 rasterizes scenes phone-side straight into\n * the 640×480 panel, so the drawable canvas grows past stock's 576×288; on\n * the RayNeo iO it opens a 540×180 page that stock firmware has no\n * equivalent of. Any model whose profile declares `hasCustomFirmware` reads it.\n * Native publishes the canvas into the glasses status (0 = none). Because\n * that path is phone-side rasterization, the stock firmware's container\n * pools (6 text / 4 image) don't bound a CFW frame either — element caps are\n * lifted alongside the canvas, bounded only to keep frames sane. Firmware\n * that draws vector shapes keeps 128 scene slots, so shape-heavy frames\n * (a game board, a chart) get a larger shared text/shape budget.\n */\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {SETTINGS, useSettingsStore} from \"../stores/settings\"\nimport {ALL_DISPLAY_SHAPES, DeviceTypes, getModelCapabilities, type Capabilities} from \"../types\"\nimport {resolveNativeNavigation} from \"./nativeNavigationGate\"\n\nconst CFW_MAX_TEXT_ELEMENTS = 24\nconst CFW_MAX_IMAGE_ELEMENTS = 16\nconst CFW_VECTOR_MAX_ELEMENTS = 120\n\nexport interface SceneCanvasSize {\n width: number\n height: number\n}\n\nexport function runtimeSceneCanvas(): SceneCanvasSize | null {\n const {sceneCanvasWidth, sceneCanvasHeight} = useGlassesStore.getState()\n if (!sceneCanvasWidth || !sceneCanvasHeight || sceneCanvasWidth <= 0 || sceneCanvasHeight <= 0) return null\n return {width: sceneCanvasWidth, height: sceneCanvasHeight}\n}\n\nfunction forceNativeNavigationOnCfw(): boolean {\n return useSettingsStore.getState().getSetting(SETTINGS.cfw_native_navigation.key) === true\n}\n\nexport function getEffectiveCapabilities(model: DeviceTypes): Capabilities {\n const base = getModelCapabilities(model)\n // Only models with a Glassly CFW publish a canvas; never let a stale value\n // reshape another model.\n const canvas = base.hasCustomFirmware ? runtimeSceneCanvas() : null\n if (!base.display || !canvas) return base\n // Glassly CFW supports the complete vector contract, including SVG and rotation.\n // Upstream g2flash publishes a raster canvas with sceneVector=false.\n const vector = useGlassesStore.getState().sceneVector === true\n return {\n ...base,\n hasNativeNavigation: resolveNativeNavigation(base.hasNativeNavigation, true, forceNativeNavigationOnCfw()),\n display: {\n ...base.display,\n width: canvas.width,\n height: canvas.height,\n maxTextElements: Math.max(\n base.display.maxTextElements ?? 0,\n vector ? CFW_VECTOR_MAX_ELEMENTS : CFW_MAX_TEXT_ELEMENTS,\n ),\n // Vector firmware draws an image as one cached slot, the same as a shape.\n maxImageElements: Math.max(\n base.display.maxImageElements ?? 0,\n vector ? CFW_VECTOR_MAX_ELEMENTS : CFW_MAX_IMAGE_ELEMENTS,\n ),\n ...(vector\n ? {shapes: [...ALL_DISPLAY_SHAPES, \"svg\" as const], animation: true, rotation: true, depth: true}\n : {}),\n },\n }\n}\n"]}
@@ -1,6 +1,10 @@
1
- /** G2.swift appends this marker after the firmware advertises Glassly CFW capabilities. */
1
+ /** The SGC appends this marker after the firmware advertises Glassly CFW capabilities (G2, RayNeo iO). */
2
2
  export declare function isCfwFirmwareVersion(firmwareVersion: string | null | undefined): boolean;
3
- /** Stock G2 and NIMO are intentionally excluded. */
3
+ /**
4
+ * Only models that ship a Glassly custom firmware, and only while they run it.
5
+ * Stock firmware on those models and every other model (NIMO, G1, ...) are
6
+ * intentionally excluded.
7
+ */
4
8
  export declare function isCustomDashboardEligible(info: {
5
9
  model?: string | null;
6
10
  firmwareVersion?: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"pageEligibility.d.ts","sourceRoot":"","sources":["../../../src/services/pages/pageEligibility.ts"],"names":[],"mappings":"AAYA,2FAA2F;AAC3F,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAExF;AAED,oDAAoD;AACpD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,GAAG,OAAO,CAEjH;AAED,wBAAgB,aAAa,IAAI,OAAO,CAOvC"}
1
+ {"version":3,"file":"pageEligibility.d.ts","sourceRoot":"","sources":["../../../src/services/pages/pageEligibility.ts"],"names":[],"mappings":"AAaA,0GAA0G;AAC1G,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAExF;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,GAAG,OAAO,CAMjH;AAED,wBAAgB,aAAa,IAAI,OAAO,CAOvC"}
@@ -7,15 +7,22 @@
7
7
  */
8
8
  import { useGlassesStore } from "../../stores/glasses";
9
9
  import { SETTINGS, useSettingsStore } from "../../stores/settings";
10
- import { DeviceTypes } from "../../types/enums";
10
+ import { getModelCapabilities } from "../../types/hardware";
11
11
  import { isGlassesConnected } from "../GlassesReadiness";
12
- /** G2.swift appends this marker after the firmware advertises Glassly CFW capabilities. */
12
+ /** The SGC appends this marker after the firmware advertises Glassly CFW capabilities (G2, RayNeo iO). */
13
13
  export function isCfwFirmwareVersion(firmwareVersion) {
14
14
  return firmwareVersion?.toLowerCase().includes("glassly cfw") === true;
15
15
  }
16
- /** Stock G2 and NIMO are intentionally excluded. */
16
+ /**
17
+ * Only models that ship a Glassly custom firmware, and only while they run it.
18
+ * Stock firmware on those models and every other model (NIMO, G1, ...) are
19
+ * intentionally excluded.
20
+ */
17
21
  export function isCustomDashboardEligible(info) {
18
- return info.model === DeviceTypes.G2 && isCfwFirmwareVersion(info.firmwareVersion);
22
+ if (!info.model)
23
+ return false;
24
+ return (getModelCapabilities(info.model).hasCustomFirmware === true &&
25
+ isCfwFirmwareVersion(info.firmwareVersion));
19
26
  }
20
27
  export function pagesEligible() {
21
28
  if (useSettingsStore.getState().getSetting(SETTINGS.custom_dashboard_enabled.key) === false)
@@ -1 +1 @@
1
- {"version":3,"file":"pageEligibility.js","sourceRoot":"","sources":["../../../src/services/pages/pageEligibility.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAC,eAAe,EAAC,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAC,QAAQ,EAAE,gBAAgB,EAAC,MAAM,uBAAuB,CAAA;AAChE,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAA;AAC7C,OAAO,EAAC,kBAAkB,EAAC,MAAM,qBAAqB,CAAA;AAEtD,2FAA2F;AAC3F,MAAM,UAAU,oBAAoB,CAAC,eAA0C;IAC7E,OAAO,eAAe,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,IAAI,CAAA;AACxE,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,yBAAyB,CAAC,IAA8D;IACtG,OAAO,IAAI,CAAC,KAAK,KAAK,WAAW,CAAC,EAAE,IAAI,oBAAoB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;AACpF,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,IAAI,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,wBAAwB,CAAC,GAAG,CAAC,KAAK,KAAK;QAAE,OAAO,KAAK,CAAA;IACzG,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAA;IACxC,OAAO,CACL,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC;QACpC,yBAAyB,CAAC,EAAC,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,EAAC,CAAC,CAC9F,CAAA;AACH,CAAC","sourcesContent":["/**\n * Whether the dashboard view may show right now: connected Glassly CFW\n * glasses with the dashboard enabled. The page host reads it before showing\n * a page and hides the showing page when it turns false; the miniapp runtime\n * folds it into the designated app's `display.views` capability. Read at\n * decision time, never cached.\n */\nimport {useGlassesStore} from \"../../stores/glasses\"\nimport {SETTINGS, useSettingsStore} from \"../../stores/settings\"\nimport {DeviceTypes} from \"../../types/enums\"\nimport {isGlassesConnected} from \"../GlassesReadiness\"\n\n/** G2.swift appends this marker after the firmware advertises Glassly CFW capabilities. */\nexport function isCfwFirmwareVersion(firmwareVersion: string | null | undefined): boolean {\n return firmwareVersion?.toLowerCase().includes(\"glassly cfw\") === true\n}\n\n/** Stock G2 and NIMO are intentionally excluded. */\nexport function isCustomDashboardEligible(info: {model?: string | null; firmwareVersion?: string | null}): boolean {\n return info.model === DeviceTypes.G2 && isCfwFirmwareVersion(info.firmwareVersion)\n}\n\nexport function pagesEligible(): boolean {\n if (useSettingsStore.getState().getSetting(SETTINGS.custom_dashboard_enabled.key) === false) return false\n const state = useGlassesStore.getState()\n return (\n isGlassesConnected(state.connection) &&\n isCustomDashboardEligible({model: state.deviceModel, firmwareVersion: state.firmwareVersion})\n )\n}\n"]}
1
+ {"version":3,"file":"pageEligibility.js","sourceRoot":"","sources":["../../../src/services/pages/pageEligibility.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAC,eAAe,EAAC,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAC,QAAQ,EAAE,gBAAgB,EAAC,MAAM,uBAAuB,CAAA;AAEhE,OAAO,EAAC,oBAAoB,EAAC,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAC,kBAAkB,EAAC,MAAM,qBAAqB,CAAA;AAEtD,0GAA0G;AAC1G,MAAM,UAAU,oBAAoB,CAAC,eAA0C;IAC7E,OAAO,eAAe,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,IAAI,CAAA;AACxE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAA8D;IACtG,IAAI,CAAC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IAC7B,OAAO,CACL,oBAAoB,CAAC,IAAI,CAAC,KAAoB,CAAC,CAAC,iBAAiB,KAAK,IAAI;QAC1E,oBAAoB,CAAC,IAAI,CAAC,eAAe,CAAC,CAC3C,CAAA;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,IAAI,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,wBAAwB,CAAC,GAAG,CAAC,KAAK,KAAK;QAAE,OAAO,KAAK,CAAA;IACzG,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAA;IACxC,OAAO,CACL,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC;QACpC,yBAAyB,CAAC,EAAC,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,EAAC,CAAC,CAC9F,CAAA;AACH,CAAC","sourcesContent":["/**\n * Whether the dashboard view may show right now: connected Glassly CFW\n * glasses with the dashboard enabled. The page host reads it before showing\n * a page and hides the showing page when it turns false; the miniapp runtime\n * folds it into the designated app's `display.views` capability. Read at\n * decision time, never cached.\n */\nimport {useGlassesStore} from \"../../stores/glasses\"\nimport {SETTINGS, useSettingsStore} from \"../../stores/settings\"\nimport {DeviceTypes} from \"../../types/enums\"\nimport {getModelCapabilities} from \"../../types/hardware\"\nimport {isGlassesConnected} from \"../GlassesReadiness\"\n\n/** The SGC appends this marker after the firmware advertises Glassly CFW capabilities (G2, RayNeo iO). */\nexport function isCfwFirmwareVersion(firmwareVersion: string | null | undefined): boolean {\n return firmwareVersion?.toLowerCase().includes(\"glassly cfw\") === true\n}\n\n/**\n * Only models that ship a Glassly custom firmware, and only while they run it.\n * Stock firmware on those models and every other model (NIMO, G1, ...) are\n * intentionally excluded.\n */\nexport function isCustomDashboardEligible(info: {model?: string | null; firmwareVersion?: string | null}): boolean {\n if (!info.model) return false\n return (\n getModelCapabilities(info.model as DeviceTypes).hasCustomFirmware === true &&\n isCfwFirmwareVersion(info.firmwareVersion)\n )\n}\n\nexport function pagesEligible(): boolean {\n if (useSettingsStore.getState().getSetting(SETTINGS.custom_dashboard_enabled.key) === false) return false\n const state = useGlassesStore.getState()\n return (\n isGlassesConnected(state.connection) &&\n isCustomDashboardEligible({model: state.deviceModel, firmwareVersion: state.firmwareVersion})\n )\n}\n"]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @fileoverview RayNeo iO Hardware Capabilities
3
+ *
4
+ * Capability profile for the RayNeo iO smart glasses. The stock firmware
5
+ * exposes a single-line subtitle page over a framed BLE protocol; with the
6
+ * Glassly CFW installed the glasses open a 540×180 page the phone draws into
7
+ * through the Glassly CFW record protocol (positioned text, images, rects).
8
+ */
9
+ import type { Capabilities } from "../hardware";
10
+ /**
11
+ * RayNeo iO capability profile
12
+ */
13
+ export declare const rayneoIO: Capabilities;
14
+ //# sourceMappingURL=rayneo-io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rayneo-io.d.ts","sourceRoot":"","sources":["../../../src/types/capabilities/rayneo-io.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAA;AAE7C;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,YAsFtB,CAAA"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * @fileoverview RayNeo iO Hardware Capabilities
3
+ *
4
+ * Capability profile for the RayNeo iO smart glasses. The stock firmware
5
+ * exposes a single-line subtitle page over a framed BLE protocol; with the
6
+ * Glassly CFW installed the glasses open a 540×180 page the phone draws into
7
+ * through the Glassly CFW record protocol (positioned text, images, rects).
8
+ */
9
+ /**
10
+ * RayNeo iO capability profile
11
+ */
12
+ export const rayneoIO = {
13
+ modelName: "RayNeo iO",
14
+ // Camera capabilities - no camera
15
+ hasCamera: false,
16
+ camera: null,
17
+ // Display capabilities - single monochrome (1-bit) panel
18
+ hasDisplay: true,
19
+ display: {
20
+ count: 1,
21
+ isColor: false,
22
+ color: "green",
23
+ // Bitmaps and positioned elements need the Glassly CFW; stock firmware
24
+ // only shows text through its subtitle page.
25
+ canDisplayBitmap: true,
26
+ resolution: { width: 540, height: 180 },
27
+ fieldOfView: { horizontal: 30 },
28
+ maxTextLines: 5,
29
+ adjustBrightness: true,
30
+ // Scene display API — the Glassly CFW page canvas.
31
+ width: 540,
32
+ height: 180,
33
+ canPosition: true,
34
+ maxTextElements: 6,
35
+ maxImageElements: 4,
36
+ intensityLevels: 2,
37
+ partialUpdate: true,
38
+ },
39
+ // Microphone capabilities - one Opus mic stream through the voice page
40
+ hasMicrophone: true,
41
+ microphone: {
42
+ count: 1,
43
+ hasVAD: false,
44
+ },
45
+ // Speaker capabilities - no speaker channel in the protocol
46
+ hasSpeaker: false,
47
+ speaker: null,
48
+ // IMU capabilities - stock firmware exposes no IMU or head-gesture stream
49
+ hasIMU: false,
50
+ imu: null,
51
+ // Button capabilities - temple touchpad/crown plus a physical button
52
+ hasButton: true,
53
+ button: {
54
+ count: 1,
55
+ buttons: [
56
+ {
57
+ type: "swipe1d",
58
+ events: ["TAP", "DOUBLE_TAP", "PRESS_HOLD", "SWIPE_UP", "SWIPE_DOWN"],
59
+ isCapacitive: true,
60
+ },
61
+ ],
62
+ },
63
+ // Light capabilities - no lights
64
+ hasLight: false,
65
+ light: null,
66
+ // Power capabilities
67
+ power: {
68
+ hasExternalBattery: false,
69
+ },
70
+ // WiFi capabilities - no WiFi
71
+ hasWifi: false,
72
+ // OTA capabilities - RayNeo iO updates are not driven by the ASG OTA flow
73
+ hasOta: false,
74
+ // Glassly CFW is bundled for the RayNeo iO and flashed over BLE from the app
75
+ hasCustomFirmware: true,
76
+ // Dashboard - the launcher renders its own status UI; Glassly does not
77
+ // manage the dashboard settings for it
78
+ hasNativeDashboard: true,
79
+ // Navigation - no firmware nav UI
80
+ hasNativeNavigation: false,
81
+ // Firmware notification popups: the phone uploads notification content
82
+ hasNativeNotifications: true,
83
+ };
84
+ //# sourceMappingURL=rayneo-io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rayneo-io.js","sourceRoot":"","sources":["../../../src/types/capabilities/rayneo-io.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAiB;IACpC,SAAS,EAAE,WAAW;IAEtB,kCAAkC;IAClC,SAAS,EAAE,KAAK;IAChB,MAAM,EAAE,IAAI;IAEZ,yDAAyD;IACzD,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE;QACP,KAAK,EAAE,CAAC;QACR,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,OAAO;QACd,uEAAuE;QACvE,6CAA6C;QAC7C,gBAAgB,EAAE,IAAI;QACtB,UAAU,EAAE,EAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAC;QACrC,WAAW,EAAE,EAAC,UAAU,EAAE,EAAE,EAAC;QAC7B,YAAY,EAAE,CAAC;QACf,gBAAgB,EAAE,IAAI;QAEtB,mDAAmD;QACnD,KAAK,EAAE,GAAG;QACV,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,IAAI;QACjB,eAAe,EAAE,CAAC;QAClB,gBAAgB,EAAE,CAAC;QACnB,eAAe,EAAE,CAAC;QAClB,aAAa,EAAE,IAAI;KACpB;IAED,uEAAuE;IACvE,aAAa,EAAE,IAAI;IACnB,UAAU,EAAE;QACV,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,KAAK;KACd;IAED,4DAA4D;IAC5D,UAAU,EAAE,KAAK;IACjB,OAAO,EAAE,IAAI;IAEb,0EAA0E;IAC1E,MAAM,EAAE,KAAK;IACb,GAAG,EAAE,IAAI;IAET,qEAAqE;IACrE,SAAS,EAAE,IAAI;IACf,MAAM,EAAE;QACN,KAAK,EAAE,CAAC;QACR,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC;gBACrE,YAAY,EAAE,IAAI;aACnB;SACF;KACF;IAED,iCAAiC;IACjC,QAAQ,EAAE,KAAK;IACf,KAAK,EAAE,IAAI;IAEX,qBAAqB;IACrB,KAAK,EAAE;QACL,kBAAkB,EAAE,KAAK;KAC1B;IAED,8BAA8B;IAC9B,OAAO,EAAE,KAAK;IAEd,0EAA0E;IAC1E,MAAM,EAAE,KAAK;IAEb,6EAA6E;IAC7E,iBAAiB,EAAE,IAAI;IAEvB,uEAAuE;IACvE,uCAAuC;IACvC,kBAAkB,EAAE,IAAI;IAExB,kCAAkC;IAClC,mBAAmB,EAAE,KAAK;IAE1B,uEAAuE;IACvE,sBAAsB,EAAE,IAAI;CAC7B,CAAA","sourcesContent":["/**\n * @fileoverview RayNeo iO Hardware Capabilities\n *\n * Capability profile for the RayNeo iO smart glasses. The stock firmware\n * exposes a single-line subtitle page over a framed BLE protocol; with the\n * Glassly CFW installed the glasses open a 540×180 page the phone draws into\n * through the Glassly CFW record protocol (positioned text, images, rects).\n */\n\nimport type {Capabilities} from \"../hardware\"\n\n/**\n * RayNeo iO capability profile\n */\nexport const rayneoIO: Capabilities = {\n modelName: \"RayNeo iO\",\n\n // Camera capabilities - no camera\n hasCamera: false,\n camera: null,\n\n // Display capabilities - single monochrome (1-bit) panel\n hasDisplay: true,\n display: {\n count: 1,\n isColor: false,\n color: \"green\",\n // Bitmaps and positioned elements need the Glassly CFW; stock firmware\n // only shows text through its subtitle page.\n canDisplayBitmap: true,\n resolution: {width: 540, height: 180},\n fieldOfView: {horizontal: 30},\n maxTextLines: 5,\n adjustBrightness: true,\n\n // Scene display API — the Glassly CFW page canvas.\n width: 540,\n height: 180,\n canPosition: true,\n maxTextElements: 6,\n maxImageElements: 4,\n intensityLevels: 2,\n partialUpdate: true,\n },\n\n // Microphone capabilities - one Opus mic stream through the voice page\n hasMicrophone: true,\n microphone: {\n count: 1,\n hasVAD: false,\n },\n\n // Speaker capabilities - no speaker channel in the protocol\n hasSpeaker: false,\n speaker: null,\n\n // IMU capabilities - stock firmware exposes no IMU or head-gesture stream\n hasIMU: false,\n imu: null,\n\n // Button capabilities - temple touchpad/crown plus a physical button\n hasButton: true,\n button: {\n count: 1,\n buttons: [\n {\n type: \"swipe1d\",\n events: [\"TAP\", \"DOUBLE_TAP\", \"PRESS_HOLD\", \"SWIPE_UP\", \"SWIPE_DOWN\"],\n isCapacitive: true,\n },\n ],\n },\n\n // Light capabilities - no lights\n hasLight: false,\n light: null,\n\n // Power capabilities\n power: {\n hasExternalBattery: false,\n },\n\n // WiFi capabilities - no WiFi\n hasWifi: false,\n\n // OTA capabilities - RayNeo iO updates are not driven by the ASG OTA flow\n hasOta: false,\n\n // Glassly CFW is bundled for the RayNeo iO and flashed over BLE from the app\n hasCustomFirmware: true,\n\n // Dashboard - the launcher renders its own status UI; Glassly does not\n // manage the dashboard settings for it\n hasNativeDashboard: true,\n\n // Navigation - no firmware nav UI\n hasNativeNavigation: false,\n\n // Firmware notification popups: the phone uploads notification content\n hasNativeNotifications: true,\n}\n"]}
@@ -10,7 +10,8 @@ export declare enum DeviceTypes {
10
10
  Z100 = "Vuzix Z100",
11
11
  NEX = "Mentra Display",
12
12
  NIMO = "NIMO",
13
- FRAME = "Brilliant Frame"
13
+ FRAME = "Brilliant Frame",
14
+ RAYNEO_IO = "RayNeo iO"
14
15
  }
15
16
  export declare enum ControllerTypes {
16
17
  R1 = "Even Realities R1"
@@ -1 +1 @@
1
- {"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../src/types/enums.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,wBAAwB,EAAC,MAAM,2BAA2B,CAAA;AAEhF,oBAAY,WAAW;IACrB,IAAI,SAAS;IACb,SAAS,sBAAsB;IAC/B,IAAI,SAAS;IACb,EAAE,sBAAsB;IACxB,EAAE,sBAAsB;IACxB,IAAI,gBAAgB;IACpB,KAAK,iBAAiB;IACtB,IAAI,eAAe;IACnB,GAAG,mBAAmB;IACtB,IAAI,SAAS;IACb,KAAK,oBAAoB;CAC1B;AAED,oBAAY,eAAe;IACzB,EAAE,sBAAsB;CACzB"}
1
+ {"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../src/types/enums.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,wBAAwB,EAAC,MAAM,2BAA2B,CAAA;AAEhF,oBAAY,WAAW;IACrB,IAAI,SAAS;IACb,SAAS,sBAAsB;IAC/B,IAAI,SAAS;IACb,EAAE,sBAAsB;IACxB,EAAE,sBAAsB;IACxB,IAAI,gBAAgB;IACpB,KAAK,iBAAiB;IACtB,IAAI,eAAe;IACnB,GAAG,mBAAmB;IACtB,IAAI,SAAS;IACb,KAAK,oBAAoB;IACzB,SAAS,cAAc;CACxB;AAED,oBAAY,eAAe;IACzB,EAAE,sBAAsB;CACzB"}