|
66 | 66 | var params = getScriptParams(); |
67 | 67 |
|
68 | 68 | // ── Determine locale ────────────────────────────────────────────────── |
69 | | - function resolveLocale(tag) { |
70 | | - if (!tag) return "en"; |
71 | | - if (messages[tag]) return tag; |
72 | | - var lower = tag.toLowerCase(); |
73 | | - for (var key in messages) { |
74 | | - if (key.toLowerCase() === lower) return key; |
| 69 | + function getBestLocale(desired, available) { |
| 70 | + var dLen = 0; |
| 71 | + if (!desired || !(dLen = desired.length) || !available) return null; |
| 72 | + |
| 73 | + var d = new Array(dLen); |
| 74 | + var dS = new Array(dLen); |
| 75 | + var dC = new Array(dLen); |
| 76 | + |
| 77 | + function matchLang(k, d) { |
| 78 | + var kLen = k.length; |
| 79 | + var dLen = d.length; |
| 80 | + var kChr; |
| 81 | + var dChr; |
| 82 | + var kBal; |
| 83 | + var dBal; |
| 84 | + for (var i = 0; (kBal = i < kLen && (kChr = k[i]) !== '-') & (dBal = i < dLen && (dChr = d[i]) !== '-'); i++) { |
| 85 | + if (kChr !== dChr && kChr.toLowerCase() !== dChr.toLowerCase()) return ~i; |
| 86 | + } |
| 87 | + return kBal || dBal ? ~i : i; |
75 | 88 | } |
76 | | - var base = tag.split("-")[0].toLowerCase(); |
77 | | - if (messages[base]) return base; |
78 | | - for (var key2 in messages) { |
79 | | - if (key2.toLowerCase().split("-")[0] === base) return key2; |
| 89 | + |
| 90 | + var b = null; |
| 91 | + var bW = null; |
| 92 | + for (var key in available) { |
| 93 | + var a = null; |
| 94 | + var s = null; |
| 95 | + var prio = -1; |
| 96 | + var l = null; |
| 97 | + var script = null; |
| 98 | + for (var i = 0; i < dLen; i++) { |
| 99 | + var sep = matchLang(key, desired[i]); |
| 100 | + if (sep < 0) continue; |
| 101 | + if (!a) try { |
| 102 | + a = new Intl.Locale(key); |
| 103 | + s = a.script || a.maximize().script; |
| 104 | + } catch (e) {} |
| 105 | + l = d[i]; |
| 106 | + try { |
| 107 | + script = l ? l.script || dS[i] : (l = d[i] = new Intl.Locale(desired[i])).script || (dS[i] ||= l.maximize().script); |
| 108 | + } catch (e) {} |
| 109 | + if (script === s) { |
| 110 | + prio = i; |
| 111 | + break; |
| 112 | + } |
| 113 | + } |
| 114 | + if (prio < 0) continue; |
| 115 | + s = a.script; |
| 116 | + var c = a.region; |
| 117 | + var w = prio << 5 | (sep + (s ? s.length + 1 : 0) + (c ? c.length + 1 : 0) != key.length) << 4; |
| 118 | + if ((s && l.script || c && l.region) && c === l.region) { |
| 119 | + w |= !s | !c << 1 | !(s === l.script) << 2; |
| 120 | + } else { |
| 121 | + w |= 8 | !!c << 2 | !!s << 1; |
| 122 | + if (c) try { |
| 123 | + w |= c !== (dC[prio] ||= new Intl.Locale(d[prio].language, { script: script }).maximize().region); |
| 124 | + } catch (e) {} |
| 125 | + } |
| 126 | + if (bW === null || w < bW) { |
| 127 | + b = key; |
| 128 | + bW = w; |
| 129 | + } |
80 | 130 | } |
81 | | - return "en"; |
| 131 | + return b; |
82 | 132 | } |
83 | 133 |
|
84 | | - var locale = resolveLocale( |
85 | | - params.lang || |
| 134 | + var locales = navigator.languages; |
| 135 | + var preferred = params.lang || |
86 | 136 | document.documentElement.lang || |
87 | 137 | navigator.language || |
88 | | - navigator.userLanguage |
89 | | - ); |
| 138 | + navigator.userLanguage; |
| 139 | + if (!locales || !locales.length || preferred !== locales[0]) locales = [...preferred.split(',').map(p => p.trim()), ...locales]; |
| 140 | + |
| 141 | + var locale = messages[locales[0]] ? locales[0] : getBestLocale(locales, messages) || 'en'; |
90 | 142 |
|
91 | 143 | // ── Size variant ────────────────────────────────────────────────────── |
92 | 144 | var size = params.size === "mini" ? "mini" : "normal"; |
|
306 | 358 | var p = pfx[offset]; |
307 | 359 | var s = sfx[offset]; |
308 | 360 | return string.slice( |
309 | | - trimConjunction && p || (p == 1 && string[0] === "+") ? pfx[offset] : 0, |
310 | | - trimSuffix && s ? -sfx[offset] : string.length |
| 361 | + trimConjunction && p || (p == 1 && string[0] === "+") ? p : 0, |
| 362 | + trimSuffix && s ? -s : string.length |
311 | 363 | ); |
312 | 364 | } |
313 | 365 |
|
|
319 | 371 | var now = new Date().getTime(); |
320 | 372 | var distance = countDownDate - now; |
321 | 373 |
|
| 374 | + if (distance < 0) { |
| 375 | + clearInterval(timer); |
| 376 | + return; |
| 377 | + } |
| 378 | + |
322 | 379 | var days = Math.floor(distance / (1000 * 60 * 60 * 24)); |
323 | 380 | var hours = Math.floor( |
324 | 381 | (distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60) |
|
342 | 399 | remaining[6] = getLocalizedUnit(seconds, "second", parts++, false); |
343 | 400 |
|
344 | 401 | countdownSpan.textContent = remaining.join(""); |
345 | | - |
346 | | - if (distance < 0) { |
347 | | - clearInterval(timer); |
348 | | - } |
349 | 402 | } |
350 | 403 |
|
351 | 404 | timer = setInterval(updateBanner, 1000); |
|
0 commit comments