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;