{"version":3,"sources":["../src/gatt-registry.generated.ts","../src/uuid.ts"],"names":["BLUETOOTH_BASE_UUID_SUFFIX","UUID_RE","GATT_ASSIGNED_SERVICES","GATT_ASSIGNED_CHARACTERISTICS","GATT_ASSIGNED_DESCRIPTORS","hexToUUID","hex","canonicalUUID","alias","converted","truncated","resolveUUIDName","name","table","getter","value","serviceNameMap","charNameMap","getServiceNameMap","uuid","getCharNameMap","HEX4_RE","HEX8_RE","levenshtein","a","b","m","n","row","i","prev","j","tmp","normalizeBluetoothName","input","lookupNamedUUID","directMatch","compactName","candidateName","candidateHex","resolveUUID","nameOrUUID","raw","lower","exactAlias","normalizedName","serviceHex","charHex","allNames","closest","bestDist","d","hint","getServiceName","getCharacteristicName","getDisplayName","bare","word","getDescriptor","BluetoothUUID"],"mappings":"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","file":"chunk-33IHM3NV.mjs","sourcesContent":["/**\n * THE single source of the Web Bluetooth §7 page-realm UUID machinery for every\n * TypeScript bundle: the npm core, the extension-injected surface\n * (`src/beacio/api/*`) and the standalone CDN polyfill (`src/cdn/beacio.ts`)\n * all import the three GATT assigned-numbers tables and the §7.1 resolver\n * (`canonicalUUID` + `resolveUUIDName`) FROM HERE. Because each shipped artifact\n * is webpack/tsup-bundled, this source module is inlined into each build, so\n * every artifact stays dependency-free while the tables + resolver exist ONCE.\n *\n * The three `registries:begin/end` table blocks are GENERATED by\n * `scripts/registries/generate.mjs` from the vendored WebBluetoothCG registry\n * files in `registries/` — the same single source of truth as\n * `Shared (Extension)/UUIDResolver.swift` (Swift cannot import TS, so it stays\n * a separate generated target). Regenerate with:\n *   node scripts/registries/generate.mjs\n *\n * The resolver semantics are the STRICT §7.1 form (spec: \"A valid UUID is a\n * lower-case 128-bit string\"): a string argument must be a valid lowercase\n * 128-bit UUID or a registered name (looked up case-folded because the tables\n * key the registry's mixed-case published spellings — e.g.\n * `magnetic_flux_density_2D` — in lowercase). The bare 4/8-hex and uppercase\n * leniency of the wire helpers (`src/beacio/api/uuid-normalization.ts`) is\n * intentionally NOT offered here.\n *\n * ARCHITECTURE BOUNDARY: This file holds ONLY the three GATT assigned-numbers\n * tables (services/characteristics/descriptors) + the Web Bluetooth §7.1\n * resolver functions (canonicalUUID, resolveUUIDName, hexToUUID). No other\n * logic. No new exports. Every consumer bundles this inline, so accumulation\n * here is paid N times across consumers.\n */\n\n/** §7 base UUID suffix; a 16/32-bit alias replaces the top 32 bits. */\nexport const BLUETOOTH_BASE_UUID_SUFFIX = \"-0000-1000-8000-00805f9b34fb\";\n\n/** §7 \"A valid UUID is a string that matches [this] regexp\" (lowercase only). */\nexport const UUID_RE =\n  /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\n// registries:begin gatt-services\n// GENERATED from registries/gatt_assigned_services.txt by scripts/registries/generate.mjs — do not edit by hand.\nexport const GATT_ASSIGNED_SERVICES: Record<string, number> = {\n  'generic_access': 0x1800,\n  'generic_attribute': 0x1801,\n  'immediate_alert': 0x1802,\n  'link_loss': 0x1803,\n  'tx_power': 0x1804,\n  'current_time': 0x1805,\n  'reference_time_update': 0x1806,\n  'next_dst_change': 0x1807,\n  'glucose': 0x1808,\n  'health_thermometer': 0x1809,\n  'device_information': 0x180A,\n  'heart_rate': 0x180D,\n  'phone_alert_status': 0x180E,\n  'battery_service': 0x180F,\n  'blood_pressure': 0x1810,\n  'alert_notification': 0x1811,\n  'human_interface_device': 0x1812,\n  'scan_parameters': 0x1813,\n  'running_speed_and_cadence': 0x1814,\n  'automation_io': 0x1815,\n  'cycling_speed_and_cadence': 0x1816,\n  'cycling_power': 0x1818,\n  'location_and_navigation': 0x1819,\n  'environmental_sensing': 0x181A,\n  'body_composition': 0x181B,\n  'user_data': 0x181C,\n  'weight_scale': 0x181D,\n  'bond_management': 0x181E,\n  'continuous_glucose_monitoring': 0x181F,\n  'internet_protocol_support': 0x1820,\n  'indoor_positioning': 0x1821,\n  'pulse_oximeter': 0x1822,\n  'http_proxy': 0x1823,\n  'transport_discovery': 0x1824,\n  'object_transfer': 0x1825,\n  'fitness_machine': 0x1826,\n  'mesh_provisioning': 0x1827,\n  'mesh_proxy': 0x1828,\n  'reconnection_configuration': 0x1829,\n};\n// registries:end gatt-services\n\n// registries:begin gatt-characteristics\n// GENERATED from registries/gatt_assigned_characteristics.txt by scripts/registries/generate.mjs — do not edit by hand.\nexport const GATT_ASSIGNED_CHARACTERISTICS: Record<string, number> = {\n  'gap.device_name': 0x2A00,\n  'gap.appearance': 0x2A01,\n  'gap.peripheral_privacy_flag': 0x2A02,\n  'gap.reconnection_address': 0x2A03,\n  'gap.peripheral_preferred_connection_parameters': 0x2A04,\n  'gatt.service_changed': 0x2A05,\n  'alert_level': 0x2A06,\n  'tx_power_level': 0x2A07,\n  'date_time': 0x2A08,\n  'day_of_week': 0x2A09,\n  'day_date_time': 0x2A0A,\n  'exact_time_100': 0x2A0B,\n  'exact_time_256': 0x2A0C,\n  'dst_offset': 0x2A0D,\n  'time_zone': 0x2A0E,\n  'local_time_information': 0x2A0F,\n  'secondary_time_zone': 0x2A10,\n  'time_with_dst': 0x2A11,\n  'time_accuracy': 0x2A12,\n  'time_source': 0x2A13,\n  'reference_time_information': 0x2A14,\n  'time_broadcast': 0x2A15,\n  'time_update_control_point': 0x2A16,\n  'time_update_state': 0x2A17,\n  'glucose_measurement': 0x2A18,\n  'battery_level': 0x2A19,\n  'battery_power_state': 0x2A1A,\n  'battery_level_state': 0x2A1B,\n  'temperature_measurement': 0x2A1C,\n  'temperature_type': 0x2A1D,\n  'intermediate_temperature': 0x2A1E,\n  'temperature_celsius': 0x2A1F,\n  'temperature_fahrenheit': 0x2A20,\n  'measurement_interval': 0x2A21,\n  'boot_keyboard_input_report': 0x2A22,\n  'system_id': 0x2A23,\n  'model_number_string': 0x2A24,\n  'serial_number_string': 0x2A25,\n  'firmware_revision_string': 0x2A26,\n  'hardware_revision_string': 0x2A27,\n  'software_revision_string': 0x2A28,\n  'manufacturer_name_string': 0x2A29,\n  'ieee_11073-20601_regulatory_certification_data_list': 0x2A2A,\n  'current_time': 0x2A2B,\n  'magnetic_declination': 0x2A2C,\n  'position_2d': 0x2A2F,\n  'position_3d': 0x2A30,\n  'scan_refresh': 0x2A31,\n  'boot_keyboard_output_report': 0x2A32,\n  'boot_mouse_input_report': 0x2A33,\n  'glucose_measurement_context': 0x2A34,\n  'blood_pressure_measurement': 0x2A35,\n  'intermediate_cuff_pressure': 0x2A36,\n  'heart_rate_measurement': 0x2A37,\n  'body_sensor_location': 0x2A38,\n  'heart_rate_control_point': 0x2A39,\n  'removable': 0x2A3A,\n  'service_required': 0x2A3B,\n  'scientific_temperature_celsius': 0x2A3C,\n  'string': 0x2A3D,\n  'network_availability': 0x2A3E,\n  'alert_status': 0x2A3F,\n  'ringer_control_point': 0x2A40,\n  'ringer_setting': 0x2A41,\n  'alert_category_id_bit_mask': 0x2A42,\n  'alert_category_id': 0x2A43,\n  'alert_notification_control_point': 0x2A44,\n  'unread_alert_status': 0x2A45,\n  'new_alert': 0x2A46,\n  'supported_new_alert_category': 0x2A47,\n  'supported_unread_alert_category': 0x2A48,\n  'blood_pressure_feature': 0x2A49,\n  'hid_information': 0x2A4A,\n  'report_map': 0x2A4B,\n  'hid_control_point': 0x2A4C,\n  'report': 0x2A4D,\n  'protocol_mode': 0x2A4E,\n  'scan_interval_window': 0x2A4F,\n  'pnp_id': 0x2A50,\n  'glucose_feature': 0x2A51,\n  'record_access_control_point': 0x2A52,\n  'rsc_measurement': 0x2A53,\n  'rsc_feature': 0x2A54,\n  'sc_control_point': 0x2A55,\n  'digital': 0x2A56,\n  'digital_output': 0x2A57,\n  'analog': 0x2A58,\n  'analog_output': 0x2A59,\n  'aggregate': 0x2A5A,\n  'csc_measurement': 0x2A5B,\n  'csc_feature': 0x2A5C,\n  'sensor_location': 0x2A5D,\n  'plx_spot_check_measurement': 0x2A5E,\n  'plx_continuous_measurement': 0x2A5F,\n  'plx_features': 0x2A60,\n  'pulse_oximetry_control_point': 0x2A62,\n  'cycling_power_measurement': 0x2A63,\n  'cycling_power_vector': 0x2A64,\n  'cycling_power_feature': 0x2A65,\n  'cycling_power_control_point': 0x2A66,\n  'location_and_speed': 0x2A67,\n  'navigation': 0x2A68,\n  'position_quality': 0x2A69,\n  'ln_feature': 0x2A6A,\n  'ln_control_point': 0x2A6B,\n  'elevation': 0x2A6C,\n  'pressure': 0x2A6D,\n  'temperature': 0x2A6E,\n  'humidity': 0x2A6F,\n  'true_wind_speed': 0x2A70,\n  'true_wind_direction': 0x2A71,\n  'apparent_wind_speed': 0x2A72,\n  'apparent_wind_direction': 0x2A73,\n  'gust_factor': 0x2A74,\n  'pollen_concentration': 0x2A75,\n  'uv_index': 0x2A76,\n  'irradiance': 0x2A77,\n  'rainfall': 0x2A78,\n  'wind_chill': 0x2A79,\n  'heat_index': 0x2A7A,\n  'dew_point': 0x2A7B,\n  'descriptor_value_changed': 0x2A7D,\n  'aerobic_heart_rate_lower_limit': 0x2A7E,\n  'aerobic_threshold': 0x2A7F,\n  'age': 0x2A80,\n  'anaerobic_heart_rate_lower_limit': 0x2A81,\n  'anaerobic_heart_rate_upper_limit': 0x2A82,\n  'anaerobic_threshold': 0x2A83,\n  'aerobic_heart_rate_upper_limit': 0x2A84,\n  'date_of_birth': 0x2A85,\n  'date_of_threshold_assessment': 0x2A86,\n  'email_address': 0x2A87,\n  'fat_burn_heart_rate_lower_limit': 0x2A88,\n  'fat_burn_heart_rate_upper_limit': 0x2A89,\n  'first_name': 0x2A8A,\n  'five_zone_heart_rate_limits': 0x2A8B,\n  'gender': 0x2A8C,\n  'heart_rate_max': 0x2A8D,\n  'height': 0x2A8E,\n  'hip_circumference': 0x2A8F,\n  'last_name': 0x2A90,\n  'maximum_recommended_heart_rate': 0x2A91,\n  'resting_heart_rate': 0x2A92,\n  'sport_type_for_aerobic_and_anaerobic_thresholds': 0x2A93,\n  'three_zone_heart_rate_limits': 0x2A94,\n  'two_zone_heart_rate_limit': 0x2A95,\n  'vo2_max': 0x2A96,\n  'waist_circumference': 0x2A97,\n  'weight': 0x2A98,\n  'database_change_increment': 0x2A99,\n  'user_index': 0x2A9A,\n  'body_composition_feature': 0x2A9B,\n  'body_composition_measurement': 0x2A9C,\n  'weight_measurement': 0x2A9D,\n  'weight_scale_feature': 0x2A9E,\n  'user_control_point': 0x2A9F,\n  'magnetic_flux_density_2d': 0x2AA0,\n  'magnetic_flux_density_3d': 0x2AA1,\n  'language': 0x2AA2,\n  'barometric_pressure_trend': 0x2AA3,\n  'bond_management_control_point': 0x2AA4,\n  'bond_management_feature': 0x2AA5,\n  'gap.central_address_resolution_support': 0x2AA6,\n  'cgm_measurement': 0x2AA7,\n  'cgm_feature': 0x2AA8,\n  'cgm_status': 0x2AA9,\n  'cgm_session_start_time': 0x2AAA,\n  'cgm_session_run_time': 0x2AAB,\n  'cgm_specific_ops_control_point': 0x2AAC,\n  'indoor_positioning_configuration': 0x2AAD,\n  'latitude': 0x2AAE,\n  'longitude': 0x2AAF,\n  'local_north_coordinate': 0x2AB0,\n  'local_east_coordinate': 0x2AB1,\n  'floor_number': 0x2AB2,\n  'altitude': 0x2AB3,\n  'uncertainty': 0x2AB4,\n  'location_name': 0x2AB5,\n  'uri': 0x2AB6,\n  'http_headers': 0x2AB7,\n  'http_status_code': 0x2AB8,\n  'http_entity_body': 0x2AB9,\n  'http_control_point': 0x2ABA,\n  'https_security': 0x2ABB,\n  'tds_control_point': 0x2ABC,\n  'ots_feature': 0x2ABD,\n  'object_name': 0x2ABE,\n  'object_type': 0x2ABF,\n  'object_size': 0x2AC0,\n  'object_first_created': 0x2AC1,\n  'object_last_modified': 0x2AC2,\n  'object_id': 0x2AC3,\n  'object_properties': 0x2AC4,\n  'object_action_control_point': 0x2AC5,\n  'object_list_control_point': 0x2AC6,\n  'object_list_filter': 0x2AC7,\n  'object_changed': 0x2AC8,\n  'resolvable_private_address_only': 0x2AC9,\n  'fitness_machine_feature': 0x2ACC,\n  'treadmill_data': 0x2ACD,\n  'cross_trainer_data': 0x2ACE,\n  'step_climber_data': 0x2ACF,\n  'stair_climber_data': 0x2AD0,\n  'rower_data': 0x2AD1,\n  'indoor_bike_data': 0x2AD2,\n  'training_status': 0x2AD3,\n  'supported_speed_range': 0x2AD4,\n  'supported_inclination_range': 0x2AD5,\n  'supported_resistance_level_range': 0x2AD6,\n  'supported_heart_rate_range': 0x2AD7,\n  'supported_power_range': 0x2AD8,\n  'fitness_machine_control_point': 0x2AD9,\n  'fitness_machine_status': 0x2ADA,\n  'date_utc': 0x2AED,\n};\n// registries:end gatt-characteristics\n\n// registries:begin gatt-descriptors\n// GENERATED from registries/gatt_assigned_descriptors.txt by scripts/registries/generate.mjs — do not edit by hand.\nexport const GATT_ASSIGNED_DESCRIPTORS: Record<string, number> = {\n  'gatt.characteristic_extended_properties': 0x2900,\n  'gatt.characteristic_user_description': 0x2901,\n  'gatt.client_characteristic_configuration': 0x2902,\n  'gatt.server_characteristic_configuration': 0x2903,\n  'gatt.characteristic_presentation_format': 0x2904,\n  'gatt.characteristic_aggregate_format': 0x2905,\n  'valid_range': 0x2906,\n  'external_report_reference': 0x2907,\n  'report_reference': 0x2908,\n  'number_of_digitals': 0x2909,\n  'value_trigger_setting': 0x290A,\n  'es_configuration': 0x290B,\n  'es_measurement': 0x290C,\n  'es_trigger_setting': 0x290D,\n  'time_trigger_setting': 0x290E,\n};\n// registries:end gatt-descriptors\n\n/** Expand a validated 16/32-bit alias into the canonical lowercase 128-bit UUID. */\nfunction hexToUUID(hex: number): string {\n  return hex.toString(16).padStart(8, \"0\") + BLUETOOTH_BASE_UUID_SUFFIX;\n}\n\n/**\n * `BluetoothUUID.canonicalUUID(alias)` (§7): expand a 16/32-bit alias into the\n * canonical lowercase 128-bit UUID string. Applies the WebIDL `[EnforceRange]\n * unsigned long` conversion: ToNumber, reject non-finite, truncate toward zero,\n * reject outside [0, 2^32 − 1]. Fractional/numeric-string inputs CONVERT.\n */\nexport function canonicalUUID(alias: number): string {\n  const converted = Number(alias);\n  if (!Number.isFinite(converted)) {\n    throw new TypeError(\n      `Failed to execute 'canonicalUUID' on 'BluetoothUUID': ` +\n        `Value is not a valid unsigned long: ${alias}`,\n    );\n  }\n  const truncated = Math.trunc(converted);\n  if (truncated < 0 || truncated > 0xffffffff) {\n    throw new TypeError(\n      `Failed to execute 'canonicalUUID' on 'BluetoothUUID': ` +\n        `Value is not a valid unsigned long: ${alias}`,\n    );\n  }\n  // `+ 0` normalizes -0 (from truncating e.g. -0.5) to 0.\n  return hexToUUID(truncated + 0);\n}\n\n/**\n * §7.1 ResolveUUIDName, scoped to a single GATT assigned-numbers table.\n * Names are table-scoped because the registries reuse names across categories\n * (`current_time` is service 0x1805 AND characteristic 0x2A2B), so\n * `getService` / `getCharacteristic` / `getDescriptor` each consult only their\n * own table.\n *\n *  1. unsigned long           → canonicalUUID(name)\n *  2. valid lowercase UUID    → pass through\n *  3. registered name         → canonicalUUID(alias) (case-folded lookup)\n *  4. otherwise               → throw a TypeError\n *\n * `String(name)` coerces page-realm non-string garbage so it stringifies (and\n * misses) rather than dying on `.toLowerCase`.\n */\nexport function resolveUUIDName(\n  name: string | number,\n  table: Record<string, number>,\n  getter: string,\n): string {\n  if (typeof name === \"number\") return canonicalUUID(name);\n  const value = String(name);\n  if (UUID_RE.test(value)) return value;\n  const alias = table[value.toLowerCase()];\n  if (alias !== undefined) return hexToUUID(alias);\n  throw new TypeError(\n    `Failed to execute '${getter}' on 'BluetoothUUID': Invalid UUID or registry name: \"${value}\"`,\n  );\n}\n","// GATT assigned-numbers tables + the §7.1 resolver (`canonicalUUID` /\n// `resolveUUIDName`) live in ONE generated module (DR-06): the npm core, the\n// extension-injected surface and the CDN polyfill all import them from there,\n// so the registry data + §7.1 semantics exist exactly once. The lenient,\n// fuzzy-matching SDK-level `resolveUUID` below is a separate, core-only helper\n// built on top of those shared tables. Regenerate the tables with:\n//   node scripts/registries/generate.mjs\nimport {\n  BLUETOOTH_BASE_UUID_SUFFIX as BASE_SUFFIX,\n  UUID_RE,\n  GATT_ASSIGNED_SERVICES as SERVICES,\n  GATT_ASSIGNED_CHARACTERISTICS as CHARACTERISTICS,\n  GATT_ASSIGNED_DESCRIPTORS as DESCRIPTORS,\n  canonicalUUID,\n  resolveUUIDName,\n} from './gatt-registry.generated';\n\nexport { canonicalUUID };\n\n/** Expand a validated 16/32-bit alias into the canonical lowercase 128-bit UUID. */\nfunction hexToUUID(hex: number): string {\n  return hex.toString(16).padStart(8, '0') + BASE_SUFFIX;\n}\n\n\n// Reverse maps for name lookups (built lazily)\nlet serviceNameMap: Map<string, string> | undefined;\nlet charNameMap: Map<string, string> | undefined;\n\nfunction getServiceNameMap(): Map<string, string> {\n  if (!serviceNameMap) {\n    serviceNameMap = new Map();\n    // First definition wins, so a canonical name (e.g. generic_access) beats its\n    // SIG abbreviation (gap) when multiple names map to the same UUID.\n    for (const [name, hex] of Object.entries(SERVICES)) {\n      const uuid = hexToUUID(hex);\n      if (!serviceNameMap.has(uuid)) serviceNameMap.set(uuid, name);\n    }\n  }\n  return serviceNameMap;\n}\n\nfunction getCharNameMap(): Map<string, string> {\n  if (!charNameMap) {\n    charNameMap = new Map();\n    // First definition wins (canonical name beats any SIG abbreviation alias).\n    for (const [name, hex] of Object.entries(CHARACTERISTICS)) {\n      const uuid = hexToUUID(hex);\n      if (!charNameMap.has(uuid)) charNameMap.set(uuid, name);\n    }\n  }\n  return charNameMap;\n}\n\nconst HEX4_RE = /^[0-9a-f]{4}$/;\nconst HEX8_RE = /^[0-9a-f]{8}$/;\n\n/** Single-row Levenshtein distance — O(m·n) time, O(n) space. */\nfunction levenshtein(a: string, b: string): number {\n  const m = a.length, n = b.length;\n  const row = Array.from({ length: n + 1 }, (_, i) => i);\n  for (let i = 1; i <= m; i++) {\n    let prev = i - 1;\n    row[0] = i;\n    for (let j = 1; j <= n; j++) {\n      const tmp = row[j];\n      row[j] = a[i - 1] === b[j - 1]\n        ? prev\n        : 1 + Math.min(prev, row[j], row[j - 1]);\n      prev = tmp;\n    }\n  }\n  return row[n];\n}\n\nfunction normalizeBluetoothName(input: string): string {\n  return input\n    .trim()\n    .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n    .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')\n    .replace(/[-.\\s]+/g, '_')\n    .replace(/_+/g, '_')\n    .replace(/^_+|_+$/g, '')\n    .toLowerCase();\n}\n\nfunction lookupNamedUUID(name: string, table: Record<string, number>): number | undefined {\n  const directMatch = table[name];\n  if (directMatch !== undefined) return directMatch;\n\n  // Registry names may contain dots and hyphens ('gap.device_name',\n  // 'ieee_11073-20601_…'); compare with all separators stripped so normalized\n  // camelCase/kebab-case inputs still match.\n  const compactName = name.replace(/[._-]/g, '');\n  if (!compactName) return undefined;\n\n  for (const [candidateName, candidateHex] of Object.entries(table)) {\n    if (candidateName.replace(/[._-]/g, '') === compactName) {\n      return candidateHex;\n    }\n  }\n\n  return undefined;\n}\n\n/**\n * Resolve a service/characteristic name, number, or short UUID to a full 128-bit UUID string.\n *\n * **Supported input formats:**\n * 1. **Named alias** -- Bluetooth SIG service or characteristic name (e.g. `'heart_rate'`, `'battery_level'`)\n * 2. **16-bit integer** -- Numeric service/characteristic ID (e.g. `0x180D`)\n * 3. **4-hex string** -- Short 16-bit hex (e.g. `'180d'`)\n * 4. **8-hex string** -- 32-bit hex (e.g. `'0000180d'`)\n * 5. **Full 128-bit UUID** -- Passed through unchanged (e.g. `'0000180d-0000-1000-8000-00805f9b34fb'`)\n *\n * **Fuzzy matching:** If the input looks like a name but does not match any known alias,\n * Levenshtein edit distance (threshold <= 3) is used to suggest corrections. Name\n * normalization converts camelCase/PascalCase to snake_case and replaces hyphens/dots/spaces\n * with underscores before matching.\n *\n * @param nameOrUUID - Service/characteristic name, hex string, numeric ID, or full UUID.\n * @returns Canonical lowercase 128-bit UUID string.\n *\n * @throws {TypeError} If a numeric input is out of the 32-bit unsigned range.\n * @throws {TypeError} If a string input is not a valid UUID format or known name (includes \"Did you mean?\" hint).\n *\n * @example\n * ```typescript\n * resolveUUID('heart_rate')      // '0000180d-0000-1000-8000-00805f9b34fb'\n * resolveUUID('180d')            // '0000180d-0000-1000-8000-00805f9b34fb'\n * resolveUUID(0x180D)            // '0000180d-0000-1000-8000-00805f9b34fb'\n * resolveUUID('battery_level')   // '00002a19-0000-1000-8000-00805f9b34fb'\n * resolveUUID('HeartRate')       // '0000180d-...' (camelCase normalized)\n * resolveUUID('heart_rat')       // throws Error: Did you mean \"heart_rate\"?\n * ```\n *\n * @see {@link getServiceName} for reverse lookup (UUID to name)\n * @see {@link getCharacteristicName} for reverse lookup (UUID to name)\n */\nexport function resolveUUID(nameOrUUID: string | number): string {\n  // Numeric input: 16-bit or 32-bit Bluetooth UUID integer\n  if (typeof nameOrUUID === 'number') {\n    if (!Number.isInteger(nameOrUUID) || nameOrUUID < 0 || nameOrUUID > 0xFFFFFFFF) {\n      throw new TypeError(`Invalid UUID integer: ${nameOrUUID}. Must be a 16-bit or 32-bit unsigned integer.`);\n    }\n    return hexToUUID(nameOrUUID);\n  }\n\n  const raw = nameOrUUID.trim();\n  const lower = raw.toLowerCase();\n\n  // Full 128-bit UUID\n  if (UUID_RE.test(lower)) return lower;\n\n  // 4-digit hex shorthand\n  if (HEX4_RE.test(lower)) return '0000' + lower + BASE_SUFFIX;\n\n  // 8-digit hex shorthand\n  if (HEX8_RE.test(lower)) return lower + BASE_SUFFIX;\n\n  // Exact registry-name match first — registry names may contain dots\n  // ('gap.device_name') that name normalization would otherwise destroy.\n  const exactAlias = SERVICES[lower] ?? CHARACTERISTICS[lower];\n  if (exactAlias !== undefined) return hexToUUID(exactAlias);\n\n  const normalizedName = normalizeBluetoothName(raw);\n\n  // Named service\n  const serviceHex = lookupNamedUUID(normalizedName, SERVICES);\n  if (serviceHex !== undefined) return hexToUUID(serviceHex);\n\n  // Named characteristic\n  const charHex = lookupNamedUUID(normalizedName, CHARACTERISTICS);\n  if (charHex !== undefined) return hexToUUID(charHex);\n\n  // Reject strings that don't look like valid UUIDs or hex shorthand.\n  // Likely a typo of a Bluetooth SIG name (e.g. \"heart_rat\" instead of \"heart_rate\").\n  // AIDEV-NOTE: Uses Levenshtein distance (≤3) with prefix fallback to catch typos\n  // beyond simple character-position mismatches (e.g. \"heartrate\" → \"heart_rate\").\n  const allNames = Object.keys(SERVICES).concat(Object.keys(CHARACTERISTICS));\n\n  // Levenshtein match — find the closest name within edit distance 3\n  let closest: string | undefined;\n  let bestDist = 4; // threshold + 1\n  for (const name of allNames) {\n    const d = levenshtein(normalizedName, name);\n    if (d < bestDist) {\n      bestDist = d;\n      closest = name;\n    }\n  }\n\n  // Prefix fallback — if no close Levenshtein match, check if input is a prefix\n  // of a known name (minimum 4 chars to avoid overly broad matches).\n  if (!closest && normalizedName.length >= 4) {\n    closest = allNames.find((name) => name.startsWith(normalizedName));\n  }\n\n  const hint = closest ? ` Did you mean \"${closest}\"?` : '';\n  // §7.1 ResolveUUIDName: \"Otherwise, throw a TypeError.\" (a real TypeError,\n  // so `err instanceof TypeError` holds for spec-conformant callers).\n  throw new TypeError(`Invalid UUID: \"${nameOrUUID}\". Expected a 128-bit UUID, 4/8-digit hex, or a known Bluetooth SIG name.${hint}`);\n}\n\n/**\n * Get the human-readable Bluetooth SIG service name for a UUID, if known.\n *\n * @param uuid - Full 128-bit UUID string (case-insensitive).\n * @returns Service name (e.g. `'heart_rate'`), or `undefined` if not a known SIG service.\n *\n * @see {@link resolveUUID} for the reverse operation (name to UUID)\n */\nexport function getServiceName(uuid: string): string | undefined {\n  return getServiceNameMap().get(uuid.toLowerCase());\n}\n\n/**\n * Get the human-readable Bluetooth SIG characteristic name for a UUID, if known.\n *\n * @param uuid - Full 128-bit UUID string (case-insensitive).\n * @returns Characteristic name (e.g. `'heart_rate_measurement'`), or `undefined` if not a known SIG characteristic.\n *\n * @see {@link resolveUUID} for the reverse operation (name to UUID)\n */\nexport function getCharacteristicName(uuid: string): string | undefined {\n  return getCharNameMap().get(uuid.toLowerCase());\n}\n\n/**\n * Format a Bluetooth SIG snake_case name (e.g. `'heart_rate'`) as Title Case\n * (e.g. `'Heart Rate'`) for display in a UI.\n *\n * Unknown inputs — anything that does not look like a snake_case SIG name, such\n * as a raw UUID string or hex shorthand — are returned unchanged so callers can\n * use the raw value as a fallback label.\n *\n * @param name - A snake_case SIG name, or a raw UUID/hex string.\n * @returns Title-cased name, or the input unchanged when it is not a SIG name.\n *\n * @example\n * ```typescript\n * getDisplayName('heart_rate')             // 'Heart Rate'\n * getDisplayName('heart_rate_measurement') // 'Heart Rate Measurement'\n * getDisplayName('gap.device_name')        // 'Device Name'\n * getDisplayName('0000180d-0000-1000-8000-00805f9b34fb') // (unchanged)\n * ```\n */\nexport function getDisplayName(name: string): string {\n  // Registry names in the GAP/GATT namespaces are dot-prefixed\n  // ('gap.device_name', 'gatt.client_characteristic_configuration'). The\n  // prefix is registry plumbing, not part of the SIG human-readable name —\n  // strip it before formatting so 0x2A00 displays as 'Device Name'.\n  const bare = name.replace(/^(gap|gatt)\\./, '');\n  // Raw UUIDs / hex shorthand are not SIG names — return them unchanged so the\n  // caller can show the raw identifier as a fallback label.\n  if (!/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/.test(bare)) return name;\n  return bare\n    .split('_')\n    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n    .join(' ');\n}\n\n// ---------------------------------------------------------------------------\n// BluetoothUUID — Web Bluetooth spec §4\n// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothuuid\n//\n// Static methods to resolve service, characteristic, and descriptor\n// names/aliases to canonical 128-bit UUID strings.\n// ---------------------------------------------------------------------------\n\n// Descriptor name → 16-bit alias map (descriptors are not part of\n// SERVICES/CHARACTERISTICS). Keys use the registry dot form, e.g.\n// 'gatt.client_characteristic_configuration'.\n\n\n// `canonicalUUID` and the §7.1 `resolveUUIDName` (used by `getDescriptor` and\n// the `BluetoothUUID` namespace below) are imported from\n// `./gatt-registry.generated` — the single source shared with the extension +\n// CDN surfaces (DR-06). `canonicalUUID` is re-exported at the top of this file.\n\n/**\n * Resolve a descriptor name or UUID alias to a canonical 128-bit UUID.\n * Implements `BluetoothUUID.getDescriptor()` from the Web Bluetooth spec\n * (§7.1 ResolveUUIDName against GATT assigned descriptors only): accepts a\n * registry descriptor name in its registry dot form\n * (e.g. `'gatt.client_characteristic_configuration'`), an integer alias, or\n * a valid lowercase 128-bit UUID. Anything else throws a TypeError.\n *\n * @param name - Descriptor name, 16/32-bit integer alias, or full UUID string.\n * @returns Canonical 128-bit UUID string.\n * @throws {TypeError} For unknown names, bare hex shorthand, or uppercase UUIDs.\n *\n * @example\n * ```typescript\n * getDescriptor('gatt.client_characteristic_configuration') // '00002902-...'\n * getDescriptor(0x2902)                                      // '00002902-...'\n * ```\n *\n * @see {@link resolveUUID} for the lenient SDK-level resolver\n */\nexport function getDescriptor(name: string | number): string {\n  return resolveUUIDName(name, DESCRIPTORS, 'getDescriptor');\n}\n\n/**\n * BluetoothUUID namespace object conforming to the Web Bluetooth spec.\n * Can be assigned to `window.BluetoothUUID` for spec compliance.\n * Each getter is scoped to its own GATT assigned-numbers table (§7.1).\n */\nexport const BluetoothUUID = {\n  canonicalUUID,\n  getService: (name: string | number) => resolveUUIDName(name, SERVICES, 'getService'),\n  getCharacteristic: (name: string | number) => resolveUUIDName(name, CHARACTERISTICS, 'getCharacteristic'),\n  getDescriptor,\n} as const;\n"]}