diff --git a/.claudedocs/sentry-triage/2026-02-19.md b/.claudedocs/sentry-triage/2026-02-19.md deleted file mode 100644 index c079e8be4..000000000 --- a/.claudedocs/sentry-triage/2026-02-19.md +++ /dev/null @@ -1,32 +0,0 @@ -# Sentry Triage — 2026-02-19 - -Commit: `09174fd` on `main` - -## Issues Triaged (5) - -### ACTIONABLE — Fixed in Code - -| ID | Title | Events | Users | Fix | -|---|---|---|---|---| -| WORLDMONITOR-1G | `Error: ML request unload-model timed out after 120000ms` | 30 | 27 | Wrapped `unloadModel()` in try/catch; timeout no longer leaks as unhandled rejection. Cleans up `loadedModels` set on failure. | -| WORLDMONITOR-1F | `Error: ML request unload-model timed out after 120000ms` | 9 | 9 | Same root cause as 1G (different release build hash). | -| WORLDMONITOR-1K | `TypeError: this.player.playVideo is not a function` | 1 | 1 | Added optional chaining (`playVideo?.()`, `pauseVideo?.()`) in `LiveNewsPanel.ts`. YT IFrame API player object may not have methods ready during initialization race. | - -### NOISE — Filtered - -| ID | Title | Events | Users | Filter | -|---|---|---|---|---| -| WORLDMONITOR-1J | `InternalError: too much recursion` | 1 | 1 | i18next internal `translate -> extractFromKey` cycle on Firefox 147. Added `/too much recursion/` to `ignoreErrors`. | -| WORLDMONITOR-1H | `TypeError: Cannot read properties of null (reading 'id')` | 1 | 1 | maplibre-gl internal render crash (`_drawLayers -> renderLayers`). Extended `beforeSend` regex to suppress null `id`/`type` when stack is in map chunk. | - -## Files Modified - -| File | Change | -|---|---| -| `src/services/ml-worker.ts` | `unloadModel()`: try/catch around `this.request()`, clean `loadedModels` on failure | -| `src/components/LiveNewsPanel.ts` | Optional chaining on `playVideo?.()` and `pauseVideo?.()` | -| `src/main.ts` | Added `/too much recursion/` to `ignoreErrors`; extended maplibre `beforeSend` filter for null `id`/`type` | - -## Sentry Status - -All 5 issues marked **resolved (in next release)** via API. They will auto-reopen if errors recur after deployment. diff --git a/.gitignore b/.gitignore index 077bfa24a..e0473ed68 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,4 @@ src-tauri/sidecar/node/* # Compiled sebuf gateway bundle (built by scripts/build-sidecar-sebuf.mjs) api/[[][[].*.js +.claudedocs/ diff --git a/src/app/search-manager.ts b/src/app/search-manager.ts index 468aeb2de..254b5773b 100644 --- a/src/app/search-manager.ts +++ b/src/app/search-manager.ts @@ -8,6 +8,7 @@ import { CIIPanel } from '@/components'; import { SITE_VARIANT, STORAGE_KEYS } from '@/config'; import { LAYER_PRESETS, LAYER_KEY_MAP } from '@/config/commands'; import { calculateCII, TIER1_COUNTRIES } from '@/services/country-instability'; +import { CURATED_COUNTRIES } from '@/config/countries'; import { INTEL_HOTSPOTS, CONFLICT_ZONES, MILITARY_BASES, UNDERSEA_CABLES, NUCLEAR_FACILITIES } from '@/config/geo'; import { PIPELINES } from '@/config/pipelines'; import { AI_DATA_CENTERS } from '@/config/ai-datacenters'; @@ -55,8 +56,8 @@ export class SearchManager implements AppModule { } : SITE_VARIANT === 'happy' ? { - placeholder: 'Search good news...', - hint: 'Search positive stories and breakthroughs', + placeholder: 'Search or type a command...', + hint: 'Good News • Countries • Navigation • Settings', } : SITE_VARIANT === 'finance' ? { @@ -468,6 +469,16 @@ export class SearchManager implements AppModule { case 'time': this.ctx.map?.setTimeRange(action as import('@/components').TimeRange); break; + + case 'country': { + const name = TIER1_COUNTRIES[action] + || CURATED_COUNTRIES[action]?.name + || new Intl.DisplayNames(['en'], { type: 'region' }).of(action) + || action; + trackCountrySelected(action, name, 'command'); + this.callbacks.openCountryBriefByCode(action, name); + break; + } } } diff --git a/src/components/SearchModal.ts b/src/components/SearchModal.ts index 961518acf..5569dfb5f 100644 --- a/src/components/SearchModal.ts +++ b/src/components/SearchModal.ts @@ -254,9 +254,12 @@ export class SearchModal { this.resultsList.innerHTML = `
-
🔍
+
\u2318
${t('modals.search.empty')}
${this.hint}
+
+ Try: dark mode iran military layers crypto +
`; } diff --git a/src/config/commands.ts b/src/config/commands.ts index 723054c52..8a0bd7678 100644 --- a/src/config/commands.ts +++ b/src/config/commands.ts @@ -1,11 +1,12 @@ import type { MapLayers } from '@/types'; +import { CURATED_COUNTRIES } from '@/config/countries'; export interface Command { id: string; keywords: string[]; label: string; icon: string; - category: 'navigate' | 'layers' | 'panels' | 'view' | 'actions'; + category: 'navigate' | 'layers' | 'panels' | 'view' | 'actions' | 'country'; } export const LAYER_PRESETS: Record = { @@ -104,3 +105,43 @@ export const COMMANDS: Command[] = [ { id: 'time:48h', keywords: ['48h', '2 days', 'last 2 days'], label: 'Show events from last 48 hours', icon: '\u{1F4C5}', category: 'actions' }, { id: 'time:7d', keywords: ['7d', 'week', 'last week', '7 days'], label: 'Show events from last 7 days', icon: '\u{1F5D3}\uFE0F', category: 'actions' }, ]; + +function toFlagEmoji(code: string): string { + return code.toUpperCase().split('').map(c => String.fromCodePoint(0x1f1e6 + c.charCodeAt(0) - 65)).join(''); +} + +// All ISO 3166-1 alpha-2 codes — Intl.DisplayNames resolves human-readable names at runtime +const ISO_CODES = [ + 'AD','AE','AF','AG','AL','AM','AO','AR','AT','AU','AZ','BA','BB','BD','BE','BF', + 'BG','BH','BI','BJ','BN','BO','BR','BS','BT','BW','BY','BZ','CA','CD','CF','CG', + 'CH','CI','CL','CM','CN','CO','CR','CU','CV','CY','CZ','DE','DJ','DK','DM','DO', + 'DZ','EC','EE','EG','ER','ES','ET','FI','FJ','FM','FR','GA','GB','GD','GE','GH', + 'GM','GN','GQ','GR','GT','GW','GY','HN','HR','HT','HU','ID','IE','IL','IN','IQ', + 'IR','IS','IT','JM','JO','JP','KE','KG','KH','KI','KM','KN','KP','KR','KW','KZ', + 'LA','LB','LC','LI','LK','LR','LS','LT','LU','LV','LY','MA','MC','MD','ME','MG', + 'MH','MK','ML','MM','MN','MR','MT','MU','MV','MW','MX','MY','MZ','NA','NE','NG', + 'NI','NL','NO','NP','NR','NZ','OM','PA','PE','PG','PH','PK','PL','PS','PT','PW', + 'PY','QA','RO','RS','RU','RW','SA','SB','SC','SD','SE','SG','SI','SK','SL','SM', + 'SN','SO','SR','SS','ST','SV','SY','SZ','TD','TG','TH','TJ','TL','TM','TN','TO', + 'TR','TT','TV','TW','TZ','UA','UG','US','UY','UZ','VA','VC','VE','VN','VU','WS', + 'YE','ZA','ZM','ZW', +]; + +const displayNames = new Intl.DisplayNames(['en'], { type: 'region' }); + +const COUNTRY_COMMANDS: Command[] = ISO_CODES.map(code => { + const curated = CURATED_COUNTRIES[code]; + const name = curated?.name || displayNames.of(code) || code; + const keywords = curated + ? [name.toLowerCase(), ...curated.searchAliases] + : [name.toLowerCase()]; + return { + id: `country:${code}`, + keywords, + label: `Open ${name} brief`, + icon: toFlagEmoji(code), + category: 'country' as const, + }; +}); + +COMMANDS.push(...COUNTRY_COMMANDS); diff --git a/src/locales/ar.json b/src/locales/ar.json index 73bf2d06c..b704ab085 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -205,14 +205,14 @@ }, "modals": { "search": { - "placeholder": "البحث في الأخبار، خطوط الأنابيب، القواعد، الأسواق...", - "hint": "أخبار • أنابيب • قواعد • كابلات • مراكز بيانات • أسواق", - "placeholderTech": "البحث في الشركات، مختبرات AI، الشركات الناشئة، الفعاليات...", - "hintTech": "مقرات • شركات • مختبرات AI • شركات ناشئة • مسرّعات • فعاليات", - "placeholderFinance": "البحث في البورصات، الأسواق، البنوك المركزية...", - "hintFinance": "بورصات • مراكز مالية • بنوك مركزية • سلع", + "placeholder": "ابحث أو اكتب أمرًا...", + "hint": "بحث • دول • طبقات • لوحات • تنقل • إعدادات", + "placeholderTech": "ابحث أو اكتب أمرًا...", + "hintTech": "بحث • شركات • مختبرات AI • طبقات • تنقل • إعدادات", + "placeholderFinance": "ابحث أو اكتب أمرًا...", + "hintFinance": "بحث • بورصات • أسواق • طبقات • تنقل • إعدادات", "recent": "عمليات البحث الأخيرة", - "empty": "البحث عبر جميع مصادر البيانات", + "empty": "ابحث في البيانات أو نفّذ أوامر", "noResults": "لا توجد نتائج", "navigate": "تنقّل", "select": "اختيار", diff --git a/src/locales/de.json b/src/locales/de.json index 7337635cb..6e8750322 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -205,10 +205,10 @@ }, "modals": { "search": { - "placeholder": "Durchsuchen Sie Nachrichten, Pipelines, Stützpunkte, Märkte ...", - "hint": "Nachrichten • Pipelines • Stützpunkte • Kabel • Rechenzentren • Märkte", + "placeholder": "Suchen oder Befehl eingeben...", + "hint": "Suche • Länder • Ebenen • Panels • Navigation • Einstellungen", "recent": "Aktuelle Suchanfragen", - "empty": "Durchsuchen Sie alle Datenquellen", + "empty": "Daten durchsuchen oder Befehle ausführen", "noResults": "No results found", "navigate": "navigieren", "select": "wählen", @@ -235,10 +235,10 @@ "techhq": "Tech-Hauptquartier", "accelerator": "Beschleuniger" }, - "placeholderTech": "Suchen Sie nach Unternehmen, KI-Laboren, Start-ups, Veranstaltungen ...", - "hintTech": "Hauptsitze • Unternehmen • KI-Labore • Startups • Beschleuniger • Veranstaltungen", - "placeholderFinance": "Suchen Sie nach Börsen, Märkten, Zentralbanken...", - "hintFinance": "Börsen • Finanzzentren • Zentralbanken • Rohstoffe" + "placeholderTech": "Suchen oder Befehl eingeben...", + "hintTech": "Suche • Unternehmen • KI-Labore • Ebenen • Navigation • Einstellungen", + "placeholderFinance": "Suchen oder Befehl eingeben...", + "hintFinance": "Suche • Börsen • Märkte • Ebenen • Navigation • Einstellungen" }, "signal": { "title": "INTELLIGENZFINDEN", diff --git a/src/locales/el.json b/src/locales/el.json index e0a3e86bf..a648e2784 100644 --- a/src/locales/el.json +++ b/src/locales/el.json @@ -205,14 +205,14 @@ }, "modals": { "search": { - "placeholder": "Αναζήτηση ειδήσεων, αγωγών, βάσεων, αγορών...", - "hint": "Ειδήσεις • Αγωγοί • Βάσεις • Καλώδια • Κέντρα Δεδομένων • Αγορές", - "placeholderTech": "Αναζήτηση εταιρειών, AI labs, startups, εκδηλώσεων...", - "hintTech": "Έδρες • Εταιρείες • AI Labs • Startups • Accelerators • Εκδηλώσεις", - "placeholderFinance": "Αναζήτηση χρηματιστηρίων, αγορών, κεντρικών τραπεζών...", - "hintFinance": "Χρηματιστήρια • Χρηματοπιστωτικά Κέντρα • Κεντρικές Τράπεζες • Εμπορεύματα", + "placeholder": "Αναζήτηση ή πληκτρολογήστε εντολή...", + "hint": "Αναζήτηση • Χώρες • Επίπεδα • Πάνελ • Πλοήγηση • Ρυθμίσεις", + "placeholderTech": "Αναζήτηση ή πληκτρολογήστε εντολή...", + "hintTech": "Αναζήτηση • Εταιρείες • AI Labs • Επίπεδα • Πλοήγηση • Ρυθμίσεις", + "placeholderFinance": "Αναζήτηση ή πληκτρολογήστε εντολή...", + "hintFinance": "Αναζήτηση • Χρηματιστήρια • Αγορές • Επίπεδα • Πλοήγηση • Ρυθμίσεις", "recent": "Πρόσφατες Αναζητήσεις", - "empty": "Αναζήτηση σε όλες τις πηγές δεδομένων", + "empty": "Αναζήτηση δεδομένων ή εκτέλεση εντολών", "noResults": "Κανένα αποτέλεσμα", "navigate": "πλοήγηση", "select": "επιλογή", diff --git a/src/locales/en.json b/src/locales/en.json index 30f6b47ff..cb67ba0b6 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -206,14 +206,14 @@ }, "modals": { "search": { - "placeholder": "Search news, pipelines, bases, markets...", - "hint": "News • Pipelines • Bases • Cables • Datacenters • Markets", - "placeholderTech": "Search companies, AI labs, startups, events...", - "hintTech": "HQs • Companies • AI Labs • Startups • Accelerators • Events", - "placeholderFinance": "Search exchanges, markets, central banks...", - "hintFinance": "Exchanges • Financial Centers • Central Banks • Commodities", + "placeholder": "Search or type a command...", + "hint": "Search • Countries • Layers • Panels • Navigation • Settings", + "placeholderTech": "Search or type a command...", + "hintTech": "Search • Companies • AI Labs • Layers • Navigation • Settings", + "placeholderFinance": "Search or type a command...", + "hintFinance": "Search • Exchanges • Markets • Layers • Navigation • Settings", "recent": "Recent Searches", - "empty": "Search across all data sources", + "empty": "Search data or run commands", "noResults": "No results", "navigate": "navigate", "select": "select", diff --git a/src/locales/es.json b/src/locales/es.json index 0730917b0..6eab5a4c8 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -205,10 +205,10 @@ }, "modals": { "search": { - "placeholder": "Busca noticias, pipelines, bases, mercados...", - "hint": "Noticias • Ductos • Bases • Cables • Datacenters • Mercados", + "placeholder": "Buscar o escribir un comando...", + "hint": "Búsqueda • Países • Capas • Paneles • Navegación • Ajustes", "recent": "Búsquedas recientes", - "empty": "Buscar en todas las fuentes de datos", + "empty": "Buscar datos o ejecutar comandos", "noResults": "No results found", "navigate": "navegar por", "select": "seleccionar", @@ -235,10 +235,10 @@ "techhq": "Sede tecnológica", "accelerator": "Aceleradora" }, - "placeholderTech": "Busca empresas, laboratorios de IA, startups, eventos...", - "hintTech": "Sedes centrales • Empresas • Laboratorios de IA • Startups • Aceleradoras • Eventos", - "placeholderFinance": "Buscar bolsas, mercados, bancos centrales...", - "hintFinance": "Bolsas • Centros financieros • Bancos centrales • Materias primas" + "placeholderTech": "Buscar o escribir un comando...", + "hintTech": "Búsqueda • Empresas • Laboratorios IA • Capas • Navegación • Ajustes", + "placeholderFinance": "Buscar o escribir un comando...", + "hintFinance": "Búsqueda • Bolsas • Mercados • Capas • Navegación • Ajustes" }, "signal": { "title": "ENCUENTRO DE INTELIGENCIA", diff --git a/src/locales/fr.json b/src/locales/fr.json index 67dc67dd9..6e00adbf6 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -205,10 +205,10 @@ }, "modals": { "search": { - "placeholder": "Rechercher actus, pipelines, bases, marchés...", - "hint": "Actus • Pipelines • Bases • Câbles • Datacenters • Marchés", + "placeholder": "Rechercher ou saisir une commande...", + "hint": "Recherche • Pays • Couches • Panneaux • Navigation • Paramètres", "recent": "Recherches récentes", - "empty": "Rechercher dans toutes les sources", + "empty": "Rechercher des données ou exécuter des commandes", "noResults": "Aucun résultat trouvé", "navigate": "naviguer", "select": "sélectionner", @@ -235,10 +235,10 @@ "techhq": "Siège Tech", "accelerator": "Accélérateur" }, - "placeholderTech": "Rechercher des entreprises, des laboratoires d'IA, des startups, des événements...", - "hintTech": "Sièges • Entreprises • AI Labs • Startups • Accélérateurs • Événements", - "placeholderFinance": "Rechercher des bourses, des marchés, des banques centrales...", - "hintFinance": "Bourses • Centres financiers • Banques centrales • Matières premières" + "placeholderTech": "Rechercher ou saisir une commande...", + "hintTech": "Recherche • Entreprises • Labos IA • Couches • Navigation • Paramètres", + "placeholderFinance": "Rechercher ou saisir une commande...", + "hintFinance": "Recherche • Bourses • Marchés • Couches • Navigation • Paramètres" }, "signal": { "title": "DÉCOUVERTE RENSEIGNEMENT", diff --git a/src/locales/it.json b/src/locales/it.json index e67584c96..af379f6d9 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -205,10 +205,10 @@ }, "modals": { "search": { - "placeholder": "Cerca notizie, oleodotti, basi, mercati...", - "hint": "Notizie • Oleodotti • Basi • Cavi • Datacenter • Mercati", + "placeholder": "Cerca o digita un comando...", + "hint": "Ricerca • Paesi • Livelli • Pannelli • Navigazione • Impostazioni", "recent": "Ricerche recenti", - "empty": "Cerca in tutte le fonti dati", + "empty": "Cerca dati o esegui comandi", "noResults": "Nessun risultato", "navigate": "naviga", "select": "seleziona", @@ -235,10 +235,10 @@ "techhq": "Sede tecnologica", "accelerator": "Acceleratore" }, - "placeholderTech": "Cerca aziende, laboratori IA, startup, eventi...", - "hintTech": "Sedi • Aziende • Laboratori IA • Startup • Acceleratori • Eventi", - "placeholderFinance": "Cerca borse, mercati, banche centrali...", - "hintFinance": "Borse • Centri finanziari • Banche centrali • Materie prime" + "placeholderTech": "Cerca o digita un comando...", + "hintTech": "Ricerca • Aziende • Laboratori IA • Livelli • Navigazione • Impostazioni", + "placeholderFinance": "Cerca o digita un comando...", + "hintFinance": "Ricerca • Borse • Mercati • Livelli • Navigazione • Impostazioni" }, "signal": { "title": "RICERCA DI INTELLIGENZA", diff --git a/src/locales/ja.json b/src/locales/ja.json index c90943c14..4e6188995 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -205,14 +205,14 @@ }, "modals": { "search": { - "placeholder": "ニュース、パイプライン、基地、市場を検索...", - "hint": "ニュース・パイプライン・基地・ケーブル・データセンター・市場", - "placeholderTech": "企業、AIラボ、スタートアップ、イベントを検索...", - "hintTech": "本社・企業・AIラボ・スタートアップ・アクセラレーター・イベント", - "placeholderFinance": "取引所、市場、中央銀行を検索...", - "hintFinance": "取引所・金融センター・中央銀行・コモディティ", + "placeholder": "検索またはコマンドを入力...", + "hint": "検索 • 国 • レイヤー • パネル • ナビゲーション • 設定", + "placeholderTech": "検索またはコマンドを入力...", + "hintTech": "検索 • 企業 • AIラボ • レイヤー • ナビゲーション • 設定", + "placeholderFinance": "検索またはコマンドを入力...", + "hintFinance": "検索 • 取引所 • 市場 • レイヤー • ナビゲーション • 設定", "recent": "最近の検索", - "empty": "全データソースを横断検索", + "empty": "データ検索またはコマンド実行", "noResults": "結果なし", "navigate": "移動", "select": "選択", diff --git a/src/locales/nl.json b/src/locales/nl.json index b8cd3d787..129ce587d 100644 --- a/src/locales/nl.json +++ b/src/locales/nl.json @@ -65,10 +65,10 @@ }, "modals": { "search": { - "placeholder": "Zoek naar nieuws, pijpleidingen, bases, markten...", - "hint": "Nieuws • Pijpleidingen • Basissen • Kabels • Datacentra • Markten", + "placeholder": "Zoeken of commando typen...", + "hint": "Zoeken • Landen • Lagen • Panelen • Navigatie • Instellingen", "recent": "Recente zoekopdrachten", - "empty": "Zoek in alle gegevensbronnen", + "empty": "Zoek gegevens of voer opdrachten uit", "noResults": "No results found", "navigate": "navigeren", "select": "selecteren", @@ -95,10 +95,10 @@ "techhq": "Tech-hoofdkantoor", "accelerator": "Gaspedaal" }, - "placeholderTech": "Zoek bedrijven, AI-labs, startups, evenementen...", - "hintTech": "Hoofdkantoren • Bedrijven • AI Labs • Startups • Accelerators • Evenementen", - "placeholderFinance": "Zoek beurzen, markten, centrale banken...", - "hintFinance": "Beurzen • Financiële centra • Centrale banken • Grondstoffen" + "placeholderTech": "Zoeken of commando typen...", + "hintTech": "Zoeken • Bedrijven • AI Labs • Lagen • Navigatie • Instellingen", + "placeholderFinance": "Zoeken of commando typen...", + "hintFinance": "Zoeken • Beurzen • Markten • Lagen • Navigatie • Instellingen" }, "signal": { "source": "Source", diff --git a/src/locales/pl.json b/src/locales/pl.json index bf6f30d35..c4a910dcb 100644 --- a/src/locales/pl.json +++ b/src/locales/pl.json @@ -205,10 +205,10 @@ }, "modals": { "search": { - "placeholder": "Szukaj aktualności, rurociągów, baz, rynków...", - "hint": "Aktualności • Rurociągi • Bazy • Kable • Centra danych • Rynki", + "placeholder": "Szukaj lub wpisz polecenie...", + "hint": "Szukaj • Kraje • Warstwy • Panele • Nawigacja • Ustawienia", "recent": "Ostatnie wyszukiwania", - "empty": "Przeszukuj wszystkie źródła danych", + "empty": "Szukaj danych lub uruchom polecenia", "noResults": "No results found", "navigate": "nawigować", "select": "wybierać", @@ -235,10 +235,10 @@ "techhq": "Siedziba technologiczna", "accelerator": "Akcelerator" }, - "placeholderTech": "Wyszukaj firmy, laboratoria AI, startupy, wydarzenia...", - "hintTech": "Siedziby główne • Firmy • Laboratoria AI • Startupy • Akceleratory • Wydarzenia", - "placeholderFinance": "Przeszukaj giełdy, rynki, banki centralne...", - "hintFinance": "Giełdy • Centra finansowe • Banki centralne • Towary" + "placeholderTech": "Szukaj lub wpisz polecenie...", + "hintTech": "Szukaj • Firmy • Laboratoria AI • Warstwy • Nawigacja • Ustawienia", + "placeholderFinance": "Szukaj lub wpisz polecenie...", + "hintFinance": "Szukaj • Giełdy • Rynki • Warstwy • Nawigacja • Ustawienia" }, "signal": { "title": "WYKONANIE INTELIGENCJI", diff --git a/src/locales/pt.json b/src/locales/pt.json index 3cf104a93..46253b0a1 100644 --- a/src/locales/pt.json +++ b/src/locales/pt.json @@ -65,10 +65,10 @@ }, "modals": { "search": { - "placeholder": "Pesquise notícias, pipelines, bases, mercados...", - "hint": "Notícias • Pipelines • Bases • Cabos • Datacenters • Mercados", + "placeholder": "Pesquisar ou digitar um comando...", + "hint": "Pesquisa • Países • Camadas • Painéis • Navegação • Configurações", "recent": "Pesquisas recentes", - "empty": "Pesquise em todas as fontes de dados", + "empty": "Pesquisar dados ou executar comandos", "noResults": "No results found", "navigate": "navegar", "select": "selecione", @@ -95,10 +95,10 @@ "techhq": "Sede de tecnologia", "accelerator": "Aceleradora" }, - "placeholderTech": "Pesquise empresas, laboratórios de IA, startups, eventos...", - "hintTech": "Sedes • Empresas • Laboratórios de IA • Startups • Aceleradoras • Eventos", - "placeholderFinance": "Pesquise bolsas, mercados, bancos centrais...", - "hintFinance": "Bolsas • Centros Financeiros • Bancos Centrais • Mercadorias" + "placeholderTech": "Pesquisar ou digitar um comando...", + "hintTech": "Pesquisa • Empresas • Laboratórios IA • Camadas • Navegação • Configurações", + "placeholderFinance": "Pesquisar ou digitar um comando...", + "hintFinance": "Pesquisa • Bolsas • Mercados • Camadas • Navegação • Configurações" }, "signal": { "source": "Source", diff --git a/src/locales/ru.json b/src/locales/ru.json index d39792c4c..e5ec17605 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -205,14 +205,14 @@ }, "modals": { "search": { - "placeholder": "Поиск новостей, трубопроводов, баз, рынков...", - "hint": "Новости • Трубопроводы • Базы • Кабели • Дата-центры • Рынки", - "placeholderTech": "Поиск компаний, ИИ-лабораторий, стартапов, мероприятий...", - "hintTech": "Штаб-квартиры • Компании • ИИ-лаборатории • Стартапы • Акселераторы • Мероприятия", - "placeholderFinance": "Поиск бирж, рынков, центральных банков...", - "hintFinance": "Биржи • Финансовые центры • Центральные банки • Сырьё", + "placeholder": "Поиск или введите команду...", + "hint": "Поиск • Страны • Слои • Панели • Навигация • Настройки", + "placeholderTech": "Поиск или введите команду...", + "hintTech": "Поиск • Компании • ИИ-лаборатории • Слои • Навигация • Настройки", + "placeholderFinance": "Поиск или введите команду...", + "hintFinance": "Поиск • Биржи • Рынки • Слои • Навигация • Настройки", "recent": "Недавние запросы", - "empty": "Поиск по всем источникам данных", + "empty": "Поиск данных или выполнение команд", "noResults": "Ничего не найдено", "navigate": "навигация", "select": "выбрать", diff --git a/src/locales/sv.json b/src/locales/sv.json index 18129e4d4..f35eb1682 100644 --- a/src/locales/sv.json +++ b/src/locales/sv.json @@ -65,10 +65,10 @@ }, "modals": { "search": { - "placeholder": "Sök efter nyheter, pipelines, baser, marknader...", - "hint": "Nyheter • Rörledningar • Baser • Kablar • Datacenter • Marknader", + "placeholder": "Sök eller skriv ett kommando...", + "hint": "Sök • Länder • Lager • Paneler • Navigering • Inställningar", "recent": "Senaste sökningar", - "empty": "Sök i alla datakällor", + "empty": "Sök data eller kör kommandon", "noResults": "No results found", "navigate": "navigera", "select": "välja", @@ -95,10 +95,10 @@ "techhq": "Teknikhuvudkontor", "accelerator": "Accelerator" }, - "placeholderTech": "Sök företag, AI-labb, startups, evenemang...", - "hintTech": "HQs • Företag • AI Labs • Startups • Acceleratorer • Events", - "placeholderFinance": "Sök börser, marknader, centralbanker...", - "hintFinance": "Börser • Finansiella centra • Centralbanker • Råvaror" + "placeholderTech": "Sök eller skriv ett kommando...", + "hintTech": "Sök • Företag • AI-labb • Lager • Navigering • Inställningar", + "placeholderFinance": "Sök eller skriv ett kommando...", + "hintFinance": "Sök • Börser • Marknader • Lager • Navigering • Inställningar" }, "signal": { "source": "Source", diff --git a/src/locales/th.json b/src/locales/th.json index b05b8cb0b..849b9a5dd 100644 --- a/src/locales/th.json +++ b/src/locales/th.json @@ -205,14 +205,14 @@ }, "modals": { "search": { - "placeholder": "ค้นหาข่าว, ท่อส่ง, ฐานทัพ, ตลาด...", - "hint": "ข่าว • ท่อส่ง • ฐานทัพ • สายเคเบิล • ศูนย์ข้อมูล • ตลาด", - "placeholderTech": "ค้นหาบริษัท, ห้องปฏิบัติการ AI, สตาร์ทอัพ, งาน...", - "hintTech": "สำนักงานใหญ่ • บริษัท • ห้องปฏิบัติการ AI • สตาร์ทอัพ • แอคเซเลอเรเตอร์ • งาน", - "placeholderFinance": "ค้นหาตลาดหลักทรัพย์, ตลาด, ธนาคารกลาง...", - "hintFinance": "ตลาดหลักทรัพย์ • ศูนย์กลางการเงิน • ธนาคารกลาง • สินค้าโภคภัณฑ์", + "placeholder": "ค้นหาหรือพิมพ์คำสั่ง...", + "hint": "ค้นหา • ประเทศ • เลเยอร์ • แผง • การนำทาง • การตั้งค่า", + "placeholderTech": "ค้นหาหรือพิมพ์คำสั่ง...", + "hintTech": "ค้นหา • บริษัท • ห้องปฏิบัติการ AI • เลเยอร์ • การนำทาง • การตั้งค่า", + "placeholderFinance": "ค้นหาหรือพิมพ์คำสั่ง...", + "hintFinance": "ค้นหา • ตลาดหลักทรัพย์ • ตลาด • เลเยอร์ • การนำทาง • การตั้งค่า", "recent": "การค้นหาล่าสุด", - "empty": "ค้นหาจากแหล่งข้อมูลทั้งหมด", + "empty": "ค้นหาข้อมูลหรือรันคำสั่ง", "noResults": "ไม่พบผลลัพธ์", "navigate": "นำทาง", "select": "เลือก", diff --git a/src/locales/tr.json b/src/locales/tr.json index 3b0e24e14..08bd15167 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -205,14 +205,14 @@ }, "modals": { "search": { - "placeholder": "Haberler, boru hatlari, usler, piyasalar ara...", - "hint": "Haberler - Boru Hatlari - Usler - Kablolar - Veri Merkezleri - Piyasalar", - "placeholderTech": "Sirketler, yapay zeka laboratuvarlari, girisimler, etkinlikler ara...", - "hintTech": "Merkezler - Sirketler - Yapay Zeka Lab. - Girisimler - Hizlandiricilar - Etkinlikler", - "placeholderFinance": "Borsalar, piyasalar, merkez bankalari ara...", - "hintFinance": "Borsalar - Finans Merkezleri - Merkez Bankalari - Emtialar", + "placeholder": "Ara veya komut yaz...", + "hint": "Arama • Ülkeler • Katmanlar • Paneller • Gezinme • Ayarlar", + "placeholderTech": "Ara veya komut yaz...", + "hintTech": "Arama • Şirketler • Yapay Zeka Lab. • Katmanlar • Gezinme • Ayarlar", + "placeholderFinance": "Ara veya komut yaz...", + "hintFinance": "Arama • Borsalar • Piyasalar • Katmanlar • Gezinme • Ayarlar", "recent": "Son Aramalar", - "empty": "Tum veri kaynaklarinda ara", + "empty": "Veri ara veya komut çalıştır", "noResults": "Sonuc bulunamadi", "navigate": "gezin", "select": "sec", diff --git a/src/locales/vi.json b/src/locales/vi.json index 82e22de43..56d6fffe2 100644 --- a/src/locales/vi.json +++ b/src/locales/vi.json @@ -205,14 +205,14 @@ }, "modals": { "search": { - "placeholder": "Tìm tin tức, đường ống, căn cứ, thị trường...", - "hint": "Tin tức • Đường ống • Căn cứ • Cáp ngầm • Trung tâm dữ liệu • Thị trường", - "placeholderTech": "Tìm công ty, phòng thí nghiệm AI, khởi nghiệp, sự kiện...", - "hintTech": "Trụ sở • Công ty • Phòng thí nghiệm AI • Khởi nghiệp • Vườn ươm • Sự kiện", - "placeholderFinance": "Tìm sàn giao dịch, thị trường, ngân hàng trung ương...", - "hintFinance": "Sàn giao dịch • Trung tâm Tài chính • Ngân hàng Trung ương • Hàng hóa", + "placeholder": "Tìm kiếm hoặc nhập lệnh...", + "hint": "Tìm kiếm • Quốc gia • Lớp • Bảng • Điều hướng • Cài đặt", + "placeholderTech": "Tìm kiếm hoặc nhập lệnh...", + "hintTech": "Tìm kiếm • Công ty • Phòng thí nghiệm AI • Lớp • Điều hướng • Cài đặt", + "placeholderFinance": "Tìm kiếm hoặc nhập lệnh...", + "hintFinance": "Tìm kiếm • Sàn giao dịch • Thị trường • Lớp • Điều hướng • Cài đặt", "recent": "Tìm kiếm Gần đây", - "empty": "Tìm kiếm trên tất cả nguồn dữ liệu", + "empty": "Tìm dữ liệu hoặc chạy lệnh", "noResults": "Không có kết quả", "navigate": "điều hướng", "select": "chọn", diff --git a/src/locales/zh.json b/src/locales/zh.json index de02b93f4..1f93853e7 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -205,14 +205,14 @@ }, "modals": { "search": { - "placeholder": "搜索新闻、管道、基地、市场...", - "hint": "新闻 • 管道 • 基地 • 电缆 • 数据中心 • 市场", - "placeholderTech": "搜索公司、AI实验室、创业公司、活动...", - "hintTech": "总部 • 公司 • AI实验室 • 创业公司 • 加速器 • 活动", - "placeholderFinance": "搜索交易所、市场、央行...", - "hintFinance": "交易所 • 金融中心 • 央行 • 大宗商品", + "placeholder": "搜索或输入命令...", + "hint": "搜索 • 国家 • 图层 • 面板 • 导航 • 设置", + "placeholderTech": "搜索或输入命令...", + "hintTech": "搜索 • 公司 • AI实验室 • 图层 • 导航 • 设置", + "placeholderFinance": "搜索或输入命令...", + "hintFinance": "搜索 • 交易所 • 市场 • 图层 • 导航 • 设置", "recent": "最近搜索", - "empty": "跨所有数据源搜索", + "empty": "搜索数据或执行命令", "noResults": "无结果", "navigate": "导航", "select": "选择", diff --git a/src/main.ts b/src/main.ts index cd59fd5d1..8d955d104 100644 --- a/src/main.ts +++ b/src/main.ts @@ -20,7 +20,7 @@ Sentry.init({ ignoreErrors: [ 'Invalid WebGL2RenderingContext', 'WebGL context lost', - /reading 'imageManager'/, + /imageManager/, /ResizeObserver loop/, /NotAllowedError/, /InvalidAccessError/, @@ -94,6 +94,10 @@ Sentry.init({ /Cannot define multiple custom elements/, /maxTextureDimension2D/, /Container app not found/, + /this\.St\.unref/, + /Invalid or unexpected token/, + /evaluating 'elemFound\.value'/, + /Cannot access '\w+' before initialization/, ], beforeSend(event) { const msg = event.exception?.values?.[0]?.value ?? ''; @@ -101,13 +105,17 @@ Sentry.init({ const frames = event.exception?.values?.[0]?.stacktrace?.frames ?? []; // Suppress maplibre internal null-access crashes (light, placement) only when stack is in map chunk if (/this\.style\._layers|reading '_layers'|this\.light is null|can't access property "(id|type|setFilter)", \w+ is (null|undefined)|Cannot read properties of null \(reading '(id|type|setFilter|_layers)'\)|null is not an object \(evaluating '(E\.|this\.style)|^\w{1,2} is null$/.test(msg)) { - if (frames.some(f => /\/(map|deck-stack)-[A-Za-z0-9]+\.js/.test(f.filename ?? ''))) return null; + if (frames.some(f => /\/(map|maplibre|deck-stack)-[A-Za-z0-9-]+\.js/.test(f.filename ?? ''))) return null; } // Suppress any TypeError that happens entirely within maplibre or deck.gl internals if (/^TypeError:/.test(msg) && frames.length > 0) { - const appFrames = frames.filter(f => f.in_app && !/\/sentry-[A-Za-z0-9]+\.js/.test(f.filename ?? '')); - if (appFrames.length > 0 && appFrames.every(f => /\/(map|deck-stack)-[A-Za-z0-9]+\.js/.test(f.filename ?? ''))) return null; + const appFrames = frames.filter(f => f.in_app && !/\/sentry-[A-Za-z0-9-]+\.js/.test(f.filename ?? '')); + if (appFrames.length > 0 && appFrames.every(f => /\/(map|maplibre|deck-stack)-[A-Za-z0-9-]+\.js/.test(f.filename ?? ''))) return null; } + // Suppress YouTube IFrame widget API internal errors + if (frames.some(f => /www-widgetapi\.js/.test(f.filename ?? ''))) return null; + // Suppress Sentry SDK internal crashes (logs.js) + if (frames.some(f => /\/ingest\/static\/logs\.js/.test(f.filename ?? ''))) return null; return event; }, }); diff --git a/src/styles/main.css b/src/styles/main.css index 655b50851..fdd844fa7 100644 --- a/src/styles/main.css +++ b/src/styles/main.css @@ -7341,6 +7341,21 @@ a.prediction-link:hover { opacity: 0.7; } +.search-empty-examples { + font-size: 11px; + margin-top: 12px; + opacity: 0.5; +} + +.search-empty-examples kbd { + background: var(--bg-tertiary, rgba(255,255,255,0.08)); + border-radius: 3px; + padding: 2px 6px; + font-size: 10px; + font-family: inherit; + margin: 0 2px; +} + .search-footer { display: flex; gap: 16px;