From 9496ee4d64d771c64cfb555f13350a75c156ac93 Mon Sep 17 00:00:00 2001 From: Mazeyar Moeini Feizabadi Date: Mon, 26 Oct 2026 16:29:48 +0100 Subject: [PATCH] fix: complete GhostMaps locale and voice integration with current main --- changelog.d/1297-s2-ghostmaps-layer.md | 2 ++ docs/CURRENT-STATE.md | 1 + scripts/package-boundaries.json | 1 + src/firstRunExperience.test.mjs | 5 +++-- src/i18n/locales/zh-CN.json | 26 +++++++++++++++++++++++++- src/i18n/same-as-english.json | 2 ++ src/voice/actionSchemas.test.mjs | 3 ++- src/voice/layerManifest.js | 4 +++- 8 files changed, 39 insertions(+), 5 deletions(-) diff --git a/changelog.d/1297-s2-ghostmaps-layer.md b/changelog.d/1297-s2-ghostmaps-layer.md index 938f5f89b..7dd52862d 100644 --- a/changelog.d/1297-s2-ghostmaps-layer.md +++ b/changelog.d/1297-s2-ghostmaps-layer.md @@ -10,3 +10,5 @@ - Release packed-image resources when a load is cancelled or fails, respect injected or omitted GhostMaps sources, and wait for background cache warm-up before removing provider test fixtures. +- Include Simplified Chinese translations and keep the combined voice prompt + within its existing size limit while retaining all spoken aliases. diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 5527e29b7..8c672d95c 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -5330,6 +5330,7 @@ request viewbox and continues searching without that geographic preference. - The row reads `LIVE` while the stream is open. A five-minute catalog read is the backstop. - **Files.** `/api/ghostmaps/file/{product}` serves only catalog products. Files are downloaded by commit-pinned raw URLs, so a CDN cannot return an older edition. They are cached on disk by blob sha, and blobs no current product uses are pruned. A request whose `?v=` names the current blob is `immutable`. Repository paths never reach the page. - **Source ownership.** The application catalog receives `sources['s2-ghostmaps']` through the shared source contracts; an omitted or null source stays unavailable without opening a stream or fetching. The standalone source factory supplies the same-origin implementation and accepts replacements. Packed-image URLs are released on cancelled or failed product construction, and remain owned by a successfully loaded product until it is removed. +- **Voice and locales.** S2 can be toggled through its registered id and aliases. The model already sees the S2 GhostMaps brand in the id, and compact alias-hint separators keep the complete voice prompt within its existing 52,000-character limit; accepted aliases are unchanged. The row and reports are translated in Spanish, Russian and Simplified Chinese. - **Rendering.** The page parses the KMZ with the import module's zip, KMZ and XML helpers into one `CustomDataSource` per product. - Points become ground-clamped billboards with the depth test off, so they never sink into terrain or 3D tiles. Because the Google 3D map hides the globe, nothing else would stop far-side pins drawing through the planet. Pins are therefore horizon-culled with Street Level's `createHorizonCull` before their first frame and again whenever the camera moves. - Lines and polygon outlines are ground-clamped polylines. diff --git a/scripts/package-boundaries.json b/scripts/package-boundaries.json index f99a0f43c..5fb99c576 100644 --- a/scripts/package-boundaries.json +++ b/scripts/package-boundaries.json @@ -3880,6 +3880,7 @@ "src/i18n/locale.js", "src/i18n/locales/es.json", "src/i18n/locales/ru.json", + "src/i18n/locales/zh-CN.json", "src/data/geoImportImages.js", "src/data/geoImportPins.js", "src/layers/streetLevel/tileMath.js", diff --git a/src/firstRunExperience.test.mjs b/src/firstRunExperience.test.mjs index 2b18c6825..15598d338 100644 --- a/src/firstRunExperience.test.mjs +++ b/src/firstRunExperience.test.mjs @@ -1054,10 +1054,11 @@ test('the voice TOOL SCHEMA matches the pinned contract — the mission mapping // Radio markup and the complete production-request comparison pin locality. // Restore the base camera/Globe View wording with the globe-rotation append. // S2 GhostMaps adds its layer id to the generated layer enums. - assert.equal(block.length, 30946, 'serialized tool schema length drifted'); + // Alias-hint separators omit spaces to keep the existing prompt budget. + assert.equal(block.length, 30888, 'serialized tool schema length drifted'); assert.equal( crypto.createHash('sha256').update(block).digest('hex'), - 'be53b22c55e620fb36c6ea0f276bfe5a59de47fa02ead99188ada40c0bf48cc0', + 'b809253254b5589f3c199c218b405d8f661f040962fdd841f1182e5009119420', 'the first-run missions must ride EXISTING tools: no schema edit, no cache bust', ); const instructions = fs.readFileSync( diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index e727b8516..ac15a9172 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -2818,5 +2818,29 @@ "Layers": "图层", "Search": "搜索", "More": "更多", - "Panels": "面板" + "Panels": "面板", + "S2 GhostMaps": "S2 GhostMaps", + "Intel Picture": "情报态势图", + "Kinetic 30d": "近 30 天军事行动", + "Border Crisis": "边境危机", + "Iran Picture": "伊朗态势图", + "Iran Kinetic": "伊朗军事行动", + "Yemen FLOT": "也门前线", + "Latest Drop": "最新发布", + "GhostMaps file could not be read": "无法读取 GhostMaps 文件", + "GhostMaps catalog unavailable": "GhostMaps 目录不可用", + "Malformed GhostMaps catalog": "GhostMaps 目录格式无效", + "{count} source links ↗ · click card to open the first": { + "other": "{count} 个来源链接 ↗ · 点击卡片打开第一个" + }, + "S2 · {name}": "S2 · {name}", + "Report": "报告", + "Open the source for {title}": "打开 {title} 的来源", + "LIVE · GitHub {commit} · {message} · checked every {seconds}s": "实时 · GitHub {commit} · {message} · 每 {seconds} 秒检查一次", + "GitHub {commit} · {message} · reconnecting for live updates": "GitHub {commit} · {message} · 正在重新连接以获取实时更新", + "Connecting to the S2 GhostMaps repository…": "正在连接 S2 GhostMaps 仓库…", + "{count} placemarks": { + "other": "{count} 个地标" + }, + "S2 Underground publishes these KMZ products to GitHub. New uploads are detected within seconds and replace the previous edition automatically. Click a marker for its report.": "S2 Underground 在 GitHub 发布这些 KMZ 产品。新上传的内容会在数秒内被检测到,并自动替换旧版本。点击标记查看报告。" } diff --git a/src/i18n/same-as-english.json b/src/i18n/same-as-english.json index 3a4a9e54a..05f5d3dee 100644 --- a/src/i18n/same-as-english.json +++ b/src/i18n/same-as-english.json @@ -169,6 +169,8 @@ "NVG", "REC", "SRC {value}", + "S2 GhostMaps", + "S2 · {name}", "Sentinel-2", "Techno", "Trance", diff --git a/src/voice/actionSchemas.test.mjs b/src/voice/actionSchemas.test.mjs index 617d0077f..4b88fa12d 100644 --- a/src/voice/actionSchemas.test.mjs +++ b/src/voice/actionSchemas.test.mjs @@ -43,7 +43,8 @@ test('the complete Realtime tool payload pins the manifest-generated layer relea // reset guidance/defaults update only move_camera and mode descriptions. // Restore base descriptions; append only globe-rotation defaults and fit guidance. // S2 GhostMaps adds its layer id to the generated layer enums. - '1f95d78074559217872ccbdfa57d4363264ea88c1a22b259e6ebba3c8189b806', + // Compact alias separators preserve the existing prompt budget. + '0128b5e28a8baf0d6466bfdbc6e7a80fd4bb32d0d22ccadfade2af641714f12a', ); }); diff --git a/src/voice/layerManifest.js b/src/voice/layerManifest.js index 14b515fa6..267399e58 100644 --- a/src/voice/layerManifest.js +++ b/src/voice/layerManifest.js @@ -525,6 +525,8 @@ const SELF_EVIDENT_IDS = new Set([ 'radio', 'wind', 'directions', + // The brand is already the layer id; all spoken aliases remain accepted. + 's2-ghostmaps', ]); /** @@ -539,7 +541,7 @@ export function voiceLayerAliasHint() { entry.toggle && entry.aliases.length && !SELF_EVIDENT_IDS.has(entry.id), ) .map((entry) => `${entry.aliases.slice(0, 2).join('/')}→${entry.id}`) - .join('; '); + .join(';'); } /** Field names that already carry their unit (altitudeM, speedKts, …). */