PageSourceSearch

https://kolect.info/build/js/pages/DocumentsPage.js

js kolect.info collected 2026-10-01 15:49:44 UTC 89,128 bytes, 1,184 lines download raw bytes

1"use strict";
2
3function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
5function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
6function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
7function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r
vendor: 9,083 bytes, lines 7-9
7); }
8function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
9function asyncGeneratorStep(
9n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
10function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
11function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
12function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
13function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
14function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
15function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
16function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
17/* welcome/js/pages/DocumentsPage.js */
18(function () {
19  var React = window.React;
20  try {
21    // ---------- 基础工具 ----------
22    var loadScriptOnce = function loadScriptOnce(src, testReady) {
23      return new Promise(function (resolve, reject) {
24        try {
25          if (testReady && testReady()) return resolve();
26          var abs = new URL(src, location.origin).href;
27          var existed = Array.from(document.scripts).find(function (s) {
28            return s.src === abs;
29          });
30          if (existed) {
31            var tries = 0;
32            var timer = setInterval(function () {
33              tries++;
34              if (testReady && testReady()) {
35                clearInterval(timer);
36                resolve();
37              } else if (tries > 200) {
38                clearInterval(timer);
39                reject(new Error("Timeout waiting for ".concat(src)));
40              }
41            }, 50);
42            return;
43          }
44          var s = document.createElement('script');
45          s.src = src;
46          s.async = true;
47          s.onload = function () {
48            if (!testReady || testReady()) resolve();else reject(new Error("Loaded ".concat(src, " but ready check failed")));
49          };
50          s.onerror = function () {
51            return reject(new Error("Failed to load ".concat(src)));
52          };
53          document.head.appendChild(s);
54        } catch (e) {
55          reject(e);
56        }
57      });
58    };
59    var ensureMarked = function ensureMarked() {
60      var _window$marked;
61      if ((_window$marked = window.marked) !== null && _window$marked !== void 0 && _window$marked.parse) return Promise.resolve();
62      return loadScriptOnce('https://cdn.jsdelivr.net/npm/marked/marked.min.js', function () {
63        return !!(window.marked && typeof window.marked.parse === 'function');
64      }).then(function () {
65        window.marked.setOptions({
66          gfm: true,
67          breaks: false,
68          headerIds: true,
69          mangle: false
70        });
71      });
72    };
73    var ensureDOMPurify = function ensureDOMPurify() {
74      if (window.DOMPurify) return Promise.resolve();
75      return loadScriptOnce('https://cdn.jsdelivr.net/npm/[email protected]/dist/purify.min.js', function () {
76        return !!window.DOMPurify;
77      })["catch"](function () {
78        return Promise.resolve();
79      });
80    };
81    var ensureGithubMarkdownCSS = function ensureGithubMarkdownCSS() {
82      return new Promise(function (resolve) {
83        var id = 'github-markdown-css';
84        if (document.getElementById(id)) return resolve();
85        var link = document.createElement('link');
86        link.id = id;
87        link.rel = 'stylesheet';
88        link.href = 'https://cdn.jsdelivr.net/npm/[email protected]/github-markdown.css';
89        link.onload = function () {
90          return resolve();
91        };
92        link.onerror = function () {
93          return resolve();
94        };
95        document.head.appendChild(link);
96      });
97    };
98    var slugify = function slugify(text) {
99      return String(text || '').toLowerCase().trim().replace(/\s+/g, '-').replace(/[^a-z0-9\-]/g, '');
100    };
101    var ensureMathJaxReady = function ensureMathJaxReady() {
102      return new Promise(function (resolve) {
103        (function waitMJ() {
104          var tries = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
105          var ok = !!(window.MathJax && window.MathJax.typesetPromise);
106          if (ok) {
107            var _window$MathJax$start;
108            var p = (_window$MathJax$start = window.MathJax.startup) === null || _window$MathJax$start === void 0 ? void 0 : _window$MathJax$start.promise;
109            if (p !== null && p !== void 0 && p.then) p.then(function () {
110              return resolve();
111            });else resolve();
112          } else if (tries > 200) {
113            resolve();
114          } else {
115            setTimeout(function () {
116              return waitMJ(tries + 1);
117            }, 50);
118          }
119        })();
120      });
121    };
122    var typesetMath = function typesetMath(rootEl) {
123      var _window$MathJax$start2, _p$then;
124      if (!rootEl || !window.MathJax || !window.MathJax.typesetPromise) return;
125      var p = (_window$MathJax$start2 = window.MathJax.startup) === null || _window$MathJax$start2 === void 0 ? void 0 : _window$MathJax$start2.promise;
126      (p === null || p === void 0 || (_p$then = p.then) === null || _p$then === void 0 ? void 0 : _p$then.call(p, function () {
127        return window.MathJax.typesetPromise([rootEl]);
128      })) || window.MathJax.typesetPromise([rootEl]);
129    }; // 把 <p>$$…$$</p> / 独立行 $$…$$ 改为块级显示
130    var preprocessBlockMath = function preprocessBlockMath(html) {
131      if (!html) return html;
132      html = html.replace(/<p>\s*\$\$([\s\S]*?)\$\$\s*<\/p>/g, function (_, tex) {
133        return "<div class=\"mjx-display\">\\( \\displaystyle ".concat(tex, " \\)</div>");
134      });
135      html = html.replace(/(?:^|\n)\s*\$\$([\s\S]*?)\$\$\s*(?=\n|$)/g, function (m, tex) {
136        return "\n<div class=\"mjx-display\">\\( \\displaystyle ".concat(tex, " \\)</div>\n");
137      });
138      return html;
139    }; // ---------- 常量 ----------
140    var buildDocumentModel = function buildDocumentModel(html) {
141      if (!html) return {
142        pages: [],
143        toc: [],
144        headingPageMap: {}
145      };
146      var wrap = document.createElement('div');
147      wrap.innerHTML = html;
148      var nodes = Array.from(wrap.childNodes || []);
149      if (!nodes.length) return {
150        pages: [],
151        toc: [],
152        headingPageMap: {}
153      };
154      var pages = [];
155      var toc = [];
156      var headingPageMap = {};
157      var seenIds = new Set();
158      var chunk = [];
159      var chunkChars = 0;
160      var PAGE_CHAR_LIMIT = typeof window !== 'undefined' && window.innerWidth < 960 ? 1800 : 2600;
161      function flush() {
162        if (!chunk.length) return;
163        pages.push(chunk.join(''));
164        chunk = [];
165        chunkChars = 0;
166      }
167      nodes.forEach(function (node, idx) {
168        var isEl = node.nodeType === 1;
169        var tag = isEl ? String(node.tagName || '').toUpperCase() : '';
170        var textSize = String(node.textContent || '').trim().length;
171        var splitByFixedLength = chunkChars + textSize > PAGE_CHAR_LIMIT && chunk.length > 0;
172        if (splitByFixedLength) flush();
173        if (isEl && /^H[1-4]$/.test(tag)) {
174          var text = String(node.textContent || '').trim();
175          if (text) {
176            var rawId = String(node.id || '').trim();
177            var baseId = rawId || slugify(text) || "section-".concat(idx + 1);
178            var nextId = baseId;
179            var suffix = 2;
180            while (seenIds.has(nextId)) nextId = "".concat(baseId, "-").concat(suffix++);
181            seenIds.add(nextId);
182            node.id = nextId;
183            toc.push({
184              id: nextId,
185              text: text,
186              level: Number(tag.slice(1))
187            });
188            headingPageMap[nextId] = pages.length;
189          }
190        }
191        var nodeHtml = node.nodeType === 3 ? node.textContent || '' : node.outerHTML || '';
192        chunk.push(nodeHtml);
193        chunkChars += textSize;
194      });
195      flush();
196      var finalPages = pages.length ? pages : [html];
197      return {
198        pages: finalPages,
199        toc: toc,
200        headingPageMap: headingPageMap
201      };
202    }; // ---------- 组件 ----------
203    var DocumentsPage = function DocumentsPage() {
204      var _React$useState = React.useState('whitepaper'),
205        _React$useState2 = _slicedToArray(_React$useState, 2),
206        tab = _React$useState2[0],
207        setTab = _React$useState2[1];
208      var _React$useState3 = React.useState(false),
209        _React$useState4 = _slicedToArray(_React$useState3, 2),
210        initReady = _React$useState4[0],
211        setInitReady = _React$useState4[1];
212      var _React$useState5 = React.useState(function () {
213          try {
214            var savedTheme = localStorage.getItem(DOCS_THEME_STORAGE_KEY);
215            return savedTheme === 'light' ? 'light' : 'dark';
216          } catch (_unused) {
217            return 'dark';
218          }
219        }),
220        _React$useState6 = _slicedToArray(_React$useState5, 2),
221        docsTheme = _React$useState6[0],
222        setDocsTheme = _React$useState6[1];
223
224      // i18n & t
225      var i18n = null,
226        t = function t(k) {
227          return k;
228        };
229      try {
230        if (typeof window.useLanguage === 'function') {
231          var hook = window.useLanguage();
232          i18n = (hook === null || hook === void 0 ? void 0 : hook.i18n) || null;
233          t = (hook === null || hook === void 0 ? void 0 : hook.t) || t;
234        }
235      } catch (_unused2) {}
236
237      // ✅ 更稳健的语言识别:cn/zh/zh-CN/zh_Hans… -> 'cn';其它 -> 'en'
238      var detectLang = React.useCallback(function (lngLike) {
239        var v = String(lngLike || '').toLowerCase().replace('_', '-');
240        if (/(^|[-])(?:zh|cn)(-|$)/.test(v) || v.includes('zh') || v.includes('han')) return 'cn';
241        return 'en';
242      }, []);
243
244      // 初始语言:i18n -> <html lang> -> navigator
245      var _React$useState7 = React.useState(function () {
246          var _i18n;
247          if ((_i18n = i18n) !== null && _i18n !== void 0 && _i18n.language) return detectLang(i18n.language);
248          var htmlLang = document.documentElement.getAttribute('lang');
249          if (htmlLang) return detectLang(htmlLang);
250          return detectLang(navigator.language);
251        }),
252        _React$useState8 = _slicedToArray(_React$useState7, 2),
253        lang = _React$useState8[0],
254        setLang = _React$useState8[1];
255
256      // A) 订阅 i18n 事件
257      React.useEffect(function () {
258        var _i18n2;
259        if (!((_i18n2 = i18n) !== null && _i18n2 !== void 0 && _i18n2.on)) return;
260        var handler = function handler(lng) {
261          return setLang(function (prev) {
262            var next = detectLang(lng);
263            return prev === next ? prev : next;
264          });
265        };
266        i18n.on('languageChanged', handler);
267        return function () {
268          try {
269            i18n.off('languageChanged', handler);
270          } catch (_unused3) {}
271        };
272      }, [i18n, detectLang]);
273
274      // B) 监听 <html lang> 变化
275      React.useEffect(function () {
276        var el = document.documentElement;
277        var obs = new MutationObserver(function () {
278          var l = el.getAttribute('lang');
279          if (!l) return;
280          var next = detectLang(l);
281          setLang(function (prev) {
282            return prev === next ? prev : next;
283          });
284        });
285        obs.observe(el, {
286          attributes: true,
287          attributeFilter: ['lang']
288        });
289        return function () {
290          return obs.disconnect();
291        };
292      }, [detectLang]);
293
294      // C) 兜底轮询:读取 i18n.language / localStorage('i18nextLng'|'lang') / <html lang>
295      React.useEffect(function () {
296        var stopped = false;
297        var last = lang;
298        var tick = function tick() {
299          if (stopped) return;
300          var cand = i18n && i18n.language || localStorage.getItem('i18nextLng') || localStorage.getItem('lang') || document.documentElement.getAttribute('lang') || '';
301          var next = detectLang(cand);
302          if (next !== last) {
303            last = next;
304            setLang(next);
305          }
306        };
307        var id = setInterval(tick, 200);
308        return function () {
309          stopped = true;
310          clearInterval(id);
311        };
312      }, [i18n, detectLang, lang]);
313
314      // —— 缓存两种语言 HTML —— //
315      var cacheRef = React.useRef(Object.create(null));
316      function loadOne(_x, _x2) {
317        return _loadOne.apply(this, arguments);
318      }
319      function _loadOne() {
320        _loadOne = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee4(fileBase, langCode) {
321          var key, url, res, text, html;
322          return _regeneratorRuntime().wrap(function _callee4$(_context4) {
323            while (1) switch (_context4.prev = _context4.next) {
324              case 0:
325                key = "".concat(fileBase, "_").concat(langCode);
326                if (!cacheRef.current[key]) {
327                  _context4.next = 3;
328                  break;
329                }
330                return _context4.abrupt("return", cacheRef.current[key]);
331              case 3:
332                url = "/KOLECT_Whitepaper.md";
333                _context4.next = 6;
334                return fetch(url, {
335                  cache: 'no-store'
336                });
337              case 6:
338                res = _context4.sent;
339                if (res.ok) {
340                  _context4.next = 9;
341                  break;
342                }
343                throw new Error("HTTP ".concat(res.status));
344              case 9:
345                _context4.next = 11;
346                return res.text();
347              case 11:
348                text = _context4.sent;
349                html = window.marked ? window.marked.parse(text) : text;
350                if (window.DOMPurify) {
351                  html = window.DOMPurify.sanitize(html, {
352                    FORBID_TAGS: ['style'],
353                    FORBID_ATTR: ['style']
354                  });
355                }
356                html = preprocessBlockMath(html);
357                cacheRef.current[key] = html;
358                return _context4.abrupt("return", html);
359              case 17:
360              case "end":
361                return _context4.stop();
362            }
363          }, _callee4);
364        }));
365        return _loadOne.apply(this, arguments);
366      }
367      function preloadBoth(_x3) {
368        return _preloadBoth.apply(this, arguments);
369      }
370      function _preloadBoth() {
371        _preloadBoth = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee5(section) {
372          return _regeneratorRuntime().wrap(function _callee5$(_context5) {
373            while (1) switch (_context5.prev = _context5.next) {
374              case 0:
375                _context5.prev = 0;
376                _context5.next = 3;
377                return Promise.all([loadOne(section.fileBase, 'en'), loadOne(section.fileBase, 'cn')]);
378              case 3:
379                _context5.next = 8;
380                break;
381              case 5:
382                _context5.prev = 5;
383                _context5.t0 = _context5["catch"](0);
384                console.warn('preload warn:', _context5.t0);
385              case 8:
386              case "end":
387                return _context5.stop();
388            }
389          }, _callee5, null, [[0, 5]]);
390        }));
391        return _preloadBoth.apply(this, arguments);
392      }
393      var _React$useState9 = React.useState(''),
394        _React$useState10 = _slicedToArray(_React$useState9, 2),
395        mdHTML = _React$useState10[0],
396        setMdHTML = _React$useState10[1];
397      var _React$useState11 = React.useState(false),
398        _React$useState12 = _slicedToArray(_React$useState11, 2),
399        loading = _React$useState12[0],
400        setLoading = _React$useState12[1];
401      var _React$useState13 = React.useState(''),
402        _React$useState14 = _slicedToArray(_React$useState13, 2),
403        error = _React$useState14[0],
404        setError = _React$useState14[1];
405      var contentRef = React.useRef(null);
406      var pendingScrollHeadingRef = React.useRef('');
407      var _React$useState15 = React.useState([]),
408        _React$useState16 = _slicedToArray(_React$useState15, 2),
409        toc = _React$useState16[0],
410        setToc = _React$useState16[1];
411      var _React$useState17 = React.useState({}),
412        _React$useState18 = _slicedToArray(_React$useState17, 2),
413        headingPageMap = _React$useState18[0],
414        setHeadingPageMap = _React$useState18[1];
415      var _React$useState19 = React.useState(''),
416        _React$useState20 = _slicedToArray(_React$useState19, 2),
417        activeId = _React$useState20[0],
418        setActiveId = _React$useState20[1];
419      var _React$useState21 = React.useState(false),
420        _React$useState22 = _slicedToArray(_React$useState21, 2),
421        mobileTocOpen = _React$useState22[0],
422        setMobileTocOpen = _React$useState22[1];
423      var _React$useState23 = React.useState(0),
424        _React$useState24 = _slicedToArray(_React$useState23, 2),
425        progress = _React$useState24[0],
426        setProgress = _React$useState24[1];
427      var _React$useState25 = React.useState([]),
428        _React$useState26 = _slicedToArray(_React$useState25, 2),
429        pages = _React$useState26[0],
430        setPages = _React$useState26[1];
431      var _React$useState27 = React.useState(0),
432        _React$useState28 = _slicedToArray(_React$useState27, 2),
433        pageIndex = _React$useState28[0],
434        setPageIndex = _React$useState28[1];
435      var currentSection = React.useMemo(function () {
436        return DOC_PANELS.find(function (s) {
437          return s.key === tab;
438        }) || DOC_PANELS[0];
439      }, [tab]);
440      var pageCount = pages.length || (mdHTML ? 1 : 0);
441      var renderHTML = pages[pageIndex] || (pageCount === 1 ? mdHTML : '');
442
443      // 初始化第三方
444      React.useEffect(function () {
445        _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
446          return _regeneratorRuntime().wrap(function _callee$(_context) {
447            while (1) switch (_context.prev = _context.next) {
448              case 0:
449                _context.prev = 0;
450                _context.next = 3;
451                return Promise.all([ensureMarked(), ensureDOMPurify(), ensureGithubMarkdownCSS(), ensureMathJaxReady()]);
452              case 3:
453                _context.next = 8;
454                break;
455              case 5:
456                _context.prev = 5;
457                _context.t0 = _context["catch"](0);
458                console.warn('Docs libs load warn:', _context.t0);
459              case 8:
460                _context.prev = 8;
461                setInitReady(true);
462                return _context.finish(8);
463              case 11:
464              case "end":
465                return _context.stop();
466            }
467          }, _callee, null, [[0, 5, 8, 11]]);
468        }))();
469      }, []);
470
471      // 首次/切 tab:预加载 en+cn,并显示当前语言
472      React.useEffect(function () {
473        if (!initReady) return;
474        var cancelled = false;
475        _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
476          var html;
477          return _regeneratorRuntime().wrap(function _callee2$(_context2) {
478            while (1) switch (_context2.prev = _context2.next) {
479              case 0:
480                setLoading(true);
481                setError('');
482                _context2.prev = 2;
483                _context2.next = 5;
484                return preloadBoth(currentSection);
485              case 5:
486                if (!cancelled) {
487                  _context2.next = 7;
488                  break;
489                }
490                return _context2.abrupt("return");
491              case 7:
492                _context2.next = 9;
493                return loadOne(currentSection.fileBase, lang);
494              case 9:
495                html = _context2.sent;
496                if (!cancelled) {
497                  _context2.next = 12;
498                  break;
499                }
500                return _context2.abrupt("return");
501              case 12:
502                setMdHTML(html);
503                _context2.next = 18;
504                break;
505              case 15:
506                _context2.prev = 15;
507                _context2.t0 = _context2["catch"](2);
508                if (!cancelled) setError("\u52A0\u8F7D\u5931\u8D25\uFF1A".concat(_context2.t0.message));
509              case 18:
510                _context2.prev = 18;
511                if (!cancelled) setLoading(false);
512                return _context2.finish(18);
513              case 21:
514              case "end":
515                return _context2.stop();
516            }
517          }, _callee2, null, [[2, 15, 18, 21]]);
518        }))();
519        return function () {
520          cancelled = true;
521        };
522      }, [initReady, currentSection, lang]);
523
524      // 语言切换:直接用缓存(如未建好则补一次)
525      React.useEffect(function () {
526        if (!initReady) return;
527        var key = "".concat(currentSection.fileBase, "_").concat(lang);
528        var cached = cacheRef.current[key];
529        if (cached) setMdHTML(cached);else _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
530          return _regeneratorRuntime().wrap(function _callee3$(_context3) {
531            while (1) switch (_context3.prev = _context3.next) {
532              case 0:
533                _context3.prev = 0;
534                _context3.t0 = setMdHTML;
535                _context3.next = 4;
536                return loadOne(currentSection.fileBase, lang);
537              case 4:
538                _context3.t1 = _context3.sent;
539                (0, _context3.t0)(_context3.t1);
540                _context3.next = 11;
541                break;
542              case 8:
543                _context3.prev = 8;
544                _context3.t2 = _context3["catch"](0);
545                setError("\u52A0\u8F7D\u5931\u8D25\uFF1A".concat(_context3.t2.message));
546              case 11:
547              case "end":
548                return _context3.stop();
549            }
550          }, _callee3, null, [[0, 8]]);
551        }))();
552      }, [lang, currentSection, initReady]);
553      React.useEffect(function () {
554        var _model$toc;
555        if (!mdHTML) {
556          setPages([]);
557          setToc([]);
558          setHeadingPageMap({});
559          setPageIndex(0);
560          return;
561        }
562        var model = buildDocumentModel(mdHTML);
563        setPages(model.pages.length ? model.pages : [mdHTML]);
564        setToc(model.toc || []);
565        setHeadingPageMap(model.headingPageMap || {});
566        setPageIndex(0);
567        setActiveId(((_model$toc = model.toc) === null || _model$toc === void 0 || (_model$toc = _model$toc[0]) === null || _model$toc === void 0 ? void 0 : _model$toc.id) || '');
568        setMobileTocOpen(false);
569      }, [mdHTML]);
570
571      // 内容更新后排版公式
572      React.useEffect(function () {
573        if (renderHTML) {
574          typesetMath(contentRef.current);
575          try {
576            enhanceYouTubeEmbeds(contentRef.current);
577          } catch (_unused4) {}
578          try {
579            transformFAQToChat(contentRef.current);
580          } catch (_unused5) {}
581          try {
582            enhanceAuditDownload(contentRef.current);
583          } catch (_unused6) {}
584          try {
585            ensureRoadmapImagePlacement(contentRef.current);
586          } catch (_unused7) {}
587          try {
588            var root = contentRef.current;
589            if (root) {
590              var hs = Array.from(root.querySelectorAll('h1,h2,h3,h4'));
591              hs.forEach(function (h) {
592                var txt = (h.textContent || '').trim();
593                if (!txt && h.parentNode) h.parentNode.removeChild(h);
594              });
595            }
596          } catch (_unused8) {}
597        }
598      }, [renderHTML, pageIndex]);
599
600      // GitBook 风格样式(一次注入)
601      React.useEffect(function () {
602        var id = 'docs-page-style';
603        if (document.getElementById(id)) return;
604        var style = document.createElement('style');
605        style.id = id;
606        style.textContent = "\n          .kb-docs-page {\n            --kb-border: rgba(255,255,255,0.2);\n            --kb-bg: transparent;\n            --kb-sidebar-bg: transparent;\n            --kb-muted: #94a3b8;\n            --kb-active: #ffffff;\n            --kb-hover: rgba(255, 255, 255, 0.12);\n            color: #f8fafc;\n          }\n          .kb-docs-page * { box-sizing: border-box; }\n          .kb-docs-shell {\n            background: var(--kb-bg);\n            border: 0;\n            border-radius: 0;\n            overflow: visible;\n            box-shadow: none;\n          }\n          .kb-docs-grid {\n            display: grid;\n            grid-template-columns: 280px minmax(0, 1fr);\n          }\n          .kb-docs-sidebar {\n            border-right: 0;\n            background: var(--kb-sidebar-bg);\n            padding: 20px 14px 24px;\n          }\n          .kb-docs-sticky {\n            position: sticky;\n            top: 24px;\n            max-height: calc(100vh - 160px);\n            overflow: auto;\n          }\n          .kb-docs-section-label {\n            margin-bottom: 10px;\n            font-size: 12px;\n            text-transform: uppercase;\n            letter-spacing: .08em;\n            font-weight: 700;\n            color: #9ca3af;\n          }\n          .kb-doc-tab {\n            width: 100%;\n            text-align: left;\n            border: 0;\n            background: rgba(255,255,255,.06);\n            color: #f8fafc;\n            border-radius: 8px;\n            padding: 8px 10px;\n            font-size: 14px;\n            font-weight: 600;\n            cursor: pointer;\n            transition: background .15s ease, color .15s ease;\n          }\n          .kb-doc-tab:hover { background: rgba(255,255,255,.12); color: #ffffff; }\n          .kb-doc-tab.active {\n            background: var(--kb-hover);\n            color: var(--kb-active);\n          }\n          .kb-docs-divider { display: none; }\n          .toc-title {\n            margin-bottom: 6px;\n            font-size: 12px;\n            text-transform: uppercase;\n            letter-spacing: .08em;\n            font-weight: 700;\n            color: #94a3b8;\n          }\n          .toc-item {\n            display: block;\n            text-decoration: none;\n            color: #cbd5e1;\n            padding: 5px 8px;\n            border-radius: 6px;\n            font-size: 14px;\n            line-height: 1.35;\n            transition: background .15s ease, color .15s ease;\n          }\n          .toc-item:hover { background: rgba(255,255,255,.10); color: #ffffff; }\n          .toc-item.active {\n            background: var(--kb-hover);\n            color: var(--kb-active);\n            font-weight: 600;\n          }\n          .toc-lv2 { padding-left: 16px; }\n          .toc-lv3 { padding-left: 24px; }\n          .toc-lv4 { padding-left: 32px; }
606\n\n          .kb-docs-main {\n            background: transparent;\n            padding: 32px clamp(18px, 4vw, 52px);\n          }\n          .kb-card {\n            background: transparent;\n            border: 0;\n            box-shadow: none;\n            padding: 0;\n          }\n          .markdown-body {\n            background: transparent !important;\n            color: #f8fafc !important;\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n            line-height: 1.7;\n          }\n          .markdown-body h1,\n          .markdown-body h2,\n          .markdown-body h3,\n          .markdown-body h4 {\n            color: #ffffff !important;\n            scroll-margin-top: 120px;\n          }\n          .markdown-body h1 {\n            font-size: clamp(1.6rem, 2.6vw, 2rem);\n            border-bottom: 0;\n            padding-bottom: .35em;\n          }\n          .markdown-body h2 {\n            border-bottom: 0;\n            padding-bottom: .25em;\n          }\n          .markdown-body p { margin: .8em 0; }\n          .markdown-body a { color: #93c5fd; }\n          .markdown-body a:hover { color: #bfdbfe; }\n          .markdown-body strong { color: #ffffff; }\n          .markdown-body hr {\n            border: 0;\n            height: 1px;\n            background: rgba(255,255,255,.15);\n          }\n          .markdown-body blockquote {\n            border-left: 0;\n            color: #e2e8f0;\n            background: rgba(15,23,42,.35);\n            border-radius: 8px;\n            padding: 10px 14px;\n          }\n          .markdown-body table {\n            width: 100%;\n            border-collapse: collapse;\n          }\n          .markdown-body table th,\n          .markdown-body table td {\n            border: 0;\n            padding: .55em .75em;\n            background: rgba(255,255,255,.03);\n          }\n          .markdown-body img {\n            max-width: 100%;\n            border-radius: 8px;\n          }\n          .markdown-body .kb-heading-active {\n            color: #ffffff !important;\n          }\n          .mjx-display {\n            display: block;\n            margin: 1rem 0;\n            text-align: center;\n          }\n\n          .kb-mobile-controls { display: none; }\n          .kb-mobile-card {\n            border: 0;\n            border-radius: 10px;\n            background: transparent;\n            padding: 12px;\n          }\n          .kb-pager {\n            margin-top: 24px;\n            border-top: 0;\n            padding-top: 16px;\n            display: grid;\n            grid-template-columns: 1fr auto 1fr;\n            align-items: center;\n            gap: 10px;\n          }\n          .kb-pager-btn {\n            border: 0;\n            border-radius: 8px;\n            padding: 8px 12px;\n            background: rgba(255,255,255,.08);\n            color: #f8fafc;\n            font-size: 13px;\n            font-weight: 600;\n            cursor: pointer;\n          }\n          .kb-pager-btn:hover:not(:disabled) { background: rgba(255,255,255,.14); }\n          .kb-pager-btn:disabled { opacity: .45; cursor: not-allowed; }\n          .kb-pager-info {\n            text-align: center;\n            color: #cbd5e1;\n            font-size: 13px;\n            font-weight: 600;\n          }\n\n          .reading-progress {\n            position: fixed;\n            left: 0;\n            height: 2px;\n            width: 0;\n            background: #2563eb;\n            transform-origin: 0 0;\n            z-index: 60;\n          }\n\n          .kb-faq-chat { margin-top: 1rem; display: grid; gap: 0.75rem; }\n          .kb-faq-last { font-size: .85rem; color: #cbd5e1; margin-bottom: .5rem; }\n          .kb-chat-item { display: grid; gap: .5rem; }\n          .kb-chat-bubble {\n            display: inline-block;\n            max-width: min(720px, 94%);\n            padding: .65rem .9rem;\n            border-radius: 12px;\n            border: 0;\n          }\n          .kb-chat-q {\n            background: rgba(30,41,59,.55);\n            color: #f8fafc;\n            position: relative;\n            padding-right: 2.2rem;\n          }\n          .kb-chat-a {\n            background: rgba(255,255,255,.12);\n            color: #f8fafc;\n          }\n          .kb-chat-q-wrap { display: flex; justify-content: flex-start; align-items: center; }\n          .kb-chat-a-wrap { display: flex; justify-content: flex-end; }\n          .kb-chat-toggle {\n            width: 22px;\n            height: 22px;\n            border-radius: 7px;\n            border: 0;\n            background: rgba(255,255,255,.2);\n            color: #f8fafc;\n            display: grid;\n            place-items: center;\n            cursor: pointer;\n            user-select: none;\n            line-height: 1;\n            font-size: 15px;\n            position: absolute;\n            right: 8px;\n            top: 50%;\n            transform: translateY(-50%);\n          }\n          .kb-chat-toggle:hover { background: rgba(255,255,255,.3); }
606\n\n          @media (max-width: 960px) {\n            .kb-docs-grid { grid-template-columns: minmax(0, 1fr); }\n            .kb-docs-sidebar { display: none; }\n            .kb-mobile-controls { display: block; margin-bottom: 14px; }\n            .kb-docs-main { padding: 20px 16px; }\n            .kb-pager { grid-template-columns: 1fr; }\n            .kb-pager-info { order: -1; }\n          }\n        ";
607        style.textContent += "\n          /* Calm, Apple-inspired document reader refinement. */\n          body.kb-docs-body {\n            background: #f5f5f7 !important;\n            background-image: linear-gradient(180deg, #f5f5f7 0%, #ffffff 34rem, #ffffff 100%) !important;\n            color: #1d1d1f;\n          }\n          .kb-docs-page {\n            --kb-ink: #1d1d1f;\n            --kb-secondary: #6e6e73;\n            --kb-line: #d2d2d7;\n            --kb-soft-line: #e5e5ea;\n            --kb-surface: rgba(255, 255, 255, 0.9);\n            --kb-sidebar: #f5f5f7;\n            --kb-blue: #0071e3;\n            width: min(1200px, calc(100% - 32px));\n            margin-right: auto;\n            margin-bottom: 3rem;\n            margin-left: auto;\n            padding-bottom: 1rem;\n            color: var(--kb-ink);\n            font-family: -apple-system, BlinkMacSystemFont, \"SF Pro Text\", \"SF Pro Display\", \"Segoe UI\", sans-serif;\n            font-optical-sizing: auto;\n          }\n          .kb-docs-shell {\n            overflow: clip;\n            border: 1px solid rgba(0, 0, 0, 0.12);\n            border-radius: 28px;\n            background: var(--kb-surface);\n            box-shadow: 0 18px 45px rgba(0, 0, 0, 0.08), 0 2px 8px rgba(0, 0, 0, 0.04);\n          }\n          .kb-docs-grid {\n            grid-template-columns: clamp(19rem, 25vw, 23rem) minmax(0, 1fr);\n            min-height: calc(100vh - 8rem);\n          }\n          .kb-docs-sidebar {\n            border-right: 1px solid var(--kb-line);\n            background: var(--kb-sidebar);\n            padding: 1.5rem 0.75rem;\n            min-width: 0;\n          }\n          .kb-docs-sticky {\n            display: flex;\n            flex-direction: column;\n            height: calc(100vh - 2.5rem);\n            max-height: calc(100vh - 2.5rem);\n            padding: 0 0.4rem;\n            overflow: hidden;\n            scrollbar-width: thin;\n            scrollbar-color: #c7c7cc transparent;\n          }\n          .kb-docs-toc-list,\n          .kb-mobile-toc-list {\n            min-height: 0;\n            overflow-x: hidden;\n            overflow-y: auto;\n            overscroll-behavior: contain;\n            scrollbar-gutter: stable;\n            scrollbar-width: thin;\n            scrollbar-color: #c7c7cc transparent;\n          }\n          .kb-docs-toc-list {\n            flex: 1 1 auto;\n            margin: 0 -0.15rem;\n            padding: 0 0.15rem 0.5rem;\n          }\n          .kb-docs-toc-list::-webkit-scrollbar,\n          .kb-mobile-toc-list::-webkit-scrollbar { width: 8px; }\n          .kb-docs-toc-list::-webkit-scrollbar-thumb,\n          .kb-mobile-toc-list::-webkit-scrollbar-thumb {\n            border: 2px solid transparent;\n            border-radius: 999px;\n            background: #c7c7cc;\n            background-clip: content-box;\n          }\n          .kb-docs-section-label,\n          .toc-title,\n          .kb-docs-eyebrow {\n            color: var(--kb-secondary);\n            font-size: 0.68rem;\n            font-weight: 700;\n            letter-spacing: 0.08em;\n            text-transform: uppercase;\n          }\n          .kb-docs-section-label { margin: 0 0 0.75rem; padding: 0 0.7rem; }\n          .toc-title { margin: 1.8rem 0 0.5rem; padding: 0 0.7rem; }\n          .kb-doc-tab {\n            min-height: 2.5rem;\n            border: 0;\n            border-radius: 10px;\n            background: transparent;\n            color: var(--kb-ink);\n            padding: 0.55rem 0.7rem;\n            font-size: 0.9rem;\n            font-weight: 590;\n            transition: background-color 160ms ease, color 160ms ease, transform 160ms ease;\n          }
607\n          .kb-doc-tab:hover { background: rgba(0, 0, 0, 0.055); color: var(--kb-ink); }\n          .kb-doc-tab:active { transform: scale(0.985); }\n          .kb-doc-tab.active {\n            background: rgba(0, 113, 227, 0.12);\n            color: #0066cc;\n            box-shadow: inset 0 0 0 1px rgba(0, 113, 227, 0.1);\n          }\n          .toc-item {\n            position: relative;\n            border-radius: 8px;\n            color: #515154;\n            padding: 0.38rem 0.7rem;\n            font-size: 0.84rem;\n            line-height: 1.35;\n            overflow-wrap: anywhere;\n            transition: background-color 160ms ease, color 160ms ease;\n          }\n          .toc-item:hover { background: rgba(0, 0, 0, 0.045); color: var(--kb-ink); }\n          .toc-item.active {\n            background: transparent;\n            color: #0066cc;\n            font-weight: 620;\n          }\n          .toc-item.active::before {\n            position: absolute;\n            top: 0.45rem;\n            bottom: 0.45rem;\n            left: 0;\n            width: 3px;\n            border-radius: 999px;\n            background: var(--kb-blue);\n            content: '';\n          }\n          .toc-lv2 { padding-left: 1.2rem; }\n          .toc-lv3 { padding-left: 1.7rem; }\n          .toc-lv4 { padding-left: 2.2rem; }\n          .kb-docs-main {\n            min-width: 0;\n            background: #ffffff;\n            padding: clamp(2rem, 5vw, 4.75rem) clamp(1.5rem, 5vw, 6rem) clamp(3rem, 6vw, 5.5rem);\n          }\n          .kb-docs-masthead {\n            max-width: 820px;\n            margin: 0 auto 3.5rem;\n            padding-bottom: 2rem;\n            border-bottom: 1px solid var(--kb-soft-line);\n          }\n          .kb-docs-eyebrow { margin: 0 0 0.65rem; color: #6e6e73; }\n          .kb-docs-masthead-row {\n            display: flex;\n            align-items: flex-start;\n            justify-content: space-between;\n            gap: 1rem;\n          }\n          .kb-docs-title {\n            margin: 0;\n            color: var(--kb-ink);\n            font-size: clamp(2.25rem, 4vw, 3.35rem);\n            font-weight: 700;\n            letter-spacing: -0.052em;\n            line-height: 1;\n          }\n          .kb-docs-intro {\n            max-width: 34rem;\n            margin: 0.9rem 0 0;\n            color: var(--kb-secondary);\n            font-size: 1.05rem;\n            letter-spacing: -0.012em;\n            line-height: 1.55;\n          }\n          .kb-docs-version {\n            flex: 0 0 auto;\n            margin-top: 0.25rem;\n            border: 1px solid var(--kb-line);\n            border-radius: 999px;\n            color: var(--kb-secondary);\n            padding: 0.33rem 0.58rem;\n            font-size: 0.75rem;\n            font-weight: 650;\n            letter-spacing: 0.02em;\n          }\n          .kb-docs-actions {\n            display: inline-flex;\n            align-items: center;\n            gap: 0.5rem;\n          }\n          .kb-docs-theme-toggle {\n            display: inline-flex;\n            align-items: center;\n            justify-content: center;\n            gap: 0.4rem;\n            min-height: 2rem;\n            border: 1px solid var(--kb-line);\n            border-radius: 999px;\n            background: #ffffff;\n            color: var(--kb-ink);\n            padding: 0.35rem 0.65rem;\n            font-size: 0.76rem;\n            font-weight: 650;\n            line-height: 1;\n            transition: transform 160ms ease, background-color 160ms ease, border-color 160ms ease;\n          }\n          .kb-docs-theme-toggle:hover { border-color: #a1a1a6; background: #f5f5f7; }\n          .kb-docs-theme-toggle:active { transform: scale(0.97); }\n          .kb-card { max-width: 820px; margin: 0 auto; }\n          .markdown-body {\n            max-width: 100%;\n            background: transparent !important;\n            color: #424245 !important;\n            font-family: inherit;\n            font-size: 1.02rem;\n            letter-spacing: -0.006em;\n            line-height: 1.72;\n          }\n          .markdown-body h1,\n          .markdown-body h2,\n          .markdown-body h3,\n          .markdown-body h4 {\n            color: var(--kb-ink) !important;\n            font-weight: 700;\n            letter-spacing: -0.035em;\n            line-height: 1.12;\n          }\n          .markdown-body h1 {\n            margin-top: 0;\n            margin-bottom: 1.25rem;\n            border: 0;\n            padding: 0;\n            font-size: clamp(2rem, 3.2vw, 2.8rem);\n          }\n          .markdown-body h2 {\n            margin-top: 3.5rem;\n            margin-bottom: 1rem;\n            border: 0;\n            padding: 0;\n            font-size: clamp(1.55rem, 2.4vw, 2.05rem);\n          }\n          .markdown-body h3 { margin-top: 2.4rem; font-size: 1.3rem; }\n          .markdown-body h4 { margin-top: 2rem; font-size: 1.08rem; }\n          .markdown-body p { margin: 1rem 0; }\n          .markdown-body ul,\n          .markdown-body ol { padding-left: 1.35rem; }\n          .markdown-body li + li { margin-top: 0.4rem; }\n          .markdown-body a { color: #0066cc !important; text-decoration-color: rgba(0, 102, 204, 0.32); }\n          .markdown-body a:hover { color: #004f9e !important; text-decoration-color: currentColor; }\n          .markdown-body strong { color: var(--kb-ink) !important; font-weight: 650; }\n          .markdown-body hr { height: 1px; margin: 2.5rem 0; background: var(--kb-soft-line); }\n          .markdown-body blockquote {\n            margin: 1.5rem 0;\n            border-left: 3px solid #a1a1a6;\n            border-radius: 0;\n            background: #f5f5f7;\n            color: #515154;\n            padding: 1rem 1.2rem;\n          }\n          .markdown-body code {\n            border-radius: 6px;\n            background: #f5f5f7;\n            color: #bf4800;\n            padding: 0.16em 0.38em;\n            font-size: 0.88em;\n          }\n          .markdown-body pre {\n            overflow-x: auto;\n            border-radius: 14px;\n            background: #1d1d1f;\n            box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);\n            padding: 1.15rem 1.25rem;\n          }\n          .markdown-body pre code { background: transparent; color: #f5f5f7; padding: 0; }\n          .markdown-body table {\n            display: block;\n            overflow-x: auto;\n            margin: 1.5rem 0;\n            border: 1px solid var(--kb-line);\n            border-radius: 14px;\n            background: #ffffff;\n          }\n          .markdown-body table th,\n          .markdown-body table td {\n            border: 0;\n            border-bottom: 1px solid var(--kb-soft-line);\n            background: transparent;\n            color: #424245;\n            padding: 0.8rem 0.9rem;\n            white-space: normal;\n          }\n          .markdown-body table th { background: #f5f5f7; color: var(--kb-ink); font-weight: 650; }\n          .markdown-body table tr:last-child td { border-bottom: 0; }\n          .markdown-body img { border: 1px solid var(--kb-soft-line); border-radius: 16px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08); }
607\n          .kb-mobile-controls { margin: 0 auto 1.5rem; max-width: 820px; }\n          .kb-mobile-card {\n            border: 1px solid var(--kb-line);\n            border-radius: 16px;\n            background: #f5f5f7;\n            padding: 1rem;\n          }\n          .kb-mobile-toc-toggle {\n            width: 100%;\n            margin-top: 0.75rem;\n            border: 1px solid var(--kb-line);\n            border-radius: 10px;\n            background: #ffffff;\n            color: var(--kb-ink);\n            padding: 0.62rem 0.75rem;\n            text-align: left;\n            font-size: 0.88rem;\n            font-weight: 600;\n          }\n          .kb-mobile-toc-list {\n            max-height: min(50vh, 28rem);\n            margin-top: 0.5rem;\n            padding-right: 0.2rem;\n          }\n          .kb-pager {\n            max-width: 820px;\n            margin: 3.5rem auto 0;\n            border-top: 1px solid var(--kb-soft-line);\n            padding-top: 1.5rem;\n          }\n          .kb-pager-btn {\n            border: 1px solid var(--kb-line);\n            border-radius: 10px;\n            background: #ffffff;\n            color: #0066cc;\n            padding: 0.68rem 0.9rem;\n            font-size: 0.84rem;\n            font-weight: 650;\n            transition: transform 160ms ease, background-color 160ms ease, border-color 160ms ease;\n          }\n          .kb-pager-btn:hover:not(:disabled) { border-color: #a1a1a6; background: #f5f5f7; }\n          .kb-pager-btn:active:not(:disabled) { transform: scale(0.98); }\n          .kb-pager-info { color: var(--kb-secondary); font-weight: 600; }\n          .kb-docs-status {\n            max-width: 820px;\n            margin: 0 auto;\n            border: 1px solid var(--kb-line);\n            border-radius: 14px;\n            background: #f5f5f7;\n            color: var(--kb-secondary);\n            padding: 1rem 1.1rem;\n            font-size: 0.94rem;\n          }\n          .kb-docs-status--error { border-color: #f0b8b8; background: #fff2f2; color: #b42318; }\n          .reading-progress { height: 3px; background: #0071e3; box-shadow: 0 1px 5px rgba(0, 113, 227, 0.25); }\n          .kb-faq-last { color: var(--kb-secondary); }\n          .kb-chat-bubble { border: 1px solid var(--kb-line); border-radius: 16px; color: var(--kb-ink); }\n          .kb-chat-q { background: #f5f5f7; }\n          .kb-chat-a { background: #ffffff; }\n          .kb-chat-toggle { border: 1px solid var(--kb-line); background: #ffffff; color: #0066cc; }\n          .kb-chat-toggle:hover { background: #f5f5f7; }\n          body.kb-docs-body.kb-docs-body--dark {\n            background: #0d0d0f !important;\n            background-image: linear-gradient(180deg, #151518 0%, #0d0d0f 38rem, #0d0d0f 100%) !important;\n          }\n          .kb-docs-page--dark {\n            --kb-ink: #f5f5f7;\n            --kb-secondary: #a1a1a6;\n            --kb-line: #3a3a3c;\n            --kb-soft-line: #2c2c2e;\n            --kb-surface: rgba(28, 28, 30, 0.94);\n            --kb-sidebar: #1c1c1e;\n            --kb-blue: #0a84ff;\n          }\n          .kb-docs-page--dark .kb-docs-shell {\n            border-color: rgba(255, 255, 255, 0.13);\n            box-shadow: 0 22px 56px rgba(0, 0, 0, 0.34), 0 2px 9px rgba(0, 0, 0, 0.22);\n          }\n          .kb-docs-page--dark .kb-docs-main { background: #151517; }\n          .kb-docs-page--dark .kb-doc-tab:hover,\n          .kb-docs-page--dark .toc-item:hover { background: rgba(255, 255, 255, 0.08); }\n          .kb-docs-page--dark .kb-doc-tab.active { background: rgba(10, 132, 255, 0.2); color: #64b5ff; box-shadow: inset 0 0 0 1px rgba(100, 181, 255, 0.12); }\n          .kb-docs-page--dark .toc-item { color: #c7c7cc; }\n          .kb-docs-page--dark .toc-item.active { color: #64b5ff; }\n          .kb-docs-page--dark .kb-docs-eyebrow { color: #a1a1a6; }\n          .kb-docs-page--dark .kb-docs-version,\n          .kb-docs-page--dark .kb-docs-theme-toggle,\n          .kb-docs-page--dark .kb-pager-btn,\n          .kb-docs-page--dark .kb-mobile-toc-toggle,\n          .kb-d
607ocs-page--dark .kb-chat-toggle { background: #242426; color: var(--kb-ink); }\n          .kb-docs-page--dark .kb-docs-theme-toggle:hover,\n          .kb-docs-page--dark .kb-pager-btn:hover:not(:disabled),\n          .kb-docs-page--dark .kb-chat-toggle:hover { border-color: #636366; background: #2c2c2e; }\n          .kb-docs-page--dark .kb-pager-btn { color: #64b5ff; }\n          .kb-docs-page--dark .markdown-body { color: #d1d1d6 !important; }\n          .kb-docs-page--dark .markdown-body h1,\n          .kb-docs-page--dark .markdown-body h2,\n          .kb-docs-page--dark .markdown-body h3,\n          .kb-docs-page--dark .markdown-body h4,\n          .kb-docs-page--dark .markdown-body strong { color: var(--kb-ink) !important; }\n          .kb-docs-page--dark .markdown-body a { color: #64b5ff !important; text-decoration-color: rgba(100, 181, 255, 0.45); }\n          .kb-docs-page--dark .markdown-body a:hover { color: #9ed0ff !important; }\n          .kb-docs-page--dark .markdown-body blockquote,\n          .kb-docs-page--dark .markdown-body code,\n          .kb-docs-page--dark .kb-mobile-card,\n          .kb-docs-page--dark .kb-docs-status,\n          .kb-docs-page--dark .kb-chat-q { background: #242426; color: #d1d1d6; }\n          .kb-docs-page--dark .markdown-body code { color: #ffb570; }\n          .kb-docs-page--dark .markdown-body table { border-color: var(--kb-line); background: #1c1c1e; }\n          .kb-docs-page--dark .markdown-body table th { background: #242426; color: var(--kb-ink); }\n          .kb-docs-page--dark .markdown-body table td { border-color: var(--kb-soft-line); color: #d1d1d6; }\n          .kb-docs-page--dark .markdown-body img { border-color: var(--kb-line); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28); }\n          .kb-docs-page--dark .kb-chat-a { background: #1c1c1e; }\n          .kb-docs-page--dark .kb-docs-status--error { background: #3a1d1d; color: #ffb4ab; }\n          .kb-docs-page--light .markdown-body .kb-heading-active {\n            color: #1d1d1f !important;\n          }\n          .kb-docs-page--light .markdown-body table,\n          .kb-docs-page--light .markdown-body table tr {\n            background: #ffffff !important;\n          }\n          .kb-docs-page--light .markdown-body table thead tr,\n          .kb-docs-page--light .markdown-body table th {\n            background: #f5f5f7 !important;\n          }\n          .kb-docs-page--light .markdown-body table th,\n          .kb-docs-page--light .markdown-body table td {\n            border-color: #e5e5ea !important;\n            color: #424245 !important;\n          }\n          .kb-docs-page--light .markdown-body table th {\n            color: #1d1d1f !important;\n          }\n          .kb-docs-page--dark .markdown-body .kb-heading-active {\n            color: #f5f5f7 !important;\n          }\n          .kb-docs-page--dark .markdown-body table tr {\n            background: #1c1c1e !important;\n          }\n          .kb-docs-page--dark .markdown-body table thead tr {\n            background: #242426 !important;\n          }\n          @media (max-width: 960px) {\n            .kb-docs-page { width: calc(100% - 32px); margin-bottom: 1.5rem; }\n            .kb-docs-shell { border-radius: 22px; }\n            .kb-docs-grid { grid-template-columns: minmax(0, 1fr); }\n            .kb-docs-main { padding: 2rem 1.25rem 3rem; }\n            .kb-docs-masthead { margin-bottom: 2rem; padding-bottom: 1.5rem; }\n            .kb-mobile-controls { display: block; }\n          }\n          @media (max-width: 640px) {\n            .kb-docs-page { width: calc(100% - 12px); padding-bottom: 0.375rem; }\n            .kb-docs-shell { width: 100%; border-radius: 18px; }\n            .kb-docs-grid,\n            .kb-docs-main,\n            .kb-docs-masthead,\n            .kb-mobile-controls,\n            .kb-card,\n            .markdown-body { width: 100%; min-width: 0; max-width: 100%; }\n            .kb-docs-main { padding: 1.25rem 1rem 2.25rem; }\n            .kb-docs-masthead-row { flex-direction: column; }\n            .kb-docs-actions { width: 100%; justify-content: space-between; }
607\n            .kb-docs-title { font-size: clamp(2rem, 11vw, 2.25rem); }\n            .kb-docs-intro { font-size: 0.98rem; }\n            .kb-docs-version { margin-top: 0.05rem; }\n            .kb-mobile-controls { margin-bottom: 2rem; }\n            .kb-mobile-card {\n              border: 0;\n              border-top: 1px solid var(--kb-soft-line);\n              border-bottom: 1px solid var(--kb-soft-line);\n              border-radius: 0;\n              background: transparent;\n              padding: 1rem 0;\n            }\n            .kb-docs-page--dark .kb-mobile-card { background: transparent; }\n            .kb-mobile-card .kb-docs-section-label { margin-bottom: 0.55rem; padding: 0 0.15rem; }\n            .kb-mobile-card .kb-doc-tab { min-height: 2.75rem; }\n            .kb-mobile-toc-toggle {\n              display: flex;\n              align-items: center;\n              justify-content: space-between;\n              min-height: 2.75rem;\n              border: 0;\n              background: rgba(118, 118, 128, 0.09);\n              padding-right: 0.9rem;\n            }\n            .kb-mobile-toc-toggle::after {\n              color: var(--kb-secondary);\n              content: '\u203A';\n              font-size: 1.25rem;\n              line-height: 1;\n              transform: rotate(90deg);\n              transition: transform 180ms ease;\n            }\n            .kb-mobile-toc-toggle[aria-expanded='true']::after { transform: rotate(-90deg); }\n            .kb-mobile-toc-list {\n              max-height: min(52vh, 24rem);\n              margin-top: 0.75rem;\n              border-top: 1px solid var(--kb-soft-line);\n              padding: 0.75rem 0 0;\n            }\n            .kb-mobile-toc-list .toc-item {\n              display: flex;\n              align-items: center;\n              min-height: 2.75rem;\n              font-size: 0.9rem;\n            }\n            .markdown-body { overflow-wrap: anywhere; font-size: 0.98rem; line-height: 1.68; }\n            .markdown-body h2 { margin-top: 2.75rem; }\n            .markdown-body pre { margin-right: -0.1rem; margin-left: -0.1rem; border-radius: 12px; padding: 1rem; }\n            .markdown-body table { max-width: 100%; }\n            .kb-pager { grid-template-columns: 1fr 1fr; }\n            .kb-pager-info { grid-column: 1 / -1; }\n          }\n          @media (prefers-reduced-motion: reduce) {\n            .kb-docs-page *, .kb-docs-page *::before, .kb-docs-page *::after { scroll-behavior: auto !important; transition-duration: 0.01ms !important; }\n          }\n          @media (prefers-contrast: more) {\n            .kb-docs-shell, .kb-docs-sidebar, .kb-docs-main { border-color: #86868b; }\n            .markdown-body { color: #1d1d1f !important; }\n          }\n        ";
608        document.head.appendChild(style);
609      }, []);
610
611      // Keep the document reader visually separate from the marketing page.
612      React.useEffect(function () {
613        document.body.classList.add('kb-docs-body');
614        document.body.classList.toggle('kb-docs-body--dark', docsTheme === 'dark');
615        try {
616          localStorage.setItem(DOCS_THEME_STORAGE_KEY, docsTheme);
617        } catch (_unused9) {}
618        return function () {
619          return document.body.classList.remove('kb-docs-body', 'kb-docs-body--dark');
620        };
621      }, [docsTheme]);
622
623      // 把 YouTube 缩略图链接替换为可播放的 iframe(宽度与图片一致,点击播放)
624      function enhanceYouTubeEmbeds(root) {
625        if (!root) return;
626        var anchors = Array.from(root.querySelectorAll('a[href^="https://www.youtube.com/watch"], a[href^="https://youtu.be/"]'));
627        anchors.forEach(function (a) {
628          var img = a.querySelector('img');
629          if (!img) return;
630          var href = a.getAttribute('href') || '';
631          var vid = function () {
632            try {
633              var u = new URL(href);
634              if (u.hostname.includes('youtube.com')) {
635                return u.searchParams.get('v');
636              }
637              if (u.hostname.includes('youtu.be')) {
638                return u.pathname.replace(/^\//, '');
639              }
640            } catch (_unused10) {}
641            var m = href.match(/[?&]v=([A-Za-z0-9_-]{6,})/) || href.match(/youtu\.be\/([A-Za-z0-9_-]{6,})/);
642            return m ? m[1] : null;
643          }();
644          if (!vid) return;
645          var natW = img.naturalWidth || 16;
646          var natH = img.naturalHeight || 9;
647          var ar = "".concat(natW, " / ").concat(natH);
648          var wrapper = document.createElement('div');
649          wrapper.className = 'kb-video-wrapper';
650          Object.assign(wrapper.style, {
651            position: 'relative',
652            width: '100%',
653            aspectRatio: ar,
654            background: '#000',
655            borderRadius: '12px',
656            overflow: 'hidden',
657            cursor: 'pointer'
658          });
659          var thumb = img.cloneNode(true);
660          Object.assign(thumb.style, {
661            width: '100%',
662            height: '100%',
663            objectFit: 'cover',
664            display: 'block',
665            filter: 'brightness(0.9)'
666          });
667          var play = document.createElement('div');
668          Object.assign(play.style, {
669            position: 'absolute',
670            left: '50%',
671            top: '50%',
672            transform: 'translate(-50%,-50%)',
673            width: '64px',
674            height: '64px',
675            borderRadius: '50%',
676            background: 'rgba(255,255,255,0.18)',
677            boxShadow: '0 8px 24px rgba(0,0,0,0.35), inset 0 0 0 1px rgba(255,255,255,0.25)',
678            display: 'grid',
679            placeItems: 'center',
680            backdropFilter: 'blur(6px)'
681          });
682          var triangle = document.createElement('div');
683          Object.assign(triangle.style, {
684            width: '0',
685            height: '0',
686            borderLeft: '18px solid #fff',
687            borderTop: '12px solid transparent',
688            borderBottom: '12px solid transparent',
689            marginLeft: '4px'
690          });
691          play.appendChild(triangle);
692          wrapper.appendChild(thumb);
693          wrapper.appendChild(play);
694          wrapper.addEventListener('click', function () {
695            var iframe = document.createElement('iframe');
696            iframe.width = '100%';
697            iframe.height = '100%';
698            iframe.src = "https://www.youtube.com/embed/".concat(vid, "?autoplay=1&rel=0");
699            iframe.title = 'YouTube video player';
700            iframe.frameBorder = '0';
701            iframe.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share';
702            iframe.allowFullscreen = true;
703            wrapper.replaceChildren(iframe);
704            wrapper.style.cursor = 'default';
705          }, {
706            once: true
707          });
708          a.replaceWith(wrapper);
709        });
710      }
711      function enhanceAuditDownload(root) {
712        if (!root) return;
713        var links = Array.from(root.querySelectorAll('a[href$="SlowMist_audit_report.pdf"]'));
714        links.forEach(function (a) {
715          a.setAttribute('download', 'SlowMist_audit_report.pdf');
716          a.style.cursor = 'pointer';
717          a.addEventListener('click', function (e) {
718            try {
719              e.preventDefault();
720              var url = a.getAttribute('href') || '/SlowMist_audit_report.pdf';
721              var link = document.createElement('a');
722              link.href = url;
723              link.download = 'SlowMist_audit_report.pdf';
724              link.rel = 'noopener';
725              document.body.appendChild(link);
726              link.click();
727              document.body.removeChild(link);
728            } catch (_unused11) {}
729          }, {
730            once: true
731          });
732        });
733      }
734      function ensureRoadmapImagePlacement(root) {
735        if (!root) return;
736        var hs = Array.from(root.querySelectorAll('h1,h2,h3,h4'));
737        var roadmapH = hs.find(function (h) {
738          return (h.textContent || '').trim().toLowerCase() === 'roadmap';
739        });
740        if (!roadmapH) return;
741        var pTarget = null;
742        var cur = roadmapH.nextElementSibling;
743        while (cur) {
744          var tag = cur.tagName ? cur.tagName.toLowerCase() : '';
745          if (tag === 'h1' || tag === 'h2' || tag === 'h3' || tag === 'h4') break;
746          if (!pTarget && tag === 'p') {
747            var txt = cur.textContent || '';
748            if (txt.includes('Kolect’s roadmap outlines')) pTarget = cur;
749          }
750          cur = cur.nextElementSibling;
751        }
752        if (!pTarget) return;
753        var img = null;
754        cur = pTarget.nextElementSibling;
755        while (cur) {
756          var _tag = cur.tagName ? cur.tagName.toLowerCase() : '';
757          if (_tag === 'h1' || _tag === 'h2' || _tag === 'h3' || _tag === 'h4') break;
758          if (_tag === 'img' && /Roadmap\.jpg$/i.test(cur.getAttribute('src') || '')) {
759            img = cur;
760            break;
761          }
762          cur = cur.nextElementSibling;
763        }
764        if (!img) {
765          img = document.createElement('img');
766          img.src = 'Roadmap.jpg';
767          img.alt = 'Roadmap image';
768        }
769        img.style.display = 'block';
770        img.style.maxWidth = '100%';
771        img.style.margin = '12px 0';
772        pTarget.parentNode.insertBefore(img, pTarget.nextSibling);
773        var dups = Array.from(root.querySelectorAll('img[src$="Roadmap.jpg"]'));
774        dups.forEach(function (el) {
775          if (el !== img && el.parentNode) el.parentNode.removeChild(el);
776        });
777      }
778      function transformFAQToChat(root) {
779        if (!root) return;
780        if (root.querySelector('.kb-faq-chat')) return;
781        var hs = Array.from(root.querySelectorAll('h1,h2,h3,h4'));
782        var faqH = hs.find(function (h) {
783          return h.textContent && h.textContent.trim().toLowerCase() === 'faq';
784        });
785        if (!faqH) return;
786        var cur = faqH.nextElementSibling;
787        var lastInfo = null;
788        var listEl = null;
789        while (cur) {
790          var tag = cur.tagName ? cur.tagName.toLowerCase() : '';
791          if (!lastInfo && tag === 'p') lastInfo = cur;
792          if (tag === 'ol') {
793            listEl = cur;
794            break;
795          }
796          cur = cur.nextElementSibling;
797        }
798        if (!listEl) return;
799        var wrap = document.createElement('div');
800        wrap.className = 'kb-faq-chat';
801        if (lastInfo) {
802          var info = document.createElement('div');
803          info.className = 'kb-faq-last';
804          info.innerHTML = lastInfo.innerHTML;
805          wrap.appendChild(info);
806        }
807        var items = Array.from(listEl.children || []);
808        items.forEach(function (li) {
809          var ps = Array.from(li.children || []).filter(function (el) {
810            return String(el.tagName || '').toLowerCase() === 'p';
811          });
812          var qText = '';
813          if (ps.length) {
814            var strong = ps[0].querySelector('strong');
815            qText = strong ? strong.textContent || strong.innerText || '' : ps[0].textContent || '';
816          } else {
817            qText = li.firstChild ? li.textContent || '' : '';
818          }
819          var ansHtml = function () {
820            if (ps.length >= 2) {
821              var frags = ps.slice(1).map(function (p) {
822                return p.innerHTML;
823              });
824              return frags.join('');
825            }
826            if (ps.length === 1) {
827              var html0 = ps[0].innerHTML || '';
828              var idx = html0.toLowerCase().indexOf('</strong>');
829              if (idx >= 0) {
830                var after = html0.slice(idx + 9);
831                after = after.replace(/^\s*<br\s*\/?>\s*/i, '');
832                if (after.trim()) return after;
833              }
834            }
835            var clones = Array.from(li.childNodes).filter(function (n) {
836              return !(ps[0] && n === ps[0]);
837            });
838            var div = document.createElement('div');
839            clones.forEach(function (n) {
840              return div.appendChild(n.cloneNode(true));
841            });
842            return div.innerHTML;
843          }();
844          var item = document.createElement('div');
845          item.className = 'kb-chat-item';
846          var qWrap = document.createElement('div');
847          qWrap.className = 'kb-chat-q-wrap';
848          var qBubble = document.createElement('div');
849          qBubble.className = 'kb-chat-bubble kb-chat-q';
850          qBubble.textContent = qText.trim();
851          qWrap.appendChild(qBubble);
852          var toggle = document.createElement('button');
853          toggle.className = 'kb-chat-toggle';
854          toggle.type = 'button';
855          toggle.textContent = '+';
856          toggle.setAttribute('aria-expanded', 'false');
857          qBubble.appendChild(toggle);
858          var aWrap = document.createElement('div');
859          aWrap.className = 'kb-chat-a-wrap';
860          var aBubble = document.createElement('div');
861          aBubble.className = 'kb-chat-bubble kb-chat-a';
862          aBubble.innerHTML = ansHtml;
863          aWrap.appendChild(aBubble);
864          aWrap.style.display = 'none';
865          var opened = false;
866          toggle.addEventListener('click', function () {
867            opened = !opened;
868            aWrap.style.display = opened ? '' : 'none';
869            toggle.textContent = opened ? '−' : '+';
870            toggle.setAttribute('aria-expanded', opened ? 'true' : 'false');
871          });
872          item.appendChild(qWrap);
873          item.appendChild(aWrap);
874          wrap.appendChild(item);
875        });
876        var anchor = listEl.nextElementSibling;
877        if (anchor) {
878          anchor.parentNode.insertBefore(wrap, anchor);
879        } else {
880          listEl.parentNode.appendChild(wrap);
881        }
882        if (lastInfo && lastInfo.parentNode) lastInfo.parentNode.removeChild(lastInfo);
883        if (listEl.parentNode) listEl.parentNode.removeChild(listEl);
884      }
885
886      // 滚动高亮
887      React.useEffect(function () {
888        var root = contentRef.current;
889        if (!root) return;
890        var els = Array.from(root.querySelectorAll('h1, h2, h3, h4')).filter(function (el) {
891          return (el.textContent || '').trim().length > 0;
892        });
893        if (!els.length) return;
894        var io = new IntersectionObserver(function (entries) {
895          entries.forEach(function (entry) {
896            if (entry.isIntersecting) {
897              setActiveId(entry.target.id);
898              els.forEach(function (el) {
899                el.classList.toggle('kb-heading-active', el === entry.target);
900              });
901            }
902          });
903        }, {
904          rootMargin: '-80px 0px -70% 0px',
905          threshold: 0.1
906        });
907        els.forEach(function (el) {
908          return io.observe(el);
909        });
910        return function () {
911          els.forEach(function (el) {
912            return io.unobserve(el);
913          });
914          io.disconnect();
915        };
916      }, [toc, pageIndex, renderHTML]);
917
918      // 与 Header 不重叠
919      var _React$useState29 = React.useState(120),
920        _React$useState30 = _slicedToArray(_React$useState29, 2),
921        topOffset = _React$useState30[0],
922        setTopOffset = _React$useState30[1];
923      React.useEffect(function () {
924        function calc() {
925          var header = document.querySelector('header[data-name="header-component"]');
926          var h = header ? header.offsetHeight : 96;
927          setTopOffset(h + 24);
928        }
929        calc();
930        window.addEventListener('resize', calc);
931        setTimeout(calc, 200);
932        return function () {
933          return window.removeEventListener('resize', calc);
934        };
935      }, []);
936
937      // 阅读进度条
938      React.useEffect(function () {
939        function onScroll() {
940          var el = contentRef.current;
941          if (!el) return;
942          var start = el.offsetTop;
943          var end = start + el.scrollHeight - window.innerHeight;
944          var y = Math.min(Math.max(window.scrollY, start), end);
945          var p = end > start ? (y - start) / (end - start) * 100 : 0;
946          setProgress(Math.max(0, Math.min(100, p)));
947        }
948        window.addEventListener('scroll', onScroll, {
949          passive: true
950        });
951        onScroll();
952        return function () {
953          return window.removeEventListener('scroll', onScroll);
954        };
955      }, [renderHTML, topOffset, pageIndex]);
956      var scrollToHeadingNow = React.useCallback(function (id) {
957        var el = document.getElementById(id);
958        if (!el) return;
959        var y = el.getBoundingClientRect().top + window.scrollY - topOffset + 8;
960        window.scrollTo({
961          top: y,
962          behavior: 'smooth'
963        });
964        setActiveId(id);
965      }, [topOffset]);
966      var scrollToHeading = React.useCallback(function (id) {
967        var closeMobile = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
968        var targetPage = headingPageMap[id];
969        setActiveId(id);
970        if (Number.isInteger(targetPage) && targetPage !== pageIndex) {
971          pendingScrollHeadingRef.current = id;
972          setPageIndex(targetPage);
973        } else {
974          scrollToHeadingNow(id);
975        }
976        if (closeMobile) setMobileTocOpen(false);
977      }, [headingPageMap, pageIndex, scrollToHeadingNow]);
978      var goToPage = React.useCallback(function (nextIndex) {
979        var _contentRef$current;
980        if (nextIndex < 0 || nextIndex >= pageCount || nextIndex === pageIndex) return;
981        pendingScrollHeadingRef.current = '';
982        setPageIndex(nextIndex);
983        var firstHeading = toc.find(function (item) {
984          return headingPageMap[item.id] === nextIndex;
985        });
986        setActiveId(firstHeading ? firstHeading.id : '');
987        setMobileTocOpen(false);
988        var rootTop = (((_contentRef$current = contentRef.current) === null || _contentRef$current === void 0 ? void 0 : _contentRef$current.getBoundingClientRect().top) || 0) + window.scrollY - topOffset + 8;
989        window.scrollTo({
990          top: Math.max(0, rootTop),
991          behavior: 'smooth'
992        });
993      }, [pageCount, pageIndex, topOffset, toc, headingPageMap]);
994      React.useEffect(function () {
995        var pendingId = pendingScrollHeadingRef.current;
996        if (!pendingId) return;
997        var el = document.getElementById(pendingId);
998        if (!el) return;
999        pendingScrollHeadingRef.current = '';
1000        requestAnimationFrame(function () {
1001          return scrollToHeadingNow(pendingId);
1002        });
1003      }, [renderHTML, pageIndex, scrollToHeadingNow]);
1004      var docsStickyTop = Math.max(16, topOffset - 24);
1005      var docsStickyHeight = "calc(100vh - ".concat(docsStickyTop + 16, "px)");
1006
1007      // —— UI ——(文案来自 t('documents.xxx'))
1008      return React.createElement(React.Fragment, null, window.Header ? React.createElement(window.Header, {
1009        onLoginClick: window.onLoginClick || function () {}
1010      }) : null, React.createElement('div', {
1011        className: "kb-docs-page kb-docs-page--".concat(docsTheme),
1012        style: {
1013          marginTop: "".concat(topOffset, "px")
1014        }
1015      }, React.createElement('div', {
1016        className: 'kb-docs-shell'
1017      }, React.createElement('div', {
1018        className: 'kb-docs-grid'
1019      }, React.createElement('aside', {
1020        className: 'kb-docs-sidebar',
1021        'data-docs-toc': '1'
1022      }, React.createElement.apply(React, ['div', {
1023        className: 'kb-docs-sticky',
1024        style: {
1025          top: "".concat(docsStickyTop, "px"),
1026          height: docsStickyHeight,
1027          maxHeight: docsStickyHeight
1028        }
1029      }, React.createElement('div', {
1030        className: 'kb-docs-section-label'
1031      }, 'Documents')].concat(_toConsumableArray(DOC_PANELS.map(function (panel) {
1032        return React.createElement('button', {
1033          key: panel.key,
1034          type: 'button',
1035          className: "kb-doc-tab ".concat(tab === panel.key ? 'active' : ''),
1036          onClick: function onClick() {
1037            return setTab(panel.key);
1038          }
1039        }, panel.label);
1040      })), [React.createElement('hr', {
1041        className: 'kb-docs-divider'
1042      }), React.createElement('div', {
1043        className: 'toc-title'
1044      }, 'On this page'), React.createElement.apply(React, ['nav', {
1045        className: 'kb-docs-toc-list space-y-1',
1046        'aria-label': 'Table of contents'
1047      }].concat(_toConsumableArray(toc.map(function (item) {
1048        return React.createElement('a', {
1049          key: item.id,
1050          href: "#".concat(item.id),
1051          onClick: function onClick(e) {
1052            e.preventDefault();
1053            scrollToHeading(item.id);
1054          },
1055          className: "toc-item ".concat(activeId === item.id ? 'active' : '', " ").concat(item.level === 2 ? 'toc-lv2' : item.level === 3 ? 'toc-lv3' : item.level === 4 ? 'toc-lv4' : '')
1056        }, item.text);
1057      }))))]))), React.createElement('main', {
1058        className: 'kb-docs-main'
1059      }, React.createElement('div', {
1060        className: 'kb-docs-masthead'
1061      }, React.createElement('p', {
1062        className: 'kb-docs-eyebrow'
1063      }, 'KOLECT · DOCUMENTATION'), React.createElement('div', {
1064        className: 'kb-docs-masthead-row'
1065      }, React.createElement('div', null, React.createElement('p', {
1066        className: 'kb-docs-title'
1067      }, currentSection.label), React.createElement('p', {
1068        className: 'kb-docs-intro'
1069      }, 'The product and protocol reference for KOLECT.')), React.createElement('div', {
1070        className: 'kb-docs-actions'
1071      }, React.createElement('span', {
1072        className: 'kb-docs-version'
1073      }, 'v1.0'), React.createElement('button', {
1074        type: 'button',
1075        className: 'kb-docs-theme-toggle',
1076        onClick: function onClick() {
1077          return setDocsTheme(function (theme) {
1078            return theme === 'dark' ? 'light' : 'dark';
1079          });
1080        },
1081        'aria-label': docsTheme === 'dark' ? 'Switch to light appearance' : 'Switch to dark appearance',
1082        'aria-pressed': docsTheme === 'dark',
1083        title: docsTheme === 'dark' ? 'Switch to light appearance' : 'Switch to dark appearance'
1084      }, React.createElement('i', {
1085        className: "fa-solid ".concat(docsTheme === 'dark' ? 'fa-sun' : 'fa-moon'),
1086        'aria-hidden': 'true'
1087      }), React.createElement('span', null, docsTheme === 'dark' ? 'Light' : 'Dark'))))), React.createElement('div', {
1088        className: 'kb-mobile-controls'
1089      }, React.createElement('div', {
1090        className: 'kb-mobile-card'
1091      }, React.createElement('div', {
1092        className: 'kb-docs-section-label'
1093      }, 'Documents'), React.createElement.apply(React, ['div', {
1094        className: 'space-y-2'
1095      }].concat(_toConsumableArray(DOC_PANELS.map(function (panel) {
1096        return React.createElement('button', {
1097          key: panel.key,
1098          type: 'button',
1099          className: "kb-doc-tab ".concat(tab === panel.key ? 'active' : ''),
1100          onClick: function onClick() {
1101            return setTab(panel.key);
1102          }
1103        }, panel.label);
1104      })))), React.createElement('button', {
1105        type: 'button',
1106        onClick: function onClick() {
1107          return setMobileTocOpen(function (v) {
1108            return !v;
1109          });
1110        },
1111        className: 'kb-mobile-toc-toggle',
1112        'aria-expanded': mobileTocOpen,
1113        'aria-controls': 'kb-mobile-toc'
1114      }, mobileTocOpen ? 'Hide Contents' : 'Show Contents'), mobileTocOpen && React.createElement.apply(React, ['nav', {
1115        id: 'kb-mobile-toc',
1116        className: 'kb-mobile-toc-list space-y-1',
1117        'aria-label': 'Table of contents'
1118      }].concat(_toConsumableArray(toc.map(function (item) {
1119        return React.createElement('a', {
1120          key: item.id,
1121          href: "#".concat(item.id),
1122          onClick: function onClick(e) {
1123            e.preventDefault();
1124            scrollToHeading(item.id, true);
1125          },
1126          className: "toc-item ".concat(activeId === item.id ? 'active' : '', " ").concat(item.level === 2 ? 'toc-lv2' : item.level === 3 ? 'toc-lv3' : item.level === 4 ? 'toc-lv4' : '')
1127        }, item.text);
1128      })))))), React.createElement('div', {
1129        className: 'min-h-[360px]'
1130      }, loading && React.createElement('div', {
1131        className: 'kb-docs-status'
1132      }, 'Loading document…'), !loading && error && React.createElement('div', {
1133        className: 'kb-docs-status kb-docs-status--error'
1134      }, error), !loading && !error && renderHTML && React.createElement(React.Fragment, null, React.createElement('div', {
1135        className: 'kb-card'
1136      }, React.createElement('article', {
1137        ref: contentRef,
1138        className: 'markdown-body max-w-none',
1139        dangerouslySetInnerHTML: {
1140          __html: renderHTML
1141        }
1142      })), pageCount > 1 && React.createElement('div', {
1143        className: 'kb-pager'
1144      }, React.createElement('button', {
1145        type: 'button',
1146        className: 'kb-pager-btn',
1147        onClick: function onClick() {
1148          return goToPage(pageIndex - 1);
1149        },
1150        disabled: pageIndex <= 0
1151      }, 'Previous Page'), React.createElement('div', {
1152        className: 'kb-pager-info'
1153      }, "Page ".concat(pageIndex + 1, " / ").concat(pageCount)), React.createElement('button', {
1154        type: 'button',
1155        className: 'kb-pager-btn',
1156        onClick: function onClick() {
1157          return goToPage(pageIndex + 1);
1158        },
1159        disabled: pageIndex >= pageCount - 1
1160      }
1160, 'Next Page'))))))), React.createElement('div', {
1161        className: 'reading-progress',
1162        style: {
1163          top: Math.max(0, topOffset - 24),
1164          width: "".concat(progress, "%")
1165        }
1166      })));
1167    }; // 挂到全局
1168    var DOC_PANELS = [{
1169      key: 'whitepaper',
1170      label: 'White Paper',
1171      fileBase: 'kolect_whitepaper'
1172    }];
1173    var DOCS_THEME_STORAGE_KEY = 'KOLECT.documents.theme.v2';
1174    window.DocumentsPage = DocumentsPage;
1175  } catch (e) {
1176    console.error('[DocumentsPage] bootstrap error:', e);
1177    window.DocumentsPage = function () {
1178      var React = window.React;
1179      return React.createElement('div', {
1180        className: 'p-4 text-red-400'
1181      }, 'DocumentsPage init error: ' + ((e === null || e === void 0 ? void 0 : e.message) || String(e)));
1182    };
1183  }
1184})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.