urfu-ui-kit-react 2.0.6-next.2 → 2.1.1

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.
Files changed (129) hide show
  1. package/README.md +157 -144
  2. package/dist/components/Accordion/Accordion.d.ts +1 -1
  3. package/dist/components/Accordion/Accordion.d.ts.map +1 -1
  4. package/dist/components/BreadCrumbs/BreadCrumbs.d.ts +1 -1
  5. package/dist/components/Button/Button.d.ts +1 -1
  6. package/dist/components/Calendar/Calendar.d.ts.map +1 -1
  7. package/dist/components/Calendar/Calendar.types.d.ts +2 -1
  8. package/dist/components/Calendar/Calendar.types.d.ts.map +1 -1
  9. package/dist/components/Card/Card.d.ts +1 -1
  10. package/dist/components/Checkbox/Checkbox.d.ts +1 -1
  11. package/dist/components/ColumnSettings/ColumnSettings.d.ts +1 -1
  12. package/dist/components/ColumnSettings/ColumnSettings.d.ts.map +1 -1
  13. package/dist/components/ErrorScreen/ErrorScreen.d.ts +16 -3
  14. package/dist/components/ErrorScreen/ErrorScreen.d.ts.map +1 -1
  15. package/dist/components/ErrorScreen/ErrorScreenIllustration.d.ts +17 -0
  16. package/dist/components/ErrorScreen/ErrorScreenIllustration.d.ts.map +1 -0
  17. package/dist/components/FormField/FormField.d.ts +1 -1
  18. package/dist/components/Icon/Icon.d.ts +2 -2
  19. package/dist/components/Icon/Icon.d.ts.map +1 -1
  20. package/dist/components/Icon/Icon.types.d.ts +5 -0
  21. package/dist/components/Icon/Icon.types.d.ts.map +1 -1
  22. package/dist/components/InputExpandTextarea/InputExpandTextarea.d.ts +1 -1
  23. package/dist/components/InputExpandTextarea/InputExpandTextarea.d.ts.map +1 -1
  24. package/dist/components/InputExpandTextarea/InputExpandTextarea.types.d.ts +2 -1
  25. package/dist/components/InputExpandTextarea/InputExpandTextarea.types.d.ts.map +1 -1
  26. package/dist/components/InputFile/InputFile.d.ts +1 -1
  27. package/dist/components/InputNumber/InputNumber.d.ts +2 -2
  28. package/dist/components/InputNumber/InputNumber.d.ts.map +1 -1
  29. package/dist/components/InputNumber/InputNumber.types.d.ts +6 -0
  30. package/dist/components/InputNumber/InputNumber.types.d.ts.map +1 -1
  31. package/dist/components/InputText/InputAffix.d.ts +47 -0
  32. package/dist/components/InputText/InputAffix.d.ts.map +1 -0
  33. package/dist/components/InputText/InputText.d.ts +3 -2
  34. package/dist/components/InputText/InputText.d.ts.map +1 -1
  35. package/dist/components/InputText/InputText.types.d.ts +40 -1
  36. package/dist/components/InputText/InputText.types.d.ts.map +1 -1
  37. package/dist/components/InputTime/InputTime.d.ts +2 -2
  38. package/dist/components/InputTime/InputTime.d.ts.map +1 -1
  39. package/dist/components/InputTime/InputTime.types.d.ts +8 -1
  40. package/dist/components/InputTime/InputTime.types.d.ts.map +1 -1
  41. package/dist/components/Menu/Menu.d.ts +1 -1
  42. package/dist/components/Message/Message.d.ts +1 -1
  43. package/dist/components/Modal/Modal.d.ts +1 -1
  44. package/dist/components/Modal/Modal.d.ts.map +1 -1
  45. package/dist/components/Modal/useModalTitleClearance.d.ts.map +1 -1
  46. package/dist/components/Multiselect/Multiselect.d.ts +2 -2
  47. package/dist/components/Multiselect/Multiselect.d.ts.map +1 -1
  48. package/dist/components/Multiselect/Multiselect.types.d.ts +8 -1
  49. package/dist/components/Multiselect/Multiselect.types.d.ts.map +1 -1
  50. package/dist/components/Notification/Notification.d.ts +24 -3
  51. package/dist/components/Notification/Notification.d.ts.map +1 -1
  52. package/dist/components/Preloader/Preloader.d.ts +1 -1
  53. package/dist/components/Radio/Radio.d.ts +1 -1
  54. package/dist/components/Search/Search.d.ts +2 -2
  55. package/dist/components/Search/Search.d.ts.map +1 -1
  56. package/dist/components/Search/Search.types.d.ts +6 -0
  57. package/dist/components/Search/Search.types.d.ts.map +1 -1
  58. package/dist/components/SearchSelect/SearchSelect.d.ts +1 -1
  59. package/dist/components/SearchSelect/SearchSelect.d.ts.map +1 -1
  60. package/dist/components/SearchSelect/SearchSelect.types.d.ts +2 -1
  61. package/dist/components/SearchSelect/SearchSelect.types.d.ts.map +1 -1
  62. package/dist/components/Select/Select.d.ts +1 -1
  63. package/dist/components/Select/Select.d.ts.map +1 -1
  64. package/dist/components/Select/Select.types.d.ts +2 -1
  65. package/dist/components/Select/Select.types.d.ts.map +1 -1
  66. package/dist/components/Status/Status.d.ts +1 -1
  67. package/dist/components/StickyActionBar/StickyActionBar.d.ts +1 -1
  68. package/dist/components/StickyActionBar/StickyActionBar.d.ts.map +1 -1
  69. package/dist/components/Switch/Switch.d.ts +2 -2
  70. package/dist/components/Table/Filter/Filter.d.ts +1 -1
  71. package/dist/components/Table/Filter/Filter.d.ts.map +1 -1
  72. package/dist/components/Table/Filter/FilterBoxShell.d.ts.map +1 -1
  73. package/dist/components/Table/Filter/FilterSortIndicator.d.ts.map +1 -1
  74. package/dist/components/Table/Table.d.ts +2 -2
  75. package/dist/components/Table/Table.d.ts.map +1 -1
  76. package/dist/components/Table/Table.types.d.ts +8 -0
  77. package/dist/components/Table/Table.types.d.ts.map +1 -1
  78. package/dist/components/Table/TableHead.d.ts.map +1 -1
  79. package/dist/components/Table/useDelayedSkeleton.d.ts +23 -0
  80. package/dist/components/Table/useDelayedSkeleton.d.ts.map +1 -0
  81. package/dist/components/Table/useTableColumnPinning.d.ts.map +1 -1
  82. package/dist/components/Table/useTableSortState.d.ts.map +1 -1
  83. package/dist/components/Table/useTableVirtualization.d.ts.map +1 -1
  84. package/dist/components/Tabs/Tabs.d.ts +1 -1
  85. package/dist/components/Tabs/Tabs.d.ts.map +1 -1
  86. package/dist/components/Tabs/Tabs.types.d.ts +11 -2
  87. package/dist/components/Tabs/Tabs.types.d.ts.map +1 -1
  88. package/dist/components/Tabs/distributeTabs.d.ts +14 -2
  89. package/dist/components/Tabs/distributeTabs.d.ts.map +1 -1
  90. package/dist/components/Tabs/useTabsOverflow.d.ts +4 -0
  91. package/dist/components/Tabs/useTabsOverflow.d.ts.map +1 -1
  92. package/dist/components/Textarea/Textarea.d.ts +2 -2
  93. package/dist/components/Textarea/Textarea.d.ts.map +1 -1
  94. package/dist/components/Textarea/Textarea.types.d.ts +8 -1
  95. package/dist/components/Textarea/Textarea.types.d.ts.map +1 -1
  96. package/dist/components/Tooltip/Tooltip.d.ts +1 -1
  97. package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
  98. package/dist/components/TreeView/TreeView.d.ts +1 -1
  99. package/dist/components/TreeView/TreeView.d.ts.map +1 -1
  100. package/dist/components/TreeView/TreeView.types.d.ts +2 -1
  101. package/dist/components/TreeView/TreeView.types.d.ts.map +1 -1
  102. package/dist/dev/index.js +852 -0
  103. package/dist/dev/types/react/src/dev/index.d.ts +15 -0
  104. package/dist/dev/types/vanilla/src/dev/index.d.ts +17 -0
  105. package/dist/dev/types/vanilla/src/dev/intercept.d.ts +32 -0
  106. package/dist/dev/types/vanilla/src/dev/journal.d.ts +29 -0
  107. package/dist/dev/types/vanilla/src/dev/panel.d.ts +8 -0
  108. package/dist/dev/types/vanilla/src/dev/shown.d.ts +24 -0
  109. package/dist/dev/types/vanilla/src/dev/store.d.ts +44 -0
  110. package/dist/dev/types/vanilla/src/dev/types.d.ts +83 -0
  111. package/dist/index.d.ts +7 -6
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/responsive/uiKitResponsive.d.ts +7 -0
  114. package/dist/responsive/uiKitResponsive.d.ts.map +1 -1
  115. package/dist/shared/devLauncherOffset.d.ts +8 -0
  116. package/dist/shared/devLauncherOffset.d.ts.map +1 -0
  117. package/dist/shared/popupTransition.d.ts +1 -1
  118. package/dist/shared/size.d.ts +15 -1
  119. package/dist/shared/size.d.ts.map +1 -1
  120. package/dist/shared/uiKitDefaults.d.ts +12 -0
  121. package/dist/shared/uiKitDefaults.d.ts.map +1 -1
  122. package/dist/style-no-fonts.css +1 -1
  123. package/dist/style.css +1 -1
  124. package/dist/style.layer.css +154 -0
  125. package/dist/style.shell.css +45 -0
  126. package/dist/urfu-ui-kit-react.js +7905 -7371
  127. package/dist/utils/describeError.d.ts +27 -0
  128. package/dist/utils/describeError.d.ts.map +1 -1
  129. package/package.json +110 -79
@@ -0,0 +1,852 @@
1
+ import { useSyncExternalStore as Rt } from "react";
2
+ let M = [], It = 1;
3
+ const N = /* @__PURE__ */ new Set();
4
+ let P = !1;
5
+ function _() {
6
+ P || (P = !0, setTimeout(() => {
7
+ P = !1, N.forEach((t) => t());
8
+ }, 16));
9
+ }
10
+ function zt(t, e, n) {
11
+ const a = Date.now(), r = { id: It++, service: t, method: e.toUpperCase(), path: n, status: "pending", duration: null, endedAt: null, faked: !1 };
12
+ M = [...M.slice(-49), r], _();
13
+ let o = !1;
14
+ return (i, s) => {
15
+ o || (o = !0, r.status = i, r.faked = s, r.endedAt = Date.now(), r.duration = r.endedAt - a, _());
16
+ };
17
+ }
18
+ function Y() {
19
+ return [...M].reverse();
20
+ }
21
+ function ct() {
22
+ M = [], P = !1, _();
23
+ }
24
+ function qt(t) {
25
+ return N.add(t), () => {
26
+ N.delete(t);
27
+ };
28
+ }
29
+ const ut = "urfu-ui-kit:dev:", m = /* @__PURE__ */ new Map(), B = /* @__PURE__ */ new Set();
30
+ let dt;
31
+ const ft = (t) => `${ut}${t}`, jt = ["offline", "network", "slow"];
32
+ let E = null;
33
+ const O = /* @__PURE__ */ new Set();
34
+ function Ut() {
35
+ let t;
36
+ try {
37
+ t = new URLSearchParams(window.location.search).get("dev");
38
+ } catch {
39
+ return;
40
+ }
41
+ if (t !== null) {
42
+ if (t === "off") {
43
+ E = null;
44
+ try {
45
+ Object.keys(localStorage).filter((e) => e.startsWith(ut)).forEach((e) => localStorage.removeItem(e));
46
+ } catch {
47
+ }
48
+ } else
49
+ E = t.split(",").map((e) => e.trim()).filter(Boolean), O.clear();
50
+ try {
51
+ const e = new URL(window.location.href);
52
+ e.searchParams.delete("dev"), window.history.replaceState(window.history.state, "", e.href);
53
+ } catch {
54
+ }
55
+ }
56
+ }
57
+ function Ft(t) {
58
+ return [...jt, ...t.builtins ?? [], ...(t.groups ?? []).flatMap((e) => e.items.map((n) => n.id))];
59
+ }
60
+ function Ht(t) {
61
+ if (!E || O.has(t.config.service)) return;
62
+ const e = new Set(Ft(t.config)), n = E.filter((a) => e.has(a));
63
+ n.length && (O.add(t.config.service), t.state = { ...t.state, faults: n }, F(t.config.service, t.state));
64
+ }
65
+ function Nt(t) {
66
+ try {
67
+ const e = JSON.parse(localStorage.getItem(ft(t)) ?? "null");
68
+ return {
69
+ faults: Array.isArray(e == null ? void 0 : e.faults) ? e.faults.filter((n) => typeof n == "string") : [],
70
+ rules: Array.isArray(e == null ? void 0 : e.rules) ? e.rules : [],
71
+ ...(e == null ? void 0 : e.launcher) === "visible" || (e == null ? void 0 : e.launcher) === "hidden" ? { launcher: e.launcher } : {}
72
+ };
73
+ } catch {
74
+ return { faults: [], rules: [] };
75
+ }
76
+ }
77
+ function F(t, e) {
78
+ try {
79
+ localStorage.setItem(ft(t), JSON.stringify(e));
80
+ } catch {
81
+ }
82
+ }
83
+ function _t(t) {
84
+ t && (dt = t);
85
+ }
86
+ function Bt() {
87
+ return dt;
88
+ }
89
+ function Wt(t) {
90
+ const e = { config: t, state: Nt(t.service) };
91
+ return Ht(e), m.set(t.service, e), C(), e;
92
+ }
93
+ function Kt(t) {
94
+ m.delete(t), m.size || (E = null, O.clear()), C();
95
+ }
96
+ function v() {
97
+ return [...m.values()];
98
+ }
99
+ function Jt(t) {
100
+ return t ? m.get(t) : m.values().next().value;
101
+ }
102
+ function pt(t) {
103
+ return B.add(t), () => {
104
+ B.delete(t);
105
+ };
106
+ }
107
+ function C() {
108
+ B.forEach((t) => t());
109
+ }
110
+ function H(t, e) {
111
+ t.state = e, F(t.config.service, e), C();
112
+ }
113
+ function Zt(t, e, n) {
114
+ const a = t.state.faults.filter((r) => r !== e);
115
+ H(t, { ...t.state, faults: n ? [...a, e] : a });
116
+ }
117
+ function Xt(t, e) {
118
+ const n = `rule-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
119
+ H(t, { ...t.state, rules: [...t.state.rules, { ...e, id: n, enabled: !0 }] });
120
+ }
121
+ function Vt(t, e, n) {
122
+ H(t, { ...t.state, rules: t.state.rules.map((a) => a.id === e ? { ...a, enabled: n } : a) });
123
+ }
124
+ function Gt(t, e) {
125
+ H(t, { ...t.state, rules: t.state.rules.filter((n) => n.id !== e) });
126
+ }
127
+ function Yt() {
128
+ m.forEach((t) => {
129
+ t.state = { faults: [], rules: [], ...t.state.launcher ? { launcher: t.state.launcher } : {} }, F(t.config.service, t.state);
130
+ }), C();
131
+ }
132
+ function R(t) {
133
+ return t.state.faults.length + t.state.rules.filter((e) => e.enabled).length;
134
+ }
135
+ function Qt(t) {
136
+ return t.state.launcher ?? t.config.launcher ?? "visible";
137
+ }
138
+ function tt(t) {
139
+ m.forEach((e) => {
140
+ e.state = { ...e.state, launcher: t }, F(e.config.service, e.state);
141
+ }), C();
142
+ }
143
+ const te = 1e4, et = 200, L = ".u-error-screen, .u-notification-fail, .u-notification-warning, .u-offline-banner-offline";
144
+ let I = [], ee = 1;
145
+ const W = /* @__PURE__ */ new WeakMap(), z = /* @__PURE__ */ new Set();
146
+ let w = null;
147
+ const x = (t) => {
148
+ const e = (t ?? "").replace(/\s+/g, " ").trim();
149
+ return e.length > et ? `${e.slice(0, et - 1)}…` : e;
150
+ }, ne = (t) => t.status === "network" || typeof t.status == "number" && t.status >= 400;
151
+ function ae(t, e) {
152
+ var s;
153
+ const n = v().map((l) => l.config.service), a = (s = e.closest("[data-name]")) == null ? void 0 : s.getAttribute("data-name"), r = a && n.includes(a) ? a : null, o = Y().find((l) => ne(l) && l.endedAt !== null && t - l.endedAt <= te && (!r || l.service === r));
154
+ if (!o) return;
155
+ const i = `${o.method} ${o.path} → ${o.status === "network" ? "сеть" : o.status}`;
156
+ return n.length > 1 ? `${o.service}: ${i}` : i;
157
+ }
158
+ function oe(t) {
159
+ var a, r, o;
160
+ if (t.classList.contains("u-error-screen"))
161
+ return {
162
+ kind: "screen",
163
+ // Код — в data-error-code на корне заглушки: крупный код рисуется не у всех вариантов (forbidden, serverError).
164
+ // .u-error-screen-code — для разметки кита до появления атрибута.
165
+ code: x(t.dataset.errorCode || ((a = t.querySelector(".u-error-screen-code")) == null ? void 0 : a.textContent)) || void 0,
166
+ title: x((r = t.querySelector(".u-error-screen-title")) == null ? void 0 : r.textContent) || x(t.getAttribute("aria-label")) || "Заглушка",
167
+ text: x((o = t.querySelector(".u-error-screen-description")) == null ? void 0 : o.textContent) || void 0
168
+ };
169
+ if (t.classList.contains("u-offline-banner-offline"))
170
+ return { kind: "offline", title: x(t.textContent) || "Нет связи" };
171
+ const e = t.classList.contains("u-notification-fail") ? "fail" : "warning", n = t.querySelector(".u-notification-content") ?? t;
172
+ return { kind: "notification", variant: e, title: x(n.textContent) || "Уведомление" };
173
+ }
174
+ function nt(t) {
175
+ if (!t.isConnected || !t.matches(L)) return;
176
+ const e = oe(t);
177
+ if (!e) return;
178
+ const n = JSON.stringify(e);
179
+ if (W.get(t) === n) return;
180
+ W.set(t, n);
181
+ const a = Date.now();
182
+ I = [...I.slice(-29), { id: ee++, at: a, ...e, cause: ae(a, t) }], z.forEach((r) => r());
183
+ }
184
+ function re(t, e) {
185
+ t instanceof Element && (t.matches(L) && e.push(t), t.querySelectorAll(L).forEach((n) => e.push(n)));
186
+ }
187
+ function se() {
188
+ w || typeof MutationObserver > "u" || (w = new MutationObserver((t) => {
189
+ const e = [];
190
+ t.forEach((n) => {
191
+ if (n.type === "childList") {
192
+ n.addedNodes.forEach((r) => re(r, e));
193
+ return;
194
+ }
195
+ const a = n.target;
196
+ a.matches(L) ? e.push(a) : W.delete(a);
197
+ }), e.length && setTimeout(() => e.forEach(nt), 0);
198
+ }), w.observe(document.documentElement, { childList: !0, subtree: !0, attributes: !0, attributeFilter: ["data-error-code", "class"] }), document.querySelectorAll(L).forEach(nt));
199
+ }
200
+ function ie() {
201
+ w == null || w.disconnect(), w = null;
202
+ }
203
+ function K() {
204
+ return [...I].reverse();
205
+ }
206
+ function ht() {
207
+ I = [], z.forEach((t) => t());
208
+ }
209
+ function le(t) {
210
+ return z.add(t), () => {
211
+ z.delete(t);
212
+ };
213
+ }
214
+ const bt = 4e3, ce = /* @__PURE__ */ new Set(["GET", "HEAD"]);
215
+ function ue(t, e) {
216
+ let n;
217
+ try {
218
+ n = new URL(t, window.location.href).pathname;
219
+ } catch {
220
+ return null;
221
+ }
222
+ if (!e) return n;
223
+ const a = e.replace(/\/+$/, ""), r = n.indexOf(a);
224
+ if (r < 0) return null;
225
+ const o = n.slice(r + a.length);
226
+ return o.startsWith("/") || o === "" ? o || "/" : null;
227
+ }
228
+ function de(t, e) {
229
+ const n = (i) => i.split("/").filter(Boolean), a = n(t.trim()), r = n(e), o = (i, s) => i === a.length ? s === r.length : a[i] === "**" ? o(i + 1, s) || s < r.length && o(i, s + 1) : s === r.length ? !1 : (a[i] === "*" || a[i] === r[s]) && o(i + 1, s + 1);
230
+ return o(0, 0);
231
+ }
232
+ function fe(t, e) {
233
+ var a;
234
+ const n = (a = t.method) == null ? void 0 : a.trim().toUpperCase();
235
+ return !n || n === "*" ? !0 : n === "WRITE" ? !ce.has(e) : n === e;
236
+ }
237
+ function pe(t, e) {
238
+ return t.html ? {
239
+ kind: "response",
240
+ delay: e,
241
+ status: t.status,
242
+ contentType: "text/html",
243
+ body: `<html><body><h1>${t.status} ${t.message ?? "Bad Gateway"}</h1></body></html>`
244
+ } : {
245
+ kind: "response",
246
+ delay: e,
247
+ status: t.status,
248
+ contentType: "application/json",
249
+ body: JSON.stringify({ statusCode: t.status, message: t.message ?? `Сбой из dev-панели: ${t.status}` })
250
+ };
251
+ }
252
+ function he(t) {
253
+ const e = new Set(t.state.faults);
254
+ return [...(t.config.groups ?? []).flatMap((a) => a.items).filter((a) => e.has(a.id)).flatMap((a) => [].concat(a.request ?? [])), ...t.state.rules.filter((a) => a.enabled)];
255
+ }
256
+ function gt(t) {
257
+ for (const e of v()) {
258
+ const n = ue(t, e.config.apiBase);
259
+ if (n !== null) return { entry: e, path: n };
260
+ }
261
+ return null;
262
+ }
263
+ function vt({ entry: t, path: e }, n) {
264
+ const a = n.toUpperCase(), r = new Set(t.state.faults), o = r.has("slow") ? bt : 0;
265
+ if (r.has("offline") || r.has("network")) return { kind: "network", delay: o };
266
+ const i = he(t).find((s) => fe(s, a) && de(s.path, e));
267
+ return i ? pe(i, o) : o ? { kind: "pass", delay: o } : null;
268
+ }
269
+ const mt = (t, e) => zt(t.entry.config.service, e, t.path), J = (t) => t.reason ?? new DOMException("The operation was aborted.", "AbortError");
270
+ function be(t, e) {
271
+ return new Promise((n, a) => {
272
+ if (e != null && e.aborted) {
273
+ a(J(e));
274
+ return;
275
+ }
276
+ const r = setTimeout(n, t);
277
+ e == null || e.addEventListener("abort", () => {
278
+ clearTimeout(r), a(J(e));
279
+ }, { once: !0 });
280
+ });
281
+ }
282
+ const wt = /* @__PURE__ */ new Set([204, 205, 304]);
283
+ let at = !1;
284
+ function ge() {
285
+ at || typeof window > "u" || (at = !0, ve(), we());
286
+ }
287
+ function ve() {
288
+ var e;
289
+ const t = (e = window.fetch) == null ? void 0 : e.bind(window);
290
+ t && (window.fetch = async (n, a) => {
291
+ const r = typeof n == "object" && "url" in n ? n : null, o = gt(r ? r.url : String(n));
292
+ if (!o) return t(n, a);
293
+ const i = (a == null ? void 0 : a.method) ?? (r == null ? void 0 : r.method) ?? "GET", s = mt(o, i), l = vt(o, i), f = (a == null ? void 0 : a.signal) ?? (r == null ? void 0 : r.signal);
294
+ try {
295
+ if (l != null && l.delay && await be(l.delay, f), f != null && f.aborted) throw J(f);
296
+ if ((l == null ? void 0 : l.kind) === "network")
297
+ throw s("network", !0), new TypeError("Failed to fetch");
298
+ if ((l == null ? void 0 : l.kind) === "response")
299
+ return s(l.status, !0), new Response(wt.has(l.status) ? null : l.body, {
300
+ status: l.status,
301
+ headers: { "Content-Type": l.contentType }
302
+ });
303
+ const p = await t(n, a);
304
+ return s(p.status, !1), p;
305
+ } catch (p) {
306
+ throw s(f != null && f.aborted ? "abort" : "network", !1), p;
307
+ }
308
+ });
309
+ }
310
+ const ot = /* @__PURE__ */ new WeakMap(), rt = /* @__PURE__ */ new WeakMap(), q = /* @__PURE__ */ new WeakMap(), me = ["readyState", "responseURL", "status", "statusText", "responseText", "response", "getAllResponseHeaders", "getResponseHeader"];
311
+ function we() {
312
+ if (typeof XMLHttpRequest > "u") return;
313
+ const t = XMLHttpRequest.prototype, e = t.open, n = t.send, a = t.abort;
314
+ t.open = function(o, i, ...s) {
315
+ st(this), me.forEach((l) => {
316
+ Reflect.deleteProperty(this, l);
317
+ }), ot.set(this, { method: o, url: String(i) }), e.call(this, o, i, ...s);
318
+ }, t.send = function(o) {
319
+ const i = ot.get(this), s = i ? gt(i.url) : null;
320
+ if (!i || !s) {
321
+ n.call(this, o);
322
+ return;
323
+ }
324
+ const l = mt(s, i.method);
325
+ rt.set(this, l);
326
+ const f = vt(s, i.method), p = () => {
327
+ this.addEventListener("abort", () => l("abort", !1), { once: !0 }), this.addEventListener("loadend", () => l(this.status || "network", !1), { once: !0 }), n.call(this, o);
328
+ };
329
+ if (!f) {
330
+ p();
331
+ return;
332
+ }
333
+ q.set(this, setTimeout(() => {
334
+ if (q.delete(this), f.kind === "pass") {
335
+ p();
336
+ return;
337
+ }
338
+ l(f.kind === "network" ? "network" : f.status, !0), xe(this, f, i.url);
339
+ }, f.delay));
340
+ }, t.abort = function() {
341
+ var i;
342
+ if (!st(this)) {
343
+ a.call(this);
344
+ return;
345
+ }
346
+ (i = rt.get(this)) == null || i("abort", !1);
347
+ const o = xt(this);
348
+ o("readyState", 4), o("status", 0), Z(this, ["readystatechange", "abort", "loadend"]), o("readyState", 0);
349
+ };
350
+ }
351
+ function st(t) {
352
+ const e = q.get(t);
353
+ return e === void 0 ? !1 : (clearTimeout(e), q.delete(t), !0);
354
+ }
355
+ const xt = (t) => (e, n) => {
356
+ Object.defineProperty(t, e, { configurable: !0, get: () => n });
357
+ }, Z = (t, e) => {
358
+ e.forEach((n) => t.dispatchEvent(new ProgressEvent(n)));
359
+ };
360
+ function xe(t, e, n) {
361
+ const a = xt(t);
362
+ if (a("readyState", 4), a("responseURL", n), e.kind === "network") {
363
+ a("status", 0), a("statusText", ""), Z(t, ["readystatechange", "error", "loadend"]);
364
+ return;
365
+ }
366
+ const r = wt.has(e.status) ? "" : e.body;
367
+ let o = r;
368
+ if (t.responseType === "json")
369
+ try {
370
+ o = e.contentType === "application/json" && r ? JSON.parse(r) : null;
371
+ } catch {
372
+ o = null;
373
+ }
374
+ a("status", e.status), a("statusText", String(e.status)), a("responseText", r), a("response", o);
375
+ const i = `content-type: ${e.contentType}\r
376
+ `;
377
+ Object.defineProperty(t, "getAllResponseHeaders", { configurable: !0, value: () => i }), Object.defineProperty(t, "getResponseHeader", {
378
+ configurable: !0,
379
+ value: (s) => s.toLowerCase() === "content-type" ? e.contentType : null
380
+ }), Z(t, ["readystatechange", "load", "loadend"]);
381
+ }
382
+ function Q(t) {
383
+ try {
384
+ t ? Reflect.deleteProperty(navigator, "onLine") : Object.defineProperty(navigator, "onLine", { configurable: !0, get: () => !1 }), window.dispatchEvent(new Event(t ? "online" : "offline"));
385
+ } catch {
386
+ }
387
+ }
388
+ function yt() {
389
+ const t = v().some((e) => e.state.faults.includes("offline"));
390
+ Yt(), ct(), ht(), t && Q(!0);
391
+ }
392
+ const ye = {
393
+ title: "Сеть",
394
+ items: [
395
+ { id: "offline", label: "Офлайн браузера", hint: "Полоса «Нет связи», запросы к API падают" },
396
+ { id: "network", label: "Обрыв соединения", hint: "Сеть есть, а сервер не отвечает" },
397
+ { id: "slow", label: "Медленные ответы", hint: `Задержка ${bt / 1e3} с на запросы к API` }
398
+ ]
399
+ }, $e = {
400
+ authFail: { label: "Сбой входа", hint: "После перезагрузки сервис рисует заглушку входа" },
401
+ crashApp: { label: "Падение приложения", hint: "Ошибка рендера над каркасом сервиса" },
402
+ crashPage: { label: "Падение страницы", hint: "Каждая открытая страница падает, пока флаг включён" }
403
+ }, X = [["", "Любой"], ["GET", "GET"], ["write", "Запись"], ["POST", "POST"], ["PUT", "PUT"], ["PATCH", "PATCH"], ["DELETE", "DELETE"]], ke = [400, 401, 403, 404, 409, 422, 429, 500, 502, 503, 504], d = (t) => String(t ?? "").replace(/[&<>"']/g, (e) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[e]), Se = '<svg viewBox="0 0 36 36" fill="none" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M28 0L20 16H36L28 0ZM28 5.11101L23.6984 13.7143H32.3016L28 5.11101Z" fill="#3BA68C"/><path fill-rule="evenodd" clip-rule="evenodd" d="M9 33.7143C12.1559 33.7143 14.7143 31.1559 14.7143 28C14.7143 24.8441 12.1559 22.2857 9 22.2857C5.84409 22.2857 3.28571 24.8441 3.28571 28C3.28571 31.1559 5.84409 33.7143 9 33.7143ZM9 36C13.4183 36 17 32.4183 17 28C17 23.5817 13.4183 20 9 20C4.58172 20 1 23.5817 1 28C1 32.4183 4.58172 36 9 36Z" fill="#E54B6A"/><path fill-rule="evenodd" clip-rule="evenodd" d="M33.7143 22.2857H22.2857V33.7143H33.7143V22.2857ZM20 20V36H36V20H20Z" fill="#1E4391"/><path fill-rule="evenodd" clip-rule="evenodd" d="M12.0593 4.9091L9 0L5.94073 4.9091L0 6.11146L4.05 10.3478L3.43769 16L9 13.7091L14.5623 16L13.95 10.3478L18 6.11146L12.0593 4.9091ZM14.0262 7.31822L10.7085 6.64674L9 3.90515L7.29149 6.64674L3.97378 7.31822L6.23558 9.68408L5.89362 12.8407L9 11.5613L12.1064 12.8407L11.7644 9.68408L14.0262 7.31822Z" fill="#E98446"/></svg>', Ee = `
404
+ :host { all: initial; }
405
+ * { box-sizing: border-box; }
406
+ .root { --p: #1e4391; --p-soft: #e8eef9; --fg: #222; --muted: #6b7280; --line: #d9dee8; --bg: #fff; --soft: #f5f7fb;
407
+ --danger: #d6342c; --danger-soft: #fdeceb;
408
+ /* Отступ кнопки снизу: StickyActionBar кита, пока стоит у нижнего края, задаёт на <html>
409
+ --u-dev-launcher-bottom (его высота + 12px) — кнопка и панель поднимаются над ним. */
410
+ --launcher-bottom: var(--u-dev-launcher-bottom, calc(12px + env(safe-area-inset-bottom, 0px)));
411
+ font-family: Montserrat, "Segoe UI", Arial, sans-serif; font-size: 13px; line-height: 1.4; color: var(--fg); }
412
+ button, input, select { font: inherit; color: inherit; }
413
+ /* Кнопка панели — в цветах кита: токены --u-color-* с :root сервиса проходят в shadow DOM
414
+ (all: initial их не сбрасывает), запасные значения — как в ките. В покое — круг с логотипом,
415
+ чтобы меньше закрывать нижние липкие панели сервиса; при наведении и фокусе раскрывается
416
+ в «логотип + Dev»; при включённых сбоях раскрыта всегда, цвет ошибки и число сбоев. */
417
+ .pill { --kit-p: var(--u-color-primary, #1e4391); --kit-error: var(--u-color-error, #ef302b);
418
+ --kit-surface: var(--u-color-surface, #fff); --kit-line: var(--u-color-border, #748ab9);
419
+ position: fixed; left: 12px; bottom: var(--launcher-bottom); z-index: 2147483000;
420
+ display: inline-flex; align-items: center; height: 36px; padding: 0; border: 1px solid var(--kit-line); border-radius: 18px;
421
+ background: var(--kit-surface); color: var(--kit-p); font-size: 13px; font-weight: 500; white-space: nowrap; cursor: pointer;
422
+ box-shadow: 0 2px 8px rgba(0,0,0,.15); }
423
+ .pill .logo { flex: none; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; background: var(--kit-surface); }
424
+ .pill .logo svg { display: block; width: 20px; height: 20px; }
425
+ .pill .label { max-width: 0; overflow: hidden; opacity: 0; padding: 0;
426
+ transition: max-width .2s ease, opacity .2s ease, padding .2s ease; }
427
+ .pill:hover .label, .pill:focus-visible .label, .pill.on .label { max-width: 260px; opacity: 1; padding: 0 14px 0 2px; }
428
+ .pill.on { background: var(--kit-error); border-color: var(--kit-error); color: #fff; }
429
+ .pill.on .logo { width: 30px; height: 30px; margin: 0 1px 0 2px; }
430
+ .pill:focus-visible { outline: 2px solid var(--kit-p); outline-offset: 2px; }
431
+ .panel { position: fixed; left: 12px; bottom: calc(var(--launcher-bottom) + 44px); z-index: 2147483001;
432
+ width: 360px; max-width: calc(100vw - 24px); max-height: min(70vh, 640px); display: flex; flex-direction: column;
433
+ background: var(--bg); border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 12px 32px rgba(16,24,40,.25); }
434
+ .panel.alone { bottom: var(--launcher-bottom); }
435
+ .hint { position: fixed; left: 12px; bottom: var(--launcher-bottom); z-index: 2147483000;
436
+ max-width: calc(100vw - 24px); padding: 8px 12px; border-radius: 10px; background: #222; color: #fff; font-size: 12px;
437
+ box-shadow: 0 4px 14px rgba(0,0,0,.2); }
438
+ .note { margin: 0 12px 8px; padding: 6px 10px; border-radius: 8px; background: var(--p-soft); color: var(--fg); font-size: 12px; overflow-wrap: anywhere; }
439
+ .pill ~ .hint { bottom: calc(var(--launcher-bottom) + 44px); }
440
+ .head { display: flex; align-items: center; gap: 8px; padding: 10px 12px 8px; }
441
+ .title { flex: 1; min-width: 0; font-weight: 700; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
442
+ .title select { font-weight: 700; border: 1px solid var(--line); border-radius: 6px; padding: 2px 4px; background: var(--bg); max-width: 100%; }
443
+ .reset { border: 0; border-radius: 6px; padding: 5px 10px; background: var(--danger-soft); color: var(--danger); font-weight: 600; font-size: 12px; cursor: pointer; }
444
+ .close { width: 26px; height: 26px; border: 0; border-radius: 6px; background: none; color: var(--muted); font-size: 18px; line-height: 1; cursor: pointer; }
445
+ .escape { padding: 0 12px 6px; color: var(--muted); font-size: 11px; }
446
+ .tabs { display: flex; gap: 4px; padding: 0 12px; border-bottom: 1px solid var(--line); }
447
+ .tab { border: 0; background: none; padding: 6px 8px; font-weight: 600; font-size: 12px; color: var(--muted); border-bottom: 2px solid transparent; cursor: pointer; }
448
+ .tab[aria-selected="true"] { color: var(--p); border-color: var(--p); }
449
+ .body { overflow: auto; padding: 8px 12px 10px; display: flex; flex-direction: column; gap: 10px; }
450
+ .search { width: 100%; padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--soft); }
451
+ .group-title { margin: 2px 0 2px; font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
452
+ .row { display: flex; align-items: center; gap: 10px; padding: 4px 0; cursor: pointer; }
453
+ .row .text { flex: 1; min-width: 0; }
454
+ .row small { display: block; color: var(--muted); font-size: 11px; }
455
+ .switch { appearance: none; flex: none; width: 30px; height: 18px; border-radius: 9px; background: var(--line); position: relative; margin: 0; cursor: pointer; }
456
+ .switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.3); transition: left .12s; }
457
+ .switch:checked { background: var(--danger); }
458
+ .switch:checked::after { left: 14px; }
459
+ .switch:focus-visible, button:focus-visible, select:focus-visible, input:focus-visible { outline: 2px solid var(--p); outline-offset: 2px; }
460
+ .rule { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 8px; background: var(--soft); font-family: Consolas, monospace; font-size: 12px; }
461
+ .rule .text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
462
+ .remove { border: 0; background: none; color: var(--muted); font-size: 16px; line-height: 1; cursor: pointer; padding: 0 2px; }
463
+ .add { display: grid; grid-template-columns: auto 1fr auto auto; gap: 6px; }
464
+ .add select, .add input { min-width: 0; padding: 5px 6px; border: 1px solid var(--line); border-radius: 6px; background: var(--bg); font-size: 12px; }
465
+ .btn { border: 1px solid var(--line); border-radius: 6px; background: var(--bg); padding: 5px 10px; font-size: 12px; font-weight: 600; cursor: pointer; }
466
+ .btn.primary { background: var(--p); border-color: var(--p); color: #fff; }
467
+ .foot { display: flex; gap: 6px; flex-wrap: wrap; padding: 8px 12px; border-top: 1px solid var(--line); }
468
+ .empty { color: var(--muted); font-size: 12px; }
469
+ .requests { display: flex; flex-direction: column; gap: 2px; }
470
+ .req { display: grid; grid-template-columns: 52px 1fr auto auto; gap: 8px; align-items: center; padding: 4px 0;
471
+ border-bottom: 1px solid var(--soft); font-family: Consolas, monospace; font-size: 12px; }
472
+ .req .path { min-width: 0; overflow-wrap: anywhere; }
473
+ .req .status { font-weight: 700; }
474
+ .req .status.bad { color: var(--danger); }
475
+ .req small { display: block; color: var(--muted); font-family: Montserrat, "Segoe UI", Arial, sans-serif; font-size: 11px; }
476
+ .req .btn { padding: 3px 8px; font-family: Montserrat, "Segoe UI", Arial, sans-serif; }
477
+ .shown { padding: 6px 0; border-bottom: 1px solid var(--soft); }
478
+ .shown-head { display: flex; justify-content: space-between; gap: 8px; color: var(--muted); font-size: 11px; }
479
+ .shown-head .kind { font-weight: 600; color: var(--danger); }
480
+ .shown-head .kind.warning { color: #b45309; }
481
+ .shown-title { font-weight: 600; }
482
+ .shown small { display: block; color: var(--muted); font-size: 11px; }
483
+ .shown .cause { margin-top: 2px; font-family: Consolas, monospace; font-size: 12px; }
484
+ .requests-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; color: var(--muted); font-size: 11px; }
485
+ dl { display: grid; grid-template-columns: auto 1fr; gap: 6px 12px; margin: 0; }
486
+ dt { color: var(--muted); }
487
+ dd { margin: 0; font-family: Consolas, monospace; font-size: 12px; overflow-wrap: anywhere; }
488
+ @media (max-width: 576px) {
489
+ .panel { left: 0; right: 0; bottom: 0; width: auto; max-width: none; max-height: 70vh; border-radius: 14px 14px 0 0;
490
+ padding-bottom: env(safe-area-inset-bottom, 0px); }
491
+ .panel ~ .pill { display: none; }
492
+ }
493
+ @media (prefers-reduced-motion: reduce) { .switch::after, .pill .label { transition: none; } }
494
+ `, Le = 6e3;
495
+ let V, h = null, u = null, k = null, y = null, T = !1, S = !1;
496
+ const $t = { open: !1, tab: "faults", search: "", service: void 0, hint: "" }, c = { ...$t };
497
+ function D() {
498
+ const t = v();
499
+ return t.find((e) => e.config.service === c.service) ?? t[0];
500
+ }
501
+ function kt(t) {
502
+ const e = (t.config.builtins ?? []).map((n) => ({ id: n, ...$e[n] }));
503
+ return [
504
+ ...e.length ? [{ title: "Весь сервис", items: e }] : [],
505
+ ye,
506
+ ...t.config.groups ?? []
507
+ ];
508
+ }
509
+ function Te(t, e) {
510
+ var n;
511
+ return ((n = kt(t).flatMap((a) => a.items).find((a) => a.id === e)) == null ? void 0 : n.label) ?? e;
512
+ }
513
+ function St(t) {
514
+ return [
515
+ ...t.state.faults.map((e) => Te(t, e)),
516
+ ...t.state.rules.filter((e) => e.enabled).map((e) => `${e.path} → ${e.status}`)
517
+ ];
518
+ }
519
+ function Ae(t, e, n, a) {
520
+ const r = t % 100, o = t % 10;
521
+ return r >= 11 && r <= 14 ? a : o === 1 ? e : o >= 2 && o <= 4 ? n : a;
522
+ }
523
+ const it = (t) => !c.search || t.toLowerCase().includes(c.search.toLowerCase());
524
+ function Ce(t) {
525
+ const e = new Set(t.state.faults), n = kt(t).map((o) => {
526
+ const i = o.items.filter((s) => it(`${s.label} ${s.hint ?? ""} ${s.id}`));
527
+ return i.length ? `<div><div class="group-title">${d(o.title)}</div>${i.map((s) => `
528
+ <label class="row"><span class="text">${d(s.label)}${s.hint ? `<small>${d(s.hint)}</small>` : ""}</span>
529
+ <input class="switch" type="checkbox" role="switch" data-fault="${d(s.id)}" ${e.has(s.id) ? "checked" : ""}
530
+ aria-label="${d(s.label)}"></label>`).join("")}</div>` : "";
531
+ }).join(""), a = t.state.rules.filter((o) => it(`${o.method ?? ""} ${o.path} ${o.status}`)), r = (o) => {
532
+ var i;
533
+ return ((i = X.find(([s]) => s === (o ?? ""))) == null ? void 0 : i[1]) ?? o;
534
+ };
535
+ return `
536
+ <input class="search" type="search" data-search placeholder="Поиск: 503, офлайн, роли…" aria-label="Поиск по сценариям" value="${d(c.search)}">
537
+ ${n || (a.length ? "" : '<div class="empty">Ничего не найдено.</div>')}
538
+ <div><div class="group-title">Ответы сервера</div>
539
+ ${a.map((o) => `<div class="rule"><span class="text">${d(r(o.method))} ${d(o.path)} → ${o.status}</span>
540
+ <input class="switch" type="checkbox" role="switch" data-rule="${d(o.id)}" ${o.enabled ? "checked" : ""}
541
+ aria-label="${d(`${o.path} → ${o.status}`)}">
542
+ <button class="remove" type="button" data-remove="${d(o.id)}" aria-label="Удалить правило">×</button></div>`).join("")}
543
+ <form class="add" data-add>
544
+ <select name="method" aria-label="Метод">${X.map(([o, i]) => `<option value="${o}">${i}</option>`).join("")}</select>
545
+ <input name="path" required placeholder="/assets/*" aria-label="Путь после ${d(t.config.apiBase ?? "адреса сайта")}">
546
+ <select name="status" aria-label="Код ответа">${ke.map((o) => `<option${o === 503 ? " selected" : ""}>${o}</option>`).join("")}</select>
547
+ <button class="btn primary" type="submit">Добавить</button>
548
+ </form>
549
+ </div>`;
550
+ }
551
+ function De() {
552
+ const t = document.documentElement.getAttribute("data-u-viewport");
553
+ return t || (window.matchMedia("(max-width: 576px)").matches ? "mobile" : window.matchMedia("(max-width: 900px)").matches ? "tablet" : "desktop");
554
+ }
555
+ function Pe(t) {
556
+ var s, l, f;
557
+ const e = document.documentElement, n = getComputedStyle(e).getPropertyValue("--u-unit").trim(), a = Bt();
558
+ let r = "—";
559
+ try {
560
+ const p = (l = (s = t.config).user) == null ? void 0 : l.call(s);
561
+ p && (r = [p.name, (f = p.roles) != null && f.length ? p.roles.join(", ") : "без ролей"].filter(Boolean).join(" · "));
562
+ } catch {
563
+ r = "не удалось прочитать";
564
+ }
565
+ const o = St(t);
566
+ return `<dl>${[
567
+ ["Ширина", `${window.innerWidth} px · ${De()}`],
568
+ ["Шкала", `${e.getAttribute("data-u-responsive") ?? "legacy"}${n ? ` · --u-unit ${n}` : ""}`],
569
+ ["Кит", a ? `${a.name} ${a.version}` : "—"],
570
+ ["Сервис", [t.config.service, t.config.version].filter(Boolean).join(" ")],
571
+ ["API", t.config.apiBase ?? "все запросы"],
572
+ ["Оболочка ЛК", window.__POWERED_BY_QIANKUN__ ? "да (Qiankun)" : "нет"],
573
+ ["Ввод", e.getAttribute("data-input-mode") ?? "—"],
574
+ ["Сеть", navigator.onLine ? "онлайн" : "офлайн"],
575
+ ["Пользователь", r],
576
+ ["Включено", o.length ? o.join("; ") : "ничего"]
577
+ ].map(([p, $]) => `<dt>${d(p)}</dt><dd>${d($)}</dd>`).join("")}</dl>`;
578
+ }
579
+ function g() {
580
+ if (!u) return;
581
+ const t = D();
582
+ if (!t) {
583
+ u.innerHTML = "";
584
+ return;
585
+ }
586
+ const e = v().flatMap(St), n = e.length, a = n ? `Dev · ${n === 1 ? e[0] : `${n} ${Ae(n, "сбой", "сбоя", "сбоев")}`}` : "Dev", r = v(), o = r.every((b) => Qt(b) === "hidden"), i = !o || n > 0, s = r.length > 1 ? `<select data-service aria-label="Сервис">${r.map((b) => `<option value="${d(b.config.service)}"${b === t ? " selected" : ""}>Dev · ${d(b.config.service)}</option>`).join("")}</select>` : `Dev · ${d(t.config.service)}`, l = c.open ? `
587
+ <section class="panel${i ? "" : " alone"}" role="region" aria-label="Панель разработки">
588
+ <div class="head"><span class="title">${s}</span>
589
+ <button class="reset" type="button" data-reset>Сбросить всё</button>
590
+ <button class="close" type="button" data-close aria-label="Свернуть панель">×</button></div>
591
+ <div class="escape">Без панели: адрес с ?dev=off · открыть и закрыть: Ctrl+Alt+D</div>
592
+ <div class="tabs" role="tablist">
593
+ <button class="tab" type="button" role="tab" data-tab="faults" aria-selected="${c.tab === "faults"}">Сбои${R(t) ? ` · ${R(t)}` : ""}</button>
594
+ <button class="tab" type="button" role="tab" data-tab="requests" aria-selected="${c.tab === "requests"}">Запросы</button>
595
+ <button class="tab" type="button" role="tab" data-tab="errors" aria-selected="${c.tab === "errors"}">Ошибки${K().length ? ` · ${K().length}` : ""}</button>
596
+ <button class="tab" type="button" role="tab" data-tab="view" aria-selected="${c.tab === "view"}">Смотреть</button>
597
+ </div>
598
+ <div class="body">${c.tab === "faults" ? Ce(t) : c.tab === "requests" ? Tt(t) : c.tab === "errors" ? ze() : Pe(t)}</div>
599
+ ${c.hint ? `<div class="note" role="status">${d(c.hint)}</div>` : ""}
600
+ <div class="foot">
601
+ ${t.config.onRefetch ? '<button class="btn" type="button" data-refetch>Перезапросить данные</button>' : ""}
602
+ <button class="btn" type="button" data-reload>Перезагрузить</button>
603
+ ${r.some((b) => b.state.faults.length) ? '<button class="btn" type="button" data-share>Ссылка на сбои</button>' : ""}
604
+ <button class="btn" type="button" data-launcher="${o ? "visible" : "hidden"}">${o ? "Показывать кнопку" : "Скрыть кнопку"}</button>
605
+ </div>
606
+ </section>` : "", f = u.activeElement, p = Et(f), $ = (f == null ? void 0 : f.dataset.search) !== void 0 ? f.selectionStart : null, Dt = G ?? Ue();
607
+ G = null;
608
+ const Pt = [
609
+ e.length ? `Включено: ${e.join(", ")}` : "Панель разработки (Ctrl+Alt+D)",
610
+ o ? "Кнопка скрыта и видна, пока включены сбои" : ""
611
+ ].filter(Boolean).join(". "), Mt = i ? `
612
+ <button class="pill${n ? " on" : ""}" type="button" data-toggle aria-expanded="${c.open}"
613
+ title="${d(Pt)}"><span class="logo">${Se}</span><span class="label">${d(a)}</span></button>` : "", Ot = c.hint && !c.open ? `<div class="hint" role="status">${d(c.hint)}</div>` : "";
614
+ if (u.innerHTML = `<style>${Ee}</style><div class="root">${l}${Mt}${Ot}</div>`, Fe(Dt), p) {
615
+ const b = u.querySelector(p);
616
+ b == null || b.focus(), b instanceof HTMLInputElement && $ !== null && b.setSelectionRange($, $);
617
+ }
618
+ }
619
+ const Me = ["search", "fault", "rule", "tab", "service", "reset", "close", "toggle", "ruleFrom", "clearJournal"];
620
+ function Et(t) {
621
+ if (!t) return null;
622
+ const e = t.getAttribute("name");
623
+ if (e && t.closest("[data-add]")) return `[data-add] [name="${e}"]`;
624
+ const n = Me.find((o) => t.dataset[o] !== void 0);
625
+ if (!n) return null;
626
+ const a = t.dataset[n], r = `data-${n.replace(/[A-Z]/g, (o) => `-${o.toLowerCase()}`)}`;
627
+ return a ? `[${r}="${a.replace(/["\\]/g, "\\$&")}"]` : `[${r}]`;
628
+ }
629
+ const Lt = ["method", "path", "status"];
630
+ let G = null;
631
+ const Oe = { network: "сеть", abort: "отмена", pending: "…" };
632
+ function Tt(t) {
633
+ const e = Y().filter((n) => n.service === t.config.service);
634
+ return e.length ? `<div class="requests-head"><span>Последние ${e.length}, новые сверху</span>
635
+ <button class="btn" type="button" data-clear-journal>Очистить</button></div>
636
+ <div class="requests">${e.map((n) => {
637
+ const a = typeof n.status == "number" ? String(n.status) : Oe[n.status], r = n.status === "network" || typeof n.status == "number" && n.status >= 400, o = [n.duration === null ? "" : `${n.duration} мс`, n.faked ? "подменён панелью" : ""].filter(Boolean).join(" · ");
638
+ return `<div class="req"><span>${d(n.method)}</span>
639
+ <span class="path">${d(n.path)}${o ? `<small>${d(o)}</small>` : ""}</span>
640
+ <span class="status${r ? " bad" : ""}">${d(a)}</span>
641
+ <button class="btn" type="button" data-rule-from="${n.id}" title="Ответ на этот адрес — в «Ответах сервера»">Правило</button></div>`;
642
+ }).join("")}</div>` : '<div class="empty">Запросов к API пока не было. Журнал помнит последние 50 и очищается при перезагрузке.</div>';
643
+ }
644
+ const Re = {
645
+ screen: "Заглушка",
646
+ fail: "Уведомление об ошибке",
647
+ warning: "Предупреждение",
648
+ offline: "Нет связи"
649
+ }, Ie = (t) => Re[t.kind === "notification" ? t.variant ?? "fail" : t.kind];
650
+ function ze() {
651
+ const t = K();
652
+ return t.length ? `<div class="requests-head"><span>Последние ${t.length}, новые сверху</span>
653
+ <button class="btn" type="button" data-clear-shown>Очистить</button></div>
654
+ <div>${t.map((e) => `<div class="shown">
655
+ <div class="shown-head"><span class="kind${e.variant === "warning" ? " warning" : ""}">${d(Ie(e))}${e.code ? ` · ${d(e.code)}` : ""}</span>
656
+ <time>${d(new Date(e.at).toLocaleTimeString("ru-RU"))}</time></div>
657
+ <div class="shown-title">${d(e.title)}</div>
658
+ ${e.text ? `<small>${d(e.text)}</small>` : ""}
659
+ <div class="cause">${e.cause ? `← ${d(e.cause)}` : "<small>Неудачных запросов к API перед показом не было</small>"}</div>
660
+ </div>`).join("")}</div>` : '<div class="empty">Ошибок пользователю пока не показывали. Здесь появятся заглушки, уведомления об ошибке и полоса «Нет связи» — с причиной из запросов к API.</div>';
661
+ }
662
+ function qe(t) {
663
+ var a;
664
+ const e = Y().find((r) => String(r.id) === String(t));
665
+ if (!e) return;
666
+ G = { method: X.some(([r]) => r === e.method) ? e.method : "", path: e.path, status: "503" }, c.tab = "faults", c.search = "", g(), (a = u == null ? void 0 : u.querySelector('[data-add] [name="status"]')) == null || a.focus();
667
+ }
668
+ function je() {
669
+ const t = [...new Set(v().flatMap((s) => s.state.faults))], e = new URL(window.location.href);
670
+ e.searchParams.set("dev", t.join(","));
671
+ const n = e.href.replace(/%2C/gi, ","), r = v().some((s) => s.state.rules.some((l) => l.enabled)) ? " Свои правила «адрес → код» в неё не входят." : "", o = () => {
672
+ A(`Ссылка скопирована.${r}`), g();
673
+ }, i = () => {
674
+ A(`Ссылка: ${n}${r}`), g();
675
+ };
676
+ try {
677
+ navigator.clipboard.writeText(n).then(o, i);
678
+ } catch {
679
+ i();
680
+ }
681
+ }
682
+ function Ue() {
683
+ const t = u == null ? void 0 : u.querySelector("[data-add]");
684
+ return t ? Object.fromEntries(Lt.map((e) => {
685
+ var n;
686
+ return [e, ((n = t.elements.namedItem(e)) == null ? void 0 : n.value) ?? ""];
687
+ })) : null;
688
+ }
689
+ function Fe(t) {
690
+ const e = u == null ? void 0 : u.querySelector("[data-add]");
691
+ !e || !t || Lt.forEach((n) => {
692
+ const a = e.elements.namedItem(n);
693
+ a && (a.value = t[n]);
694
+ });
695
+ }
696
+ function He(t) {
697
+ if (!t) {
698
+ A(""), tt("visible");
699
+ return;
700
+ }
701
+ c.open = !1;
702
+ const e = v().some((n) => R(n) > 0);
703
+ A(`Кнопка Dev скрыта${e ? " и видна, пока включены сбои" : ""}. Панель: Ctrl+Alt+D`), tt("hidden");
704
+ }
705
+ function A(t) {
706
+ clearTimeout(V), c.hint = t, t && (V = setTimeout(() => {
707
+ c.hint = "", g();
708
+ }, Le));
709
+ }
710
+ function j(t = !c.open) {
711
+ var e, n;
712
+ t && A(""), c.open = t, g(), t ? (e = u == null ? void 0 : u.querySelector("[data-search], [data-tab]")) == null || e.focus() : (n = u == null ? void 0 : u.querySelector("[data-toggle]")) == null || n.focus();
713
+ }
714
+ function Ne(t) {
715
+ var a, r, o, i;
716
+ const e = t.target, n = D();
717
+ if (n)
718
+ if (e.closest("[data-toggle]")) j();
719
+ else if (e.closest("[data-close]")) j(!1);
720
+ else if (e.closest("[data-reset]"))
721
+ yt(), (r = (a = n.config).onRefetch) == null || r.call(a);
722
+ else if (e.closest("[data-reload]")) window.location.reload();
723
+ else if (e.closest("[data-rule-from]")) qe(Number(e.closest("[data-rule-from]").dataset.ruleFrom));
724
+ else if (e.closest("[data-clear-journal]"))
725
+ ct(), g();
726
+ else if (e.closest("[data-clear-shown]")) ht();
727
+ else if (e.closest("[data-share]")) je();
728
+ else if (e.closest("[data-launcher]")) He(e.closest("[data-launcher]").dataset.launcher === "hidden");
729
+ else if (e.closest("[data-refetch]")) (i = (o = n.config).onRefetch) == null || i.call(o);
730
+ else if (e.closest("[data-tab]")) {
731
+ const s = e.closest("[data-tab]").dataset.tab;
732
+ c.tab = s === "view" || s === "requests" || s === "errors" ? s : "faults", g();
733
+ } else e.closest("[data-remove]") && Gt(n, e.closest("[data-remove]").dataset.remove);
734
+ }
735
+ function _e(t) {
736
+ const e = t.target, n = D();
737
+ if (n)
738
+ if (e.dataset.fault) {
739
+ const a = e.checked;
740
+ Zt(n, e.dataset.fault, a), e.dataset.fault === "offline" && Q(!a);
741
+ } else e.dataset.rule ? Vt(n, e.dataset.rule, e.checked) : e.dataset.service !== void 0 && (c.service = e.value, g());
742
+ }
743
+ function Be(t) {
744
+ const e = t.target;
745
+ e.dataset.search !== void 0 && (c.search = e.value, g());
746
+ }
747
+ function We(t) {
748
+ const e = t.target;
749
+ if (e.dataset.add === void 0) return;
750
+ t.preventDefault();
751
+ const n = D(), a = new FormData(e), r = String(a.get("path") ?? "").trim();
752
+ !n || !r || (e.reset(), Xt(n, {
753
+ method: String(a.get("method") ?? "") || void 0,
754
+ path: r.startsWith("/") ? r : `/${r}`,
755
+ status: Number(a.get("status")) || 500,
756
+ html: Number(a.get("status")) === 502 || void 0
757
+ }));
758
+ }
759
+ function At(t) {
760
+ t.ctrlKey && t.altKey && t.code === "KeyD" ? (t.preventDefault(), j()) : t.key === "Escape" && c.open && h && t.composedPath().includes(h) && (t.preventDefault(), t.stopPropagation(), j(!1));
761
+ }
762
+ function Ke() {
763
+ if (h || typeof document > "u") return;
764
+ h = document.createElement("div"), h.id = "urfu-ui-kit-dev", h.setAttribute("data-urfu-ui-kit-dev", ""), u = h.attachShadow({ mode: "open" }), u.addEventListener("click", Ne), u.addEventListener("change", _e), u.addEventListener("input", Be), u.addEventListener("submit", We), window.addEventListener("keydown", At, !0), lt(), y = new MutationObserver((a) => {
765
+ (!(h != null && h.isConnected) || a.some((r) => r.type === "attributes")) && lt();
766
+ }), y.observe(document.documentElement, { childList: !0, subtree: !0, attributes: !0, attributeFilter: ["open"] }), c.open = v().some((a) => R(a) > 0);
767
+ const t = pt(g), e = qt(Ct);
768
+ u.addEventListener("pointerdown", Ze), window.addEventListener("pointerup", U, !0), window.addEventListener("pointercancel", U, !0);
769
+ const n = le(() => {
770
+ c.open && g();
771
+ });
772
+ se(), k = () => {
773
+ t(), e(), n(), ie();
774
+ }, g();
775
+ }
776
+ function Je() {
777
+ try {
778
+ const t = document.querySelectorAll("dialog:modal");
779
+ return t[t.length - 1] ?? null;
780
+ } catch {
781
+ return null;
782
+ }
783
+ }
784
+ function lt() {
785
+ if (!h) return;
786
+ const t = Je() ?? document.documentElement;
787
+ h.parentNode !== t && t.appendChild(h);
788
+ }
789
+ function Ct() {
790
+ var r;
791
+ if (!c.open || c.tab !== "requests") {
792
+ S = !1;
793
+ return;
794
+ }
795
+ if (T) {
796
+ S = !0;
797
+ return;
798
+ }
799
+ S = !1;
800
+ const t = u == null ? void 0 : u.querySelector(".body"), e = D();
801
+ if (!u || !t || !e) {
802
+ g();
803
+ return;
804
+ }
805
+ const n = u.activeElement, a = n && t.contains(n) ? Et(n) : null;
806
+ t.innerHTML = Tt(e), a && ((r = t.querySelector(a)) == null || r.focus());
807
+ }
808
+ function Ze() {
809
+ T = !0;
810
+ }
811
+ function U() {
812
+ T && (T = !1, S && setTimeout(Ct, 0));
813
+ }
814
+ function Xe() {
815
+ k == null || k(), k = null, y == null || y.disconnect(), y = null, window.removeEventListener("keydown", At, !0), window.removeEventListener("pointerup", U, !0), window.removeEventListener("pointercancel", U, !0), T = !1, S = !1, clearTimeout(V), h == null || h.remove(), h = null, u = null, Object.assign(c, $t);
816
+ }
817
+ function Ve(t, e) {
818
+ return typeof window > "u" ? () => {
819
+ } : (Ut(), _t(e), Wt(t).state.faults.includes("offline") && Q(!1), ge(), Ke(), () => {
820
+ Kt(t.service), v().length || Xe();
821
+ });
822
+ }
823
+ function Ge(t, e) {
824
+ var n;
825
+ return ((n = Jt(e)) == null ? void 0 : n.state.faults.includes(t)) ?? !1;
826
+ }
827
+ function Ye(t) {
828
+ return pt(t);
829
+ }
830
+ function nn() {
831
+ yt();
832
+ }
833
+ const Qe = () => "2.1.1";
834
+ function an(t) {
835
+ return Ve(t, { name: "urfu-ui-kit-react", version: Qe() });
836
+ }
837
+ function tn(t, e) {
838
+ return Rt(Ye, () => Ge(t, e), () => !1);
839
+ }
840
+ function on({ scope: t, service: e }) {
841
+ if (tn(t === "app" ? "crashApp" : "crashPage", e)) throw new Error(`Сбой из dev-панели: падение ${t === "app" ? "приложения" : "страницы"}`);
842
+ return null;
843
+ }
844
+ export {
845
+ on as DevCrashProbe,
846
+ Ge as isDevFault,
847
+ de as matchPath,
848
+ an as mountDevPanel,
849
+ nn as resetDevFaults,
850
+ Ye as subscribeDevFaults,
851
+ tn as useDevFault
852
+ };