@goodandready/dsh-russian-lang 0.3.8 → 0.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -226,7 +226,6 @@ window.__ModuleLoader__.load({
226
226
  // 1b. Пользовательские переопределения + плюрализация.
227
227
  // Overrides: пользовательский слой поверх словарей (russian-lang.overrides).
228
228
  // Plural: ядро выбирает .one/.other по n===1, русскому нужны few/many.
229
- const origTranslate = runtime.translate.bind(runtime)
230
229
  const getOverrides = () => {
231
230
  try {
232
231
  const value = scope.getSnapshot().value
@@ -234,26 +233,7 @@ window.__ModuleLoader__.load({
234
233
  } catch (err) { return {} }
235
234
  }
236
235
  const getPluginLocalizationStatus = makePluginLocalizationStatus(RU)
237
- try {
238
- runtime.formatNumber = formatNumber
239
- runtime.formatCompactNumber = formatCompactNumber
240
- runtime.formatDate = formatDate
241
- runtime.formatTokens = formatTokens
242
- runtime.formatRelativeTime = formatRelativeTime
243
- runtime.formatCurrency = formatCurrency
244
- runtime.inflect = inflect
245
- runtime.getPluginLocalizationStatus = getPluginLocalizationStatus
246
- runtime.stemRussian = stemRussian
247
- runtime.fuzzyMatchRu = fuzzyMatchRu
248
- runtime.humanizeError = humanizeError
249
- runtime.plural = plural
250
- runtime.pluralForm = pluralForm
251
- } catch (err) { /* ignore */ }
252
- // lookup: в ядре 0.1.2 lookup(ns, key, chain) требует третий довод —
253
- // цепочку языков; в старых ядрах его два. Спрашиваем у самого метода
254
- // (lookup.length), цепочку берём у ядра (fallbackChain приватный, но в
255
- // собранном коде доступен), иначе минимальная [active]. Голый вызов без
256
- // chain ронял чужой слот sidebar.workspaces (chain is not iterable).
236
+
257
237
  const lookupChain = () => {
258
238
  try {
259
239
  const chain = runtime.fallbackChain && runtime.fallbackChain(runtime.getLocale().active)
@@ -262,79 +242,62 @@ window.__ModuleLoader__.load({
262
242
  return [runtime.getLocale().active]
263
243
  }
264
244
  const translationRegistry = new Map()
265
- const lookup = (ns, key) => {
266
- const chain = lookupChain()
267
- return runtime.lookup.length >= 3 ? runtime.lookup(ns, key, chain) : runtime.lookup(ns, key)
245
+ const lookup = (ns, key) => (runtime.lookup.length >= 3 ? runtime.lookup(ns, key, lookupChain()) : runtime.lookup(ns, key))
246
+ const syncLang = () => {
247
+ try {
248
+ if (typeof document !== 'undefined' && document.documentElement && runtime.getLocale().active === 'ru') document.documentElement.lang = 'ru-RU'
249
+ } catch (err) { /* ignore */ }
268
250
  }
269
- runtime.translate = function (ns, key, params) {
270
- if (ns && !RU[ns] && !loadedPluginNames.has(ns)) schedulePluginLoad(ns)
271
- // 1. Пользовательский override — самый верхний слой.
272
- const overrides = getOverrides()
273
- if (overrides[key] !== undefined) {
274
- return params ? fill(overrides[key], params) : overrides[key]
275
- }
276
- // 2. Плюрализация для русского.
277
- if (runtime.getLocale().active === 'ru' && params) {
278
- const n = params.n ?? params.count
279
- if (typeof n === 'number') {
280
- const form = pluralForm(n)
281
- const m = /^(.*)[.](one|other)$/.exec(key)
282
- if (m) {
283
- // Ядро выбирает .one/.other по n===1; русскому нужны few/many.
284
- if (form === 'few' || form === 'many') {
285
- const pluralKey = m[1] + '.' + form
286
- const template = lookup(ns, pluralKey) ?? lookup('common', pluralKey)
287
- if (template !== undefined) {
288
- return fill(template, params)
251
+ const RUNTIME_PROP_NAMES = ['plural','pluralForm','formatDate','formatCompactNumber','formatTokens','formatNumber','formatRelativeTime','formatCurrency','inflect','getPluginLocalizationStatus','stemRussian','fuzzyMatchRu','humanizeError']
252
+ ctx.effect(() => {
253
+ const origTranslate = runtime.translate
254
+ const origProps = {}
255
+ for (const p of RUNTIME_PROP_NAMES) origProps[p] = runtime[p]
256
+ runtime.plural = plural
257
+ runtime.pluralForm = pluralForm
258
+ runtime.formatDate = formatDate
259
+ runtime.formatCompactNumber = formatCompactNumber
260
+ runtime.formatTokens = formatTokens
261
+ Object.assign(runtime, { formatNumber, formatRelativeTime, formatCurrency, inflect, getPluginLocalizationStatus, stemRussian, fuzzyMatchRu, humanizeError })
262
+ const boundOrig = typeof origTranslate === 'function' ? origTranslate.bind(runtime) : (() => '')
263
+ runtime.translate = function (ns, key, params) {
264
+ if (ns && !RU[ns] && !loadedPluginNames.has(ns)) schedulePluginLoad(ns)
265
+ const ov = getOverrides()
266
+ if (ov[key] !== undefined) return params ? fill(ov[key], params) : ov[key]
267
+ if (runtime.getLocale().active === 'ru' && params) {
268
+ const n = params.n ?? params.count
269
+ if (typeof n === 'number') {
270
+ const form = pluralForm(n)
271
+ const m = /^(.*)[.](one|other)$/.exec(key)
272
+ if (m) {
273
+ if (form === 'few' || form === 'many') {
274
+ const tmpl = lookup(ns, m[1] + '.' + form) ?? lookup('common', m[1] + '.' + form)
275
+ if (tmpl !== undefined) return fill(tmpl, params)
289
276
  }
290
- }
291
- } else if (form !== 'other' && !/[.](one|other|few|many)$/.test(key)) {
292
- // Счётный ключ без суффикса: t('X', {n}). Если словарь даёт формы
293
- // X.one / X.few / X.many - берём подходящую, иначе как раньше.
294
- const pluralKey = key + '.' + form
295
- const template = lookup(ns, pluralKey) ?? lookup('common', pluralKey)
296
- if (template !== undefined) {
297
- return fill(template, params)
277
+ } else if (form !== 'other' && !/[.](one|other|few|many)$/.test(key)) {
278
+ const tmpl = lookup(ns, key + '.' + form) ?? lookup('common', key + '.' + form)
279
+ if (tmpl !== undefined) return fill(tmpl, params)
298
280
  }
299
281
  }
300
282
  }
283
+ const res = boundOrig(ns, key, params)
284
+ if (typeof res === 'string' && res && res.length < 300) translationRegistry.set(res.trim(), { ns, key, params, value: res })
285
+ return res
301
286
  }
302
- const res = origTranslate(ns, key, params)
303
- if (typeof res === 'string' && res && res.length < 300) {
304
- translationRegistry.set(res.trim(), { ns, key, params, value: res })
287
+ let removeLang = null
288
+ if (!runtime.getLocale().locales.some((l) => l.id === 'ru') && typeof runtime.addLanguage === 'function') {
289
+ removeLang = runtime.addLanguage({ id: 'ru', label: 'Русский', fallback: 'en' })
290
+ syncLang()
305
291
  }
306
- return res
307
- }
308
-
309
- // 2. <html lang>: в таблице DOCUMENT_LANGUAGE ядра нет "ru", без нас там
310
- // окажется undefined после переключения.
311
- const syncLang = () => {
312
- try {
313
- if (typeof document !== 'undefined' && document.documentElement
314
- && runtime.getLocale().active === 'ru') {
315
- document.documentElement.lang = 'ru-RU'
292
+ return () => {
293
+ runtime.translate = origTranslate
294
+ for (const p of RUNTIME_PROP_NAMES) {
295
+ if (origProps[p] !== undefined) runtime[p] = origProps[p]
296
+ else delete runtime[p]
316
297
  }
317
- } catch (err) { /* ignore */ }
318
- }
319
-
320
- const native = runtime.getLocale().locales.some((l) => l.id === 'ru')
321
-
322
- if (!native) {
323
- // Ядро не знает ru: регистрируем его через addLanguage (реальный API
324
- // LocaleRuntime). Родная строка Language берёт меню из snapshot.locales,
325
- // setLocale() по нему же валидирует выбор — «Русский» появляется в
326
- // родном списке. (Старый код писал runtime.snapshot/publish напрямую —
327
- // этих методов в DSH 0.1.2-alpha нет, переключение молча не работало.)
328
- runtime.addLanguage({ id: 'ru', label: 'Русский', fallback: 'en' })
329
- syncLang()
330
-
331
- // Хост-monkey-patch (подмена runtime.host.getSnapshot/set ради
332
- // preference="ru") удалён: в DSH v0.1.2-alpha.2 settings пишется через
333
- // ctx.remote.settings.mutate, а adopt() читает preference из scope
334
- // snapshot напрямую. Подмена host конфликтовала с новой settings-mirror
335
- // и ломала запись namespace, из-за чего галочки не сохранялись. Выбор
336
- // языка держим своим russian-lang.enabled; включение делает tryBoot ниже.
337
- }
298
+ if (typeof removeLang === 'function') { try { removeLang() } catch (_) { /* bestEffort */ } }
299
+ }
300
+ }, 'dsh-russian-lang: runtime-lifecycle')
338
301
 
339
302
  // 3. Флаг russianLang.enabled всегда повторяет активный язык: выбор
340
303
  // английского или китайского в родном меню выключает русский и наоборот.
@@ -1333,7 +1296,7 @@ window.__ModuleLoader__.load({
1333
1296
  // #363: Живая типографика formatInputLive перед отправкой по Enter
1334
1297
  if (ev.key === 'Enter' && !ev.shiftKey && !ev.ctrlKey && !ev.altKey && !ev.metaKey) {
1335
1298
  const snapVal = scope ? (scope.getSnapshot().value || {}) : {}
1336
- const typoLive = snapVal.typography ? snapVal.typography.liveInput !== false : true
1299
+ const typoLive = snapVal.typography ? snapVal.typography.liveInput === true : false
1337
1300
  if (typoLive && typeof formatInputLive === 'function' && (el.tagName === 'TEXTAREA' || el.tagName === 'INPUT')) {
1338
1301
  const formatted = formatInputLive(value)
1339
1302
  if (formatted && formatted !== value) {
@@ -1345,7 +1308,7 @@ window.__ModuleLoader__.load({
1345
1308
  // #198 / #202: Защита ввода в Lexical composer и нативных полях
1346
1309
  try {
1347
1310
  const snapVal = scope ? (scope.getSnapshot().value || {}) : {}
1348
- const typoLive = snapVal.typography ? snapVal.typography.liveInput !== false : true
1311
+ const typoLive = snapVal.typography ? snapVal.typography.liveInput === true : false
1349
1312
  if (typoLive && !ev.ctrlKey && !ev.altKey && !ev.metaKey) {
1350
1313
  const isTextarea = el.tagName === 'TEXTAREA' || el.tagName === 'INPUT'
1351
1314
 
@@ -1884,9 +1847,8 @@ window.__ModuleLoader__.load({
1884
1847
  if (!text || typeof text !== 'string') return { error: 'Текст для перевода пуст.' }
1885
1848
  try {
1886
1849
  const res = await fetch('/api/dsh-russian-lang/translate', {
1887
- headers: { 'content-type': 'application/json', 'x-dsh-translator': '1' },
1888
1850
  method: 'POST',
1889
- headers: { 'content-type': 'application/json' },
1851
+ headers: { 'content-type': 'application/json', 'x-dsh-translator': '1' },
1890
1852
  body: JSON.stringify({ text })
1891
1853
  })
1892
1854
  const data = await res.json().catch(() => ({}))
@@ -2293,7 +2255,7 @@ window.__ModuleLoader__.load({
2293
2255
  React.createElement('label', { className: 'rl-item-label' },
2294
2256
  checkbox(value.slashAliases !== false && ruActive,
2295
2257
  (ev) => {
2296
- try { scope.set('slashAliases', ev.target.checked) } catch (err) { /* bestEffort */ void e; }
2258
+ try { scope.set('slashAliases', ev.target.checked) } catch (err) { /* bestEffort */ void err; }
2297
2259
  }, !ruActive || disabled),
2298
2260
  t('slashAliases')
2299
2261
  )
@@ -2498,7 +2460,7 @@ window.__ModuleLoader__.load({
2498
2460
  const v = newVal.trim()
2499
2461
  if (!k || !v) return
2500
2462
  const next = Object.assign({}, overrides, { [k]: v })
2501
- try { scope.set('overrides', updated) } catch (_e) { void _e }
2463
+ try { scope.set('overrides', next) } catch (_e) { void _e }
2502
2464
  setNewKey('')
2503
2465
  setNewVal('')
2504
2466
  },
@@ -2524,7 +2486,7 @@ window.__ModuleLoader__.load({
2524
2486
  onClick: () => {
2525
2487
  const next = Object.assign({}, overrides)
2526
2488
  delete next[k]
2527
- try { scope.set('overrides', updated) } catch (_e) { void _e }
2489
+ try { scope.set('overrides', next) } catch (_e) { void _e }
2528
2490
  },
2529
2491
  }, t('overrideDelete'))
2530
2492
  )
@@ -2609,65 +2571,7 @@ window.__ModuleLoader__.load({
2609
2571
  }
2610
2572
 
2611
2573
  const RL_CSS = [
2612
- '.rl-modal-mask{position:fixed;top:0;left:0;width:100vw;height:100vh;background:var(--dsw-alias-bg-mask);display:flex;align-items:center;justify-content:center;z-index:99999;backdrop-filter:blur(2px)}',
2613
- '.rl-modal-box{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;width:calc(100vw - 40px);max-width:500px;box-shadow:var(--dsw-alias-shadow-l3);display:flex;flex-direction:column;gap:12px;padding:18px}',
2614
- '.rl-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;overflow:hidden;transition:border-color .15s ease}',
2615
- '.rl-head{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;display:flex;align-items:center;gap:12px;padding:14px 18px}',
2616
- '.rl-head:hover{background:var(--dsw-alias-bg-layer-2)}',
2617
- '.rl-head-main{flex:1;display:flex;flex-direction:column;gap:4px}',
2618
- '.rl-title{color:var(--dsw-alias-label-primary);font-size:16px;font-weight:600;line-height:1.4;display:flex;align-items:center;flex-wrap:wrap;gap:8px}',
2619
- '.rl-sub{color:var(--dsw-alias-label-secondary);font-size:13px}',
2620
- '.rl-chev{margin-left:auto;flex:none;color:var(--dsw-alias-label-tertiary);display:inline-flex;transition:transform .16s}',
2621
- '.rl-chev-open{transform:rotate(180deg)}',
2622
- '.rl-body{border-top:1px solid var(--dsw-alias-border-l2);padding:18px}',
2623
- '.rl-page{display:flex;flex-direction:column;gap:16px;max-width:960px}',
2624
- '.rl-section-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:10px;padding:16px 18px;display:flex;flex-direction:column;gap:12px}',
2625
- '.rl-section-title{font-size:14px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between;gap:8px}',
2626
- '.rl-section-desc{font-size:12px;color:var(--dsw-alias-label-secondary);margin-top:-4px;line-height:1.4}',
2627
- '.rl-grid-2{display:grid;grid-template-columns:repeat(auto-fit, minmax(280px, 1fr));gap:10px}',
2628
- '.rl-grid-3{display:grid;grid-template-columns:repeat(auto-fit, minmax(140px, 1fr));gap:10px}',
2629
- '.rl-badge{font-size:11px;padding:2px 8px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);display:inline-flex;align-items:center;gap:4px;font-weight:500}',
2630
- '.rl-badge-ok{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 8%, transparent)}',
2631
- '.rl-badge-warn{border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary);background:color-mix(in srgb, var(--dsw-alias-state-warning-primary) 8%, transparent)}',
2632
- '.rl-badge-dim{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-3)}',
2633
- '.rl-item-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;padding:10px 12px;display:flex;flex-direction:column;gap:4px}',
2634
- '.rl-item-head{display:flex;align-items:center;justify-content:space-between;gap:8px}',
2635
- '.rl-item-label{font-size:13px;font-weight:500;color:var(--dsw-alias-label-primary);display:flex;align-items:center;gap:8px;cursor:pointer}',
2636
- '.rl-item-desc{font-size:11px;color:var(--dsw-alias-label-secondary);line-height:1.4}',
2637
- '.rl-stat-box{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;padding:10px 12px;display:flex;flex-direction:column;gap:2px}',
2638
- '.rl-stat-val{font-size:16px;font-weight:700;color:var(--dsw-alias-label-primary)}',
2639
- '.rl-stat-label{font-size:11px;color:var(--dsw-alias-label-secondary);letter-spacing:0.3px}',
2640
- '.rl-hotkey-box{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;padding:10px 12px;font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.4;display:flex;align-items:flex-start;gap:10px}',
2641
- '.rl-hotkey-tag{font-size:11px;font-weight:700;padding:2px 6px;border-radius:4px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);white-space:nowrap}',
2642
- '.rl-preview-box{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;padding:10px 12px;font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.4}',
2643
- '.rl-btn{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:6px 12px;font-size:12px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);font-weight:500;display:inline-flex;align-items:center;justify-content:center;gap:6px;transition:all .15s ease;text-decoration:none}',
2644
- '.rl-btn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-1);border-color:var(--dsw-alias-label-secondary)}',
2645
- '.rl-btn-primary{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3);border-color:transparent}',
2646
- '.rl-btn-primary:hover:not(:disabled){opacity:0.9}',
2647
- '.rl-select{height:32px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:6px;padding:0 8px;font-size:12px;outline:none;width:100%;max-width:380px}',
2648
- '.rl-select:focus{border-color:var(--dsw-alias-state-brand-primary)}',
2649
- '.rl-check{width:16px;height:16px;accent-color:var(--dsw-alias-label-primary);cursor:pointer;flex-shrink:0}',
2650
- '.rl-hint-text{font-size:11px;color:var(--dsw-alias-label-secondary);line-height:1.4}',
2651
- '.rl-actions-row{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding-top:4px}',
2652
- '.rl-lang-chip{appearance:none;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-secondary);font-size:11px;font-weight:700;padding:2px 7px;border-radius:6px;display:inline-flex;align-items:center;transition:all .15s;margin:0 4px}',
2653
- '.rl-lang-chip:hover{border-color:var(--dsw-alias-label-primary);color:var(--dsw-alias-label-primary)}',
2654
- '.rl-lang-chip-active{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}',
2655
- '.rl-action-btn{appearance:none;background:0 0;border:1px solid transparent;border-radius:4px;color:var(--dsw-alias-label-secondary);cursor:pointer;font-size:11px;padding:2px 5px;display:inline-flex;align-items:center;transition:all .15s}',
2656
- '.rl-action-btn:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3)}',
2657
- '.rl-action-btn-active{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-border-l2)}',
2658
- '.rl-turn-translation{margin:8px 0;padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:8px;font-size:13px;line-height:1.5}',
2659
- '.rl-trans-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;border-bottom:1px solid var(--dsw-alias-border-l2);padding-bottom:4px}',
2660
- '.rl-trans-title{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary);text-transform:uppercase;letter-spacing:0.5px}',
2661
- '.rl-trans-tools{display:flex;gap:4px}',
2662
- '.rl-trans-btn{appearance:none;background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);cursor:pointer;padding:2px 7px;border-radius:4px;font-size:11px}',
2663
- '.rl-trans-btn:hover{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}',
2664
- '.rl-trans-body{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;user-select:text}',
2665
- '.rl-export-md-btn{appearance:none;border:1px solid var(--dsw-alias-border-l2);height:32px;color:var(--dsw-alias-label-primary);cursor:pointer;background:transparent;border-radius:18px;justify-content:center;align-items:center;gap:4px;padding:6px 12px;font-size:13px;font-weight:500;display:inline-flex;white-space:nowrap;margin-left:6px;transition:all .15s ease}',
2666
- '.rl-export-md-btn:hover{background:var(--dsw-alias-interactive-bg-hover)}',
2667
- '.rl-inspector-hover{position:absolute;pointer-events:none;border:2px solid var(--dsw-alias-state-brand-primary);border-radius:4px;background:color-mix(in srgb,var(--dsw-alias-state-brand-primary) 12%,transparent);box-shadow:0 0 10px color-mix(in srgb,var(--dsw-alias-state-brand-primary) 30%,transparent);z-index:99998;transition:all .06s ease;display:none}',
2668
- '.rl-inspector-badge{position:absolute;bottom:calc(100% + 4px);left:0;background:var(--dsw-alias-state-brand-primary);color:var(--dsw-alias-label-inverse);font-size:10px;font-weight:600;padding:2px 6px;border-radius:4px;white-space:nowrap;box-shadow:var(--dsw-alias-shadow-l2);pointer-events:none}',
2669
- '.rl-inspector-pill{position:fixed;bottom:18px;right:18px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l1);border-radius:20px;padding:6px 12px;box-shadow:var(--dsw-alias-shadow-l3);display:none;align-items:center;gap:8px;font-size:12px;z-index:99990;user-select:none}',
2670
- '.rl-inspector-pill-active{border-color:var(--dsw-alias-state-brand-primary);box-shadow:0 0 12px color-mix(in srgb,var(--dsw-alias-state-brand-primary) 35%,transparent)}',
2574
+ '.rl-modal-mask{position:fixed;top:0;left:0;width:100vw;height:100vh;background:var(--dsw-alias-bg-mask);display:flex;align-items:center;justify-content:center;z-index:99999;backdrop-filter:blur(2px)}.rl-modal-box{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;width:calc(100vw - 40px);max-width:500px;box-shadow:var(--dsw-alias-shadow-l3);display:flex;flex-direction:column;gap:12px;padding:18px}.rl-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;overflow:hidden;transition:border-color .15s ease}.rl-head{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;display:flex;align-items:center;gap:12px;padding:14px 18px}.rl-head:hover{background:var(--dsw-alias-bg-layer-2)}.rl-head-main{flex:1;display:flex;flex-direction:column;gap:4px}.rl-title{color:var(--dsw-alias-label-primary);font-size:16px;font-weight:600;line-height:1.4;display:flex;align-items:center;flex-wrap:wrap;gap:8px}.rl-sub{color:var(--dsw-alias-label-secondary);font-size:13px}.rl-chev{margin-left:auto;flex:none;color:var(--dsw-alias-label-tertiary);display:inline-flex;transition:transform .16s}.rl-chev-open{transform:rotate(180deg)}.rl-body{border-top:1px solid var(--dsw-alias-border-l2);padding:18px}.rl-page{display:flex;flex-direction:column;gap:16px;max-width:960px}.rl-section-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:10px;padding:16px 18px;display:flex;flex-direction:column;gap:12px}.rl-section-title{font-size:14px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between;gap:8px}.rl-section-desc{font-size:12px;color:var(--dsw-alias-label-secondary);margin-top:-4px;line-height:1.4}.rl-grid-2{display:grid;grid-template-columns:repeat(auto-fit, minmax(280px, 1fr));gap:10px}.rl-grid-3{display:grid;grid-template-columns:repeat(auto-fit, minmax(140px, 1fr));gap:10px}.rl-badge{font-size:11px;padding:2px 8px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);display:inline-flex;align-items:center;gap:4px;font-weight:500}.rl-badge-ok{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 8%, transparent)}.rl-badge-warn{border-color:var(--dsw-alias-state-warning-primary);color:var(--dsw-alias-state-warning-primary);background:color-mix(in srgb, var(--dsw-alias-state-warning-primary) 8%, transparent)}.rl-badge-dim{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-3)}.rl-item-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;padding:10px 12px;display:flex;flex-direction:column;gap:4px}.rl-item-head{display:flex;align-items:center;justify-content:space-between;gap:8px}.rl-item-label{font-size:13px;font-weight:500;color:var(--dsw-alias-label-primary);display:flex;align-items:center;gap:8px;cursor:pointer}.rl-item-desc{font-size:11px;color:var(--dsw-alias-label-secondary);line-height:1.4}.rl-stat-box{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;padding:10px 12px;display:flex;flex-direction:column;gap:2px}.rl-stat-val{font-size:16px;font-weight:700;color:var(--dsw-alias-label-primary)}.rl-stat-label{font-size:11px;color:var(--dsw-alias-label-secondary);letter-spacing:0.3px}.rl-hotkey-box{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;padding:10px 12px;font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.4;display:flex;align-items:flex-start;gap:10px}.rl-hotkey-tag{font-size:11px;font-weight:700;padding:2px 6px;border-radius:4px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);white-space:nowrap}.rl-preview-box{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;padding:10px 12px;font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.4}.rl-btn{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:6px 12px;font-size:12px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);font-weight:500;display:inline-flex;align-items:center;justify-content:center;gap:6px;transition:all .15s ease;text-decoration:none}.rl-btn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-1);border-color:var(--dsw-alias-label-secondary)}.rl-btn-primary{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3);border-color:transparent}.rl-btn-primary:hover:not(:disabled){opacity:0.9}.rl-select{height:32px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:6px;padding:0 8px;font-size:12px;outline:none;width:100%;max-width:380px}.rl-select:focus{border-color:var(--dsw-alias-state-brand-primary)}.rl-check{width:16px;height:16px;accent-color:var(--dsw-alias-label-primary);cursor:pointer;flex-shrink:0}.rl-hint-text{font-size:11px;color:var(--dsw-alias-label-secondary);line-height:1.4}.rl-actions-row{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding-top:4px}.rl-lang-chip{appearance:none;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-secondary);font-size:11px;font-weight:700;padding:2px 7px;border-radius:6px;display:inline-flex;align-items:center;transition:all .15s;margin:0 4px}.rl-lang-chip:hover{border-color:var(--dsw-alias-label-primary);color:var(--dsw-alias-label-primary)}.rl-lang-chip-active{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.rl-action-btn{appearance:none;background:0 0;border:1px solid transparent;border-radius:4px;color:var(--dsw-alias-label-secondary);cursor:pointer;font-size:11px;padding:2px 5px;display:inline-flex;align-items:center;transition:all .15s}.rl-action-btn:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3)}.rl-action-btn-active{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-border-l2)}.rl-turn-translation{margin:8px 0;padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:8px;font-size:13px;line-height:1.5}.rl-trans-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;border-bottom:1px solid var(--dsw-alias-border-l2);padding-bottom:4px}.rl-trans-title{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary);text-transform:uppercase;letter-spacing:0.5px}.rl-trans-tools{display:flex;gap:4px}.rl-trans-btn{appearance:none;background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);cursor:pointer;padding:2px 7px;border-radius:4px;font-size:11px}.rl-trans-btn:hover{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.rl-trans-body{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;user-select:text}.rl-export-md-btn{appearance:none;border:1px solid var(--dsw-alias-border-l2);height:32px;color:var(--dsw-alias-label-primary);cursor:pointer;background:transparent;border-radius:18px;justify-content:center;align-items:center;gap:4px;padding:6px 12px;font-size:13px;font-weight:500;display:inline-flex;white-space:nowrap;margin-left:6px;transition:all .15s ease}.rl-export-md-btn:hover{background:var(--dsw-alias-interactive-bg-hover)}.rl-inspector-hover{position:absolute;pointer-events:none;border:2px solid var(--dsw-alias-state-brand-primary);border-radius:4px;background:color-mix(in srgb,var(--dsw-alias-state-brand-primary) 12%,transparent);box-shadow:0 0 10px color-mix(in srgb,var(--dsw-alias-state-brand-primary) 30%,transparent);z-index:99998;transition:all .06s ease;display:none}.rl-inspector-badge{position:absolute;bottom:calc(100% + 4px);left:0;background:var(--dsw-alias-state-brand-primary);color:var(--dsw-alias-label-inverse);font-size:10px;font-weight:600;padding:2px 6px;border-radius:4px;white-space:nowrap;box-shadow:var(--dsw-alias-shadow-l2);pointer-events:none}.rl-inspector-pill{position:fixed;bottom:18px;right:18px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l1);border-radius:20px;padding:6px 12px;box-shadow:var(--dsw-alias-shadow-l3);display:none;align-items:center;gap:8px;font-size:12px;z-index:99990;user-select:none}.rl-inspector-pill-active{border-color:var(--dsw-alias-state-brand-primary);box-shadow:0 0 12px color-mix(in srgb,var(--dsw-alias-state-brand-primary) 35%,transparent)}'
2671
2575
  ].join('')
2672
2576
  const STYLE_ID = 'dsh-russian-lang-styles'
2673
2577
  if (typeof document !== 'undefined' && (document.getElementById && !document.getElementById(STYLE_ID))) {