diff --git a/index.html b/index.html index fe2ea0c..08823ca 100644 --- a/index.html +++ b/index.html @@ -43,6 +43,12 @@ .steps-list li { display: flex; gap: var(--kt-ai-space-4); } .step-n { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; background: var(--vibe-tint); color: var(--kt-ai-fg); display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 600; } .steps-list p { margin: 0; } + + .scheme-wrap { margin-top: var(--kt-ai-space-7); overflow-x: auto; } + #schemeSvg svg { display: block; width: 100%; min-width: 820px; height: auto; } + .scheme-legend { display: flex; gap: var(--kt-ai-space-6); flex-wrap: wrap; margin-top: var(--kt-ai-space-4); font-size: 13px; color: var(--kt-ai-fg-muted); } + .scheme-legend-item { display: inline-flex; align-items: center; gap: var(--kt-ai-space-2); } + .scheme-legend-line { display: inline-block; width: 28px; border-top: 2px solid var(--vibe-accent); } @@ -51,8 +57,9 @@
Помощник: экстренные службы + Схема Реестр окон - Схема + Как это работает
@@ -122,6 +129,20 @@ +
+
+
+

Схема маршрутизации для 727103 (Алматы)

+

Схема построена из данных реестра: владелец номера пересчёта 727103 — BRW SIP (7273130333), резерв — 7272222222 (SIP Trunk, принадлежит ГТС Алматы).

+
+
+
+ маршрут (мобильный и фиксированный) + резерв при недоступности SIP +
+
+
+
@@ -140,7 +161,7 @@

Формат оконечного номера — ABC21UV

-

Для Алматы: 7271UV. Реестр пополняется, а схема пересчитывается автоматически — введите номер в поле поиска и сверьте маршрут.

+

Для Алматы: 7271UV. Введите номер в поле поиска и сверьте: его данные подставятся в цепочки и в схему маршрутизации.

Перейти к поиску
diff --git a/script.js b/script.js index 9ba10a8..9ec679f 100644 --- a/script.js +++ b/script.js @@ -171,6 +171,7 @@ document.getElementById("r2src").textContent = "Станция владельца номера → SSW/NGN рег. → " + (d.entry ? d.entry.num : "оконечный номер"); renderChain("chain1", d.mobile); renderChain("chain2", d.fixed); + renderScheme(d.entry ? d.entry.num : num); } function renderRegister() { @@ -202,8 +203,116 @@ document.getElementById("regCounter").textContent = "Каждый номер: тип (ТДМ / GPON / SIP), станция владения, формат набора ABC21UV и резерв. В реестре: " + REG.length + "."; } + function renderScheme(focusNum) { + const NS = "http://www.w3.org/2000/svg"; + const svg = document.createElementNS(NS, "svg"); + svg.setAttribute("viewBox", "0 0 1100 460"); + svg.setAttribute("role", "img"); + svg.setAttribute("aria-label", "Схема маршрутизации вызовов экстренных служб"); + + const entry = findEntry(focusNum) || REG[0] || null; + const endNum = entry ? entry.num : "—"; + const hasBrw = entry ? normalize(entry.type).indexOf("BRW") === 0 : false; + + function rect(x, y, w, h, rx, fill, stroke, sw) { + const r = document.createElementNS(NS, "rect"); + r.setAttribute("x", x); r.setAttribute("y", y); + r.setAttribute("width", w); r.setAttribute("height", h); + r.setAttribute("rx", rx); + if (fill) r.setAttribute("fill", fill); + if (stroke) r.setAttribute("stroke", stroke); + r.setAttribute("stroke-width", sw || 1); + return r; + } + function txt(x, y, s, size, fill, weight) { + const t = document.createElementNS(NS, "text"); + t.setAttribute("x", x); t.setAttribute("y", y); + t.setAttribute("text-anchor", "middle"); + t.setAttribute("style", "font-size:" + size + "px; fill:" + fill + ";" + (weight ? " font-weight:" + weight + ";" : "")); + t.textContent = s; + return t; + } + function edge(x1, y1, x2, y2, dashed, label, ldy) { + const l = document.createElementNS(NS, "line"); + l.setAttribute("x1", x1); l.setAttribute("y1", y1); + l.setAttribute("x2", x2); l.setAttribute("y2", y2); + l.setAttribute("stroke", dashed ? "var(--kt-ai-fg-muted)" : "var(--vibe-accent)"); + l.setAttribute("stroke-width", "1.6"); + if (dashed) l.setAttribute("stroke-dasharray", "5 4"); + l.setAttribute("marker-end", "url(#arrow" + (dashed ? "M" : "A") + ")"); + l.setAttribute("opacity", "0.85"); + svg.appendChild(l); + if (label) { + const t = document.createElementNS(NS, "text"); + t.setAttribute("x", (x1 + x2) / 2); t.setAttribute("y", ((y1 + y2) / 2) + (ldy || -7)); + t.setAttribute("text-anchor", "middle"); + t.setAttribute("style", "font-size:10px; fill:var(--kt-ai-fg-muted)"); + t.textContent = label; + svg.appendChild(t); + } + } + + const defs = document.createElementNS(NS, "defs"); + defs.innerHTML = ''; + svg.appendChild(defs); + + edge(215, 60, 390, 170); + edge(385, 60, 530, 170); + edge(560, 204, 620, 266); + if (hasBrw) { + edge(695, 300, 656, 334); + } + edge(620, 300, 350, 335, true, "резерв при недоступности SIP", -7); + + const boxFill = "var(--kt-ai-card-bg)"; + const bStroke = "var(--kt-ai-border)"; + + // Мобильные операторы + svg.appendChild(rect(50, 32, 165, 56, 10, boxFill, bStroke)); + svg.appendChild(txt(132, 56, "Мобильные", 14, "var(--kt-ai-fg)", 600)); + svg.appendChild(txt(132, 73, "операторы", 14, "var(--kt-ai-fg)", 600)); + // ГТС + svg.appendChild(rect(220, 32, 165, 56, 10, boxFill, bStroke)); + svg.appendChild(txt(302, 63, "ГТС", 15, "var(--kt-ai-fg)", 600)); + // SSW/NGN транзит + svg.appendChild(rect(390, 170, 170, 56, 10, boxFill, bStroke)); + svg.appendChild(txt(475, 193, "SSW/NGN транзит", 14, "var(--kt-ai-fg)", 600)); + svg.appendChild(txt(475, 210, "транзитная шлюзовая система", 11, "var(--kt-ai-fg-muted)")); + // SSW/NGN рег. + svg.appendChild(rect(550, 266, 170, 56, 10, boxFill, bStroke)); + svg.appendChild(txt(635, 289, "SSW/NGN рег.", 14, "var(--kt-ai-fg)", 600)); + svg.appendChild(txt(635, 306, "региональная маршрутизация", 11, "var(--kt-ai-fg-muted)")); + // Резерв + svg.appendChild(rect(200, 335, 150, 56, 10, "var(--kt-ai-bg)", bStroke)); + svg.appendChild(txt(275, 358, "SIP Trunk (резерв)", 12, "var(--kt-ai-fg)", 600)); + svg.appendChild(txt(275, 375, "7272222222 · ГТС Алматы", 11, "var(--kt-ai-fg-muted)")); + // Оконечный номер + svg.appendChild(rect(700, 335, 190, 56, 10, "var(--kt-ai-bg)", hasBrw ? "var(--vibe-accent)" : bStroke, hasBrw ? 2 : 1)); + svg.appendChild(txt(795, 358, "Оконечный номер", 13, "var(--kt-ai-fg)", 600)); + svg.appendChild(txt(795, 375, endNum, 12, "var(--vibe-accent)", 600)); + // BRW SIP + if (hasBrw) { + svg.appendChild(rect(450, 335, 205, 56, 10, boxFill, bStroke)); + svg.appendChild(txt(552, 358, "BRW SIP", 14, "var(--kt-ai-fg)", 600)); + svg.appendChild(txt(552, 375, "7273130333", 12, "var(--kt-ai-fg-muted)", 600)); + const l1 = document.createElementNS(NS, "line"); + l1.setAttribute("x1", 655); l1.setAttribute("y1", 363); + l1.setAttribute("x2", 695); l1.setAttribute("y2", 363); + l1.setAttribute("stroke", "var(--vibe-accent)"); + l1.setAttribute("stroke-width", "1.6"); + l1.setAttribute("marker-end", "url(#arrowA)"); + l1.setAttribute("opacity", "0.85"); + svg.appendChild(l1); + } + + const el = document.getElementById("schemeSvg"); + el.innerHTML = ""; + el.appendChild(svg); + } + document.addEventListener("DOMContentLoaded", function () { renderRegister(); + renderScheme("727103"); const input = document.getElementById("num"); const btn = document.getElementById("findBtn"); btn.addEventListener("click", function () { show(input.value); });