PageSourceSearch

https://factchecker.cloud/src/App.tsx?t=1790124554917

js factchecker.cloud collected 2026-09-24 14:36:21 UTC 45,879 bytes, 534 lines download raw bytes

1import { createHotContext as __vite__createHotContext } from "/@vite/client";import.meta.hot = __vite__createHotContext("/src/App.tsx");const lazy = __vite__cjsImport0_react["lazy"]; const Suspense = __vite__cjsImport0_react["Suspense"]; const useEffect = __vite__cjsImport0_react["useEffect"];const koKR = __vite__cjsImport3_antd_locale_ko_KR;const _jsxDEV = __vite__cjsImport12_react_jsxDevRuntime["jsxDEV"];import __vite__cjsImport0_react from "/node_modules/.vite/deps/react.js?v=3fbb631b";
2import { BrowserRouter, Routes, Route, Navigate } from "/node_modules/.vite/deps/react-router-dom.js?v=3fbb631b";
3import { ConfigProvider, Spin } from "/node_modules/.vite/deps/antd.js?v=3fbb631b";
4// Why: antd 의 Empty/Table/Pagination/DatePicker 등은 default 가 영어 ("No data", "Page",
5// "Select date"...). ConfigProvider locale 로 일괄 한국어화 — 개별 컴포넌트에 description
6// prop 을 명시하지 않아도 자동 적용.
7import __vite__cjsImport3_antd_locale_ko_KR from "/node_modules/.vite/deps/antd_locale_ko___KR.js?v=ed14b234";
8import { useAuthStore } from "/src/store/authStore.ts";
9import { useChatStore } from "/src/store/chatStore.ts";
10import { useDocumentStore } from "/src/store/documentStore.ts";
11import { STORAGE_KEYS } from "/src/constants.ts";
12import { colors, fonts, radius } from "/src/theme/tokens.ts";
13import ErrorBoundary from "/src/components/Common/ErrorBoundary.tsx";
14import MainLayout from "/src/components/Layout/MainLayout.tsx";
15import ProtectedRoute from "/src/components/Common/ProtectedRoute.tsx";
16var _jsxFileName = "/home/bang/datatek_rag/frontend/src/App.tsx";
17import __vite__cjsImport12_react_jsxDevRuntime from "/node_modules/.vite/deps/react_jsx-dev-runtime.js?v=3fbb631b";
18var _s = $RefreshSig$();
19const Login = lazy(_c = () => import("/src/pages/Login.tsx"));
20_c2 = Login;
21const Register = lazy(_c3 = () => import("/src/pages/Register.tsx"));
22_c4 = Register;
23const Chat = lazy(_c5 = () => import("/src/pages/Chat.tsx?t=1790124554917"));
24_c6 = Chat;
25const Documents = lazy(_c7 = () => import("/src/pages/Documents.tsx"));
26_c8 = Documents;
27const Categories = lazy(_c9 = () => import("/src/pages/Categories.tsx"));
28_c10 = Categories;
29const Admin = lazy(_c11 = () => import("/src/pages/Admin.tsx"));
30_c12 = Admin;
31const Board = lazy(_c13 = () => import("/src/pages/Board.tsx"));
32_c14 = Board;
33const BoardPost = lazy(_c15 = () => import("/src/pages/BoardPost.tsx"));
34_c16 = BoardPost;
35const BoardEditor = lazy(_c17 = () => import("/src/pages/BoardEditor.tsx"));
36_c18 = BoardEditor;
37const Settings = lazy(_c19 = () => import("/src/pages/Settings.tsx"));
38_c20 = Settings;
39const ProfileSettings = lazy(_c21 = () => import("/src/pages/settings/ProfileSettings.tsx"));
40_c22 = ProfileSettings;
41const SecuritySettings = lazy(_c23 = () => import("/src/pages/settings/SecuritySettings.tsx"));
42_c24 = SecuritySettings;
43const MemorySettings = lazy(_c25 = () => import("/src/pages/settings/MemorySettings.tsx"));
44_c26 = MemorySettings;
45function App() {
46	_s();
47	// Why: 이전엔 useAuthStore() 전체 구독으로 token/user/error 모든 변화가 App 을 재렌더해
48	// ConfigProvider/BrowserRouter/Suspense 가 재평가되며 라우트 트리 전체가 reconcile.
49	// action 함수만 stable 하게 select.
50	const loadUserFromStorage = useAuthStore((s) => s.loadUserFromStorage);
51	// Load user from localStorage on app mount
52	useEffect(() => {
53		loadUserFromStorage();
54	}, [loadUserFromStorage]);
55	// 다른 탭에서 로그아웃 / 로그인하면 localStorage 의 TOKEN / USER 키가 바뀐다.
56	// 이 탭도 동기화하지 않으면 "한 탭에서 로그아웃 → 다른 탭은 여전히 인증됨" 이 되어
57	// 보안상 바람직하지 않고 UX 도 어긋난다. storage 이벤트를 듣고 상태를 재적재.
58	useEffect(() => {
59		const onStorageChange = (e) => {
60			if (e.key === null) {
61				// storage.clear() 호출 — 전체 리셋
62				loadUserFromStorage();
63				return;
64			}
65			// Why: 다른 탭이
66			// RAG selection (SELECTED_DOCUMENTS / SELECTED_CATEGORIES / SELECTED_EXCLUDED_
67			// DOCUMENTS) 또는 5 tool toggle (web_search / code_execution / memory /
68			// review / mcp) 또는 admin policy cache 를 변경하면, 이 탭의 in-memory state
69			// 가 stale 한 채로 다음 chat send 에서 wrong-scope citation 또는 silently
70			// 부활한 web_search 같은 cross-tab leak 가능. CRITICAL — Tab A 가 webSearch
71			// OFF 했는데 Tab B 가 다른 토글 변경 시 5 키 일괄 setItem 으로 OFF revival.
72			// storage event 의 inbound sync 로 in-memory 와 storage 일관성 보존.
73			const _RAG_SELECTION_KEYS = new Set([
74				STORAGE_KEYS.SELECTED_DOCUMENTS,
75				STORAGE_KEYS.SELECTED_CATEGORIES,
76				STORAGE_KEYS.SELECTED_EXCLUDED_DOCUMENTS
77			]);
78			if (e.key && _RAG_SELECTION_KEYS.has(e.key)) {
79				// RAG selection 의 cross-tab 갱신 — documentStore 의 reset() 호출 후
80				// selection 만 init 시점처럼 storage 에서 재읽음. reset() 은 documents 와
81				// categories 캐시도 invalidate 해 다음 사이드바 렌더가 fresh fetch.
82				useDocumentStore.getState().reset?.();
83				return;
84			}
85			// Tool toggle (5 chat tool) 의 cross-tab sync 는 별도 사이클 — hooks state
86			// 가 외부 invalidate 가능한 zustand store 또는 Context 로 옮기는 design 필요
87			// (기존 useState + localStorage manual 패턴은 cross-tab 정확히 fix 어려움).
88			// 본 사이클은 RAG selection (가장 critical wrong-scope citation 시나리오) 만.
89			// Why: atomic AUTH_SESSION key 도
90			// 처리 — TOKEN/USER 비원자적 쓰기의 hybrid mismatch 차단. atomic key 의
91			// newValue=null 또는 다른 user.id 면 reset 동일 분기.
92			if (e.key === STORAGE_KEYS.AUTH_SESSION) {
93				const tokenCleared = !e.newValue;
94				let userIdentityChanged = false;
95				if (e.newValue) {
96					try {
97						const incoming = JSON.parse(e.newValue);
98						const incomingId = incoming?.user && typeof incoming.user.id === "string" ? incoming.user.id : null;
99						const currentId = useAuthStore.getState().user?.id ?? null;
100						if (incomingId && currentId && incomingId !== currentId) {
101							userIdentityChanged = true;
102						}
103					} catch {}
104				}
105				if (tokenCleared || userIdentityChanged) {
106					const chatState = useChatStore.getState();
107					if (chatState.isStreaming) chatState.cancelStreaming();
108					chatState.reset?.();
109					useDocumentStore.getState().reset?.();
110					void import("/src/api/admin.ts").then((mod) => {
111						try {
112							mod.invalidateRAGSettingsPublicCache();
113						} catch {}
114					});
115				}
116				loadUserFromStorage();
117				return;
118			}
119			if (e.key === STORAGE_KEYS.TOKEN || e.key === STORAGE_KEYS.USER) {
120				// Why: 다른 탭에서 로그아웃하면 TOKEN 키가 삭제된다. 이 탭이 진행 중인 SSE 스트림을
121				// 가지고 있으면, 토큰이 사라진 상태로 fetch 가 계속 청크를 받다가 401 → 토스트 노이즈
122				// 가 로그인 화면에 뜬다. 추가로 streamingMessage 가 unmount 된 Chat 트리에 계속
123				// mutate. 토큰 삭제 감지 시 chatStore 의 streaming 도 abort + reset.
124				const tokenCleared = e.key === STORAGE_KEYS.TOKEN && !e.newValue;
125				// Why: 사용자 A 가 Tab A 에 로그인된 상태에서, Tab B 가 logout 없이 곧바로 다른
126				// 계정 B 로 login 하면 localStorage 의 TOKEN/USER 키는 *삭제 없이 새 값으로 덮어쓰기*
127				// 된다. 이 경우 tokenCleared=false 라 chatStore/documentStore reset 이 건너뛰어, Tab A
128				// 의 in-memory 에는 여전히 user A 의 sessions / selectedDocumentIds 가 남아 있다.
129				// loadUserFromStorage 는 auth 만 user B 로 갱신하므로 헤더는 B, 사이드바는 A 의 세션이
130				// 보이고 클릭 시 403/404 + cross-user 데이터 노출. e.key === USER 일 때 새 newValue 의
131				// user.id 가 현재 in-memory user.id 와 다르면 동일한 reset 경로를 타게 한다.
132				let userIdentityChanged = false;
133				if (e.key === STORAGE_KEYS.USER && e.newValue) {
134					try {
135						const incoming = JSON.parse(e.newValue);
136						const incomingId = incoming && typeof incoming.id === "string" ? incoming.id : null;
137						const currentId = useAuthStore.getState().user?.id ?? null;
138						if (incomingId && currentId && incomingId !== currentId) {
139							userIdentityChanged = true;
140						}
141					} catch {}
142				}
143				if (tokenCleared || userIdentityChanged) {
144					const chatState = useChatStore.getState();
145					if (chatState.isStreaming) chatState.cancelStreaming();
146					chatState.reset?.();
147					// Why: Header.handleLogout 은 같은 탭에서 resetDocuments() 를 호출해 selectedDocumentIds /
148					// selectedCategoryIds / excludedDocumentIds 를 in-memory + localStorage 양쪽에서 비운다.
149					// 그러나 다른 탭에서 로그아웃했을 때 이 storage 핸들러는 chatStore 만 reset 하고
150					// documentStore 는 그대로 둬, 이 탭의 in-memory selection 이 살아남는다. 다른 사용자가
151					// 같은 브라우저로 이 탭에 로그인하면 이전 사용자의 RAG scope (선택 문서/카테고리/제외
152					// 문서) 가 silent 로 따라들어가 chat 답변이 의도치 않게 그 범위로 한정 + 프라이버시
153					// 누수. tokenCleared 시 documentStore.reset() 도 호출.
154					useDocumentStore.getState().reset?.();
155					// Why: same-
156					// tab logout 의 invalidateRAGSettingsPublicCache 호출
157					// 이 cross-tab 으로 전파 안 됨. Tab A logout → Tab B 의 storage event
158					// 까지는 chat/document store 만 reset 하고 admin policy 30s cache 는
159					// 잔존 → Tab B 에 다른 사용자가 같은 browser 로 login 시 이전 admin 의
160					// tool_*_allowed flags / LLM provider 가 stale UI 로 노출 (cross-user
161					// admin config leak). same-tab sibling drift 차단.
162					void import("/src/api/admin.ts").then((mod) => {
163						try {
164							mod.invalidateRAGSettingsPublicCache();
165						} catch {}
166					});
167				}
168				loadUserFromStorage();
169			}
170		};
171		window.addEventListener("storage", onStorageChange);
172		return () => window.removeEventListener("storage", onStorageChange);
173	}, [loadUserFromStorage]);
174	return /* @__PURE__ */ _jsxDEV(ErrorBoundary, { children: /* @__PURE__ */ _jsxDEV(ConfigProvider, {
175		locale: koKR,
176		theme: {
177			// Why: 모든 색/폰트/radius 값은 theme/tokens.ts 의 single source of truth 에서
178			// 가져옴. 이전엔 hex 가 여기 직접 박혀 있어 index.css :root 변수와 두 곳 동기화
179			// 필요 — 이제 tokens.ts 한 곳만 바꾸면 ConfigProvider 자동 갱신 (index.css 의
180			// :root 도 같은 hex 사용. tokens.ts 주석 참고).
181			token: {
182				colorPrimary: colors.brand,
183				colorLink: colors.brand,
184				colorLinkHover: colors.brandHover,
185				colorBgLayout: colors.surface,
186				colorBorder: colors.border,
187				colorBorderSecondary: colors.divider,
188				colorText: colors.text,
189				colorTextSecondary: colors.textSecondary,
190				colorTextTertiary: colors.textTertiary,
191				borderRadius: radius.base,
192				borderRadiusSM: radius.sm,
193				borderRadiusLG: radius.lg,
194				fontFamily: fonts.sans,
195				fontFamilyCode: fonts.mono,
196				fontSize: 14,
197				controlHeight: 36,
198				controlOutlineWidth: 3
199			},
200			components: {
201				Button: {
202					primaryShadow: "0 1px 0 rgba(15, 20, 25, 0.08)",
203					fontWeight: 500
204				},
205				Card: { headerFontSize: 15 },
206				Layout: {
207					headerBg: colors.card,
208					bodyBg: colors.surface,
209					siderBg: colors.card
210				},
211				Menu: {
212					itemSelectedBg: colors.brandSoft,
213					itemSelectedColor: colors.brand
214				}
215			}
216		},
217		children: /* @__PURE__ */ _jsxDEV(BrowserRouter, { children: /* @__PURE__ */ _jsxDEV(Suspense, {
218			fallback: /* @__PURE__ */ _jsxDEV("div", {
219				style: {
220					display: "flex",
221					justifyContent: "center",
222					alignItems: "center",
223					height: "100vh"
224				},
225				children: /* @__PURE__ */ _jsxDEV(Spin, { size: "large" }, void 0, false, {
226					fileName: _jsxFileName,
227					lineNumber: 216,
228					columnNumber: 127
229				}, this)
230			}, void 0, false, {
231				fileName: _jsxFileName,
232				lineNumber: 216,
233				columnNumber: 29
234			}, this),
235			children: /* @__PURE__ */ _jsxDEV(Routes, { children: [
236				/* @__PURE__ */ _jsxDEV(Route, {
237					path: "/login",
238					element: /* @__PURE__ */ _jsxDEV(Login, {}, void 0, false, {
239						fileName: _jsxFileName,
240						lineNumber: 219,
241						columnNumber: 41
242					}, this)
243				}, void 0, false, {
244					fileName: _jsxFileName,
245					lineNumber: 219,
246					columnNumber: 11
247				}, this),
248				/* @__PURE__ */ _jsxDEV(Route, {
249					path: "/register",
250					element: /* @__PURE__ */ _jsxDEV(Register, {}, void 0, false, {
251						fileName: _jsxFileName,
252						lineNumber: 220,
253						columnNumber: 44
254					}, this)
255				}, void 0, false, {
256					fileName: _jsxFileName,
257					lineNumber: 220,
258					columnNumber: 11
259				}, this),
260				/* @__PURE__ */ _jsxDEV(Route, {
261					path: "/",
262					element: /* @__PURE__ */ _jsxDEV(ProtectedRoute, { children: /* @__PURE__ */ _jsxDEV(MainLayout, {}, void 0, false, {
263						fileName: _jsxFileName,
264						lineNumber: 227,
265						columnNumber: 17
266					}, this) }, void 0, false, {
267						fileName: _jsxFileName,
268						lineNumber: 226,
269						columnNumber: 15
270					}, this),
271					children: [
272						/* @__PURE__ */ _jsxDEV(Route, {
273							index: true,
274							element: /* @__PURE__ */ _jsxDEV(Chat, {}, void 0, false, {
275								fileName: _jsxFileName,
276								lineNumber: 231,
277								columnNumber: 35
278							}, this)
279						}, void 0, false, {
280							fileName: _jsxFileName,
281							lineNumber: 231,
282							columnNumber: 13
283						}, this),
284						/* @__PURE__ */ _jsxDEV(Route, {
285							path: "documents",
286							element: /* @__PURE__ */ _jsxDEV(Documents, {}, void 0, false, {
287								fileName: _jsxFileName,
288								lineNumber: 235,
289								columnNumber: 46
290							}, this)
291						}, void 0, false, {
292							fileName: _jsxFileName,
293							lineNumber: 235,
294							columnNumber: 13
295						}, this),
296						/* @__PURE__ */ _jsxDEV(Route, {
297							path: "categories",
298							element: /* @__PURE__ */ _jsxDEV(Categories, {}, void 0, false, {
299								fileName: _jsxFileName,
300								lineNumber: 236,
301								columnNumber: 47
302							}, this)
303						}, void 0, false, {
304							fileName: _jsxFileName,
305							lineNumber: 236,
306							columnNumber: 13
307						}, this),
308						/* @__PURE__ */ _jsxDEV(Route, {
309							path: "board",
310							element: /* @__PURE__ */ _jsxDEV(Board, {}, void 0, false, {
311								fileName: _jsxFileName,
312								lineNumber: 239,
313								columnNumber: 42
314							}, this)
315						}, void 0, false, {
316							fileName: _jsxFileName,
317							lineNumber: 239,
318							columnNumber: 13
319						}, this),
320						/* @__PURE__ */ _jsxDEV(Route, {
321							path: "board/new",
322							element: /* @__PURE__ */ _jsxDEV(BoardEditor, {}, void 0, false, {
323								fileName: _jsxFileName,
324								lineNumber: 240,
325								columnNumber: 46
326							}, this)
327						}, void 0, false, {
328							fileName: _jsxFileName,
329							lineNumber: 240,
330							columnNumber: 13
331						}, this),
332						/* @__PURE__ */ _jsxDEV(Route, {
333							path: "board/:postId",
334							element: /* @__PURE__ */ _jsxDEV(BoardPost, {}, void 0, false, {
335								fileName: _jsxFileName,
336								lineNumber: 241,
337								columnNumber: 50
338							}, this)
339						}, void 0, false, {
340							fileName: _jsxFileName,
341							lineNumber: 241,
342							columnNumber: 13
343						}, this),
344						/* @__PURE__ */ _jsxDEV(Route, {
345							path: "board/:postId/edit",
346							element: /* @__PURE__ */ _jsxDEV(BoardEditor, {}, void 0, false, {
347								fileName: _jsxFileName,
348								lineNumber: 242,
349								columnNumber: 55
350							}, this)
351						}, void 0, false, {
352							fileName: _jsxFileName,
353							lineNumber: 242,
354							columnNumber: 13
355						}, this),
356						/* @__PURE__ */ _jsxDEV(Route, {
357							path: "admin",
358							element: /* @__PURE__ */ _jsxDEV(Admin, {}, void 0, false, {
359								fileName: _jsxFileName,
360								lineNumber: 243,
361								columnNumber: 42
362							}, this)
363						}, void 0, false, {
364							fileName: _jsxFileName,
365							lineNumber: 243,
366							columnNumber: 13
367						}, this),
368						/* @__PURE__ */ _jsxDEV(Route, {
369							path: "settings",
370							element: /* @__PURE__ */ _jsxDEV(Settings, {}, void 0, false, {
371								fileName: _jsxFileName,
372								lineNumber: 244,
373								columnNumber: 45
374							}, this),
375							children: [
376								/* @__PURE__ */ _jsxDEV(Route, {
377									index: true,
378									element: /* @__PURE__ */ _jsxDEV(Navigate, {
379										to: "profile",
380										replace: true
381									}, void 0, false, {
382										fileName: _jsxFileName,
383										lineNumber: 245,
384										columnNumber: 37
385									}, this)
386								}, void 0, false, {
387									fileName: _jsxFileName,
388									lineNumber: 245,
389									columnNumber: 15
390								}, this),
391								/* @__PURE__ */ _jsxDEV(Route, {
392									path: "profile",
393									element: /* @__PURE__ */ _jsxDEV(ProfileSettings, {}, void 0, false, {
394										fileName: _jsxFileName,
395										lineNumber: 246,
396										columnNumber: 46
397									}, this)
398								}, void 0, false, {
399									fileName: _jsxFileName,
400									lineNumber: 246,
401									columnNumber: 15
402								}, this),
403								/* @__PURE__ */ _jsxDEV(Route, {
404									path: "security",
405									element: /* @__PURE__ */ _jsxDEV(SecuritySettings, {}, void 0, false, {
406										fileName: _jsxFileName,
407										lineNumber: 247,
408										columnNumber: 47
409									}, this)
410								}, void 0, false, {
411									fileName: _jsxFileName,
412									lineNumber: 247,
413									columnNumber: 15
414								}, this),
415								/* @__PURE__ */ _jsxDEV(Route, {
416									path: "memory",
417									element: /* @__PURE__ */ _jsxDEV(MemorySettings, {}, void 0, false, {
418										fileName: _jsxFileName,
419										lineNumber: 248,
420										columnNumber: 45
421									}, this)
422								}, void 0, false, {
423									fileName: _jsxFileName,
424									lineNumber: 248,
425									columnNumber: 15
426								}, this)
427							]
428						}, void 0, true, {
429							fileName: _jsxFileName,
430							lineNumber: 244,
431							columnNumber: 13
432						}, this)
433					]
434				}, void 0, true, {
435					fileName: _jsxFileName,
436					lineNumber: 223,
437					columnNumber: 11
438				}, this),
439				/* @__PURE__ */ _jsxDEV(Route, {
440					path: "*",
441					element: /* @__PURE__ */ _jsxDEV(Navigate, {
442						to: "/",
443						replace: true
444					}, void 0, false, {
445						fileName: _jsxFileName,
446						lineNumber: 253,
447						columnNumber: 36
448					}, this)
449				}, void 0, false, {
450					fileName: _jsxFileName,
451					lineNumber: 253,
452					columnNumber: 11
453				}, this)
454			] }, void 0, true, {
455				fileName: _jsxFileName,
456				lineNumber: 217,
457				columnNumber: 9
458			}, this)
459		}, void 0, false, {
460			fileName: _jsxFileName,
461			lineNumber: 216,
462			columnNumber: 9
463		}, this) }, void 0, false, {
464			fileName: _jsxFileName,
465			lineNumber: 215,
466			columnNumber: 9
467		}, this)
468	}, void 0, false, {
469		fileName: _jsxFileName,
470		lineNumber: 169,
471		columnNumber: 7
472	}, this) }, void 0, false, {
473		fileName: _jsxFileName,
474		lineNumber: 168,
475		columnNumber: 5
476	}, this);
477}
478_s(App, "7N5BxKKpfR6rtuHVzJZsRGTv4qo=", false, function() {
479	return [useAuthStore];
480});
481_c27 = App;
482export default App;
483var _c, _c2, _c3, _c4, _c5, _c6, _c7, _c8, _c9, _c10, _c11, _c12, _c13, _c14, _c15, _c16, _c17, _c18, _c19, _c20, _c21, _c22, _c23, _c24, _c25, _c26, _c27;
484$RefreshReg$(_c, "Login$lazy");
485$RefreshReg$(_c2, "Login");
486$RefreshReg$(_c3, "Register$lazy");
487$RefreshReg$(_c4, "Register");
488$RefreshReg$(_c5, "Chat$lazy");
489$RefreshReg$(_c6, "Chat");
490$RefreshReg$(_c7, "Documents$lazy");
491$RefreshReg$(_c8, "Documents");
492$RefreshReg$(_c9, "Categories$lazy");
493$RefreshReg$(_c10, "Categories");
494$RefreshReg$(_c11, "Admin$lazy");
495$RefreshReg$(_c12, "Admin");
496$RefreshReg$(_c13, "Board$lazy");
497$RefreshReg$(_c14, "Board");
498$RefreshReg$(_c15, "BoardPost$lazy");
499$RefreshReg$(_c16, "BoardPost");
500$RefreshReg$(_c17, "BoardEditor$lazy");
501$RefreshReg$(_c18, "BoardEditor");
502$RefreshReg$(_c19, "Settings$lazy");
503$RefreshReg$(_c20, "Settings");
504$RefreshReg$(_c21, "ProfileSettings$lazy");
505$RefreshReg$(_c22, "ProfileSettings");
506$RefreshReg$(_c23, "SecuritySettings$lazy");
507$RefreshReg$(_c24, "SecuritySettings");
508$RefreshReg$(_c25, "MemorySettings$lazy");
509$RefreshReg$(_c26, "MemorySettings");
510$RefreshReg$(_c27, "App");
511import * as RefreshRuntime from "/@react-refresh";
512const inWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
513import * as __vite_react_currentExports from "/src/App.tsx?t=1790124554917";
514if (import.meta.hot && !inWebWorker) {
515  if (!window.$RefreshReg$) {
516    throw new Error(
517      "@vitejs/plugin-react can't detect preamble. Something is wrong."
518    );
519  }
520
521  const currentExports = __vite_react_currentExports;
522  queueMicrotask(() => {
523    RefreshRuntime.registerExportsForReactRefresh("/home/bang/datatek_rag/frontend/src/App.tsx", currentExports);
524    import.meta.hot.accept((nextExports) => {
525      if (!nextExports) return;
526      const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate("/home/bang/datatek_rag/frontend/src/App.tsx", currentExports, nextExports);
527      if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage);
528    });
529  });
530}
531function $RefreshReg$(type, id) { return RefreshRuntime.register(type, "/home/bang/datatek_rag/frontend/src/App.tsx" + ' ' + id); }
532function $RefreshSig$() { return RefreshRuntime.createSignatureFunctionForTransform(); }
533
534//# sourceMappingURL=data:application/json;base64,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xPQUFELENBQVE7Ozs7O01BQUk7Ozs7O01BQ3pDLHdCQUFDLE9BQUQ7T0FBTyxNQUFLO09BQVcsU0FBUyx3QkFBQyxVQUFELENBQVc7Ozs7O2lCQUEzQztRQUNFLHdCQUFDLE9BQUQ7U0FBTztTQUFNLFNBQVMsd0JBQUMsVUFBRDtVQUFVLElBQUc7VUFBVTtTQUFTOzs7OztRQUFJOzs7OztRQUMxRCx3QkFBQyxPQUFEO1NBQU8sTUFBSztTQUFVLFNBQVMsd0JBQUMsaUJBQUQsQ0FBa0I7Ozs7O1FBQUk7Ozs7O1FBQ3JELHdCQUFDLE9BQUQ7U0FBTyxNQUFLO1NBQVcsU0FBUyx3QkFBQyxrQkFBRCxDQUFtQjs7Ozs7UUFBSTs7Ozs7UUFDdkQsd0JBQUMsT0FBRDtTQUFPLE1BQUs7U0FBUyxTQUFTLHdCQUFDLGdCQUFELENBQWlCOzs7OztRQUFJOzs7OztPQUM5Qzs7Ozs7O0tBQ0Y7Ozs7OztJQUdQLHdCQUFDLE9BQUQ7S0FBTyxNQUFLO0tBQUksU0FBUyx3QkFBQyxVQUFEO01BQVUsSUFBRztNQUFJO0tBQVM7Ozs7O0lBQUk7Ozs7O0dBQy9DOzs7OztFQUNBOzs7O1dBQ0s7Ozs7O0NBQ0Q7Ozs7VUFDSDs7Ozs7QUFFbkI7Ozs7O0FBRUEsZUFBZSIsIm5hbWVzIjpbXSwic291cmNlcyI6WyJBcHAudHN4Il0sInZlcnNpb24iOjMsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGxhenksIFN1c3BlbnNlLCB1c2VFZmZlY3QgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBCcm93c2VyUm91dGVyLCBSb3V0ZXMsIFJvdXRlLCBOYXZpZ2F0ZSB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IHsgQ29uZmlnUHJvdmlkZXIsIFNwaW4gfSBmcm9tICdhbnRkJztcbi8vIFdoeTogYW50ZCDsnZggRW1wdHkvVGFibGUvUGFnaW5hdGlvbi9EYXRlUGlja2VyIOuTseydgCBkZWZhdWx0IOqwgCDsmIHslrQgKFwiTm8gZGF0YVwiLCBcIlBhZ2VcIixcbi8vIFwiU2VsZWN0IGRhdGVcIi4uLikuIENvbmZpZ1Byb3ZpZGVyIGxvY2FsZSDroZwg7J286rSEIO2VnOq1reyWtO2ZlCDigJQg6rCc67OEIOy7tO2PrOuEjO2KuOyXkCBkZXNjcmlwdGlvblxuLy8gcHJvcCDsnYQg66qF7Iuc7ZWY7KeAIOyViuyVhOuPhCDsnpDrj5kg7KCB7JqpLlxuaW1wb3J0IGtvS1IgZnJvbSAnYW50ZC9sb2NhbGUva29fS1InO1xuaW1wb3J0IHsgdXNlQXV0aFN0b3JlIH0gZnJvbSAnLi9zdG9yZS9hdXRoU3RvcmUnO1xuaW1wb3J0IHsgdXNlQ2hhdFN0b3JlIH0gZnJvbSAnLi9zdG9yZS9jaGF0U3RvcmUnO1xuaW1wb3J0IHsgdXNlRG9jdW1lbnRTdG9yZSB9IGZyb20gJy4vc3RvcmUvZG9jdW1lbnRTdG9yZSc7XG5pbXBvcnQgeyBTVE9SQUdFX0tFWVMgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBjb2xvcnMsIGZvbnRzLCByYWRpdXMgfSBmcm9tICcuL3RoZW1lL3Rva2Vucyc7XG5pbXBvcnQgRXJyb3JCb3VuZGFyeSBmcm9tICcuL2NvbXBvbmVudHMvQ29tbW9uL0Vycm9yQm91bmRhcnknO1xuaW1wb3J0IE1haW5MYXlvdXQgZnJvbSAnLi9jb21wb25lbnRzL0xheW91dC9NYWluTGF5b3V0JztcbmltcG9ydCBQcm90ZWN0ZWRSb3V0ZSBmcm9tICcuL2NvbXBvbmVudHMvQ29tbW9uL1Byb3RlY3RlZFJvdXRlJztcblxuY29uc3QgTG9naW4gPSBsYXp5KCgpID0+IGltcG9ydCgnLi9wYWdlcy9Mb2dpbicpKTtcbmNvbnN0IFJlZ2lzdGVyID0gbGF6eSgoKSA9PiBpbXBvcnQoJy4vcGFnZXMvUmVnaXN0ZXInKSk7XG5jb25zdCBDaGF0ID0gbGF6eSgoKSA9PiBpbXBvcnQoJy4vcGFnZXMvQ2hhdCcpKTtcbmNvbnN0IERvY3VtZW50cyA9IGxhenkoKCkgPT4gaW1wb3J0KCcuL3BhZ2VzL0RvY3VtZW50cycpKTtcbmNvbnN0IENhdGVnb3JpZXMgPSBsYXp5KCgpID0+IGltcG9ydCgnLi9wYWdlcy9DYXRlZ29yaWVzJykpO1xuY29uc3QgQWRtaW4gPSBsYXp5KCgpID0+IGltcG9ydCgnLi9wYWdlcy9BZG1pbicpKTtcbmNvbnN0IEJvYXJkID0gbGF6eSgoKSA9PiBpbXBvcnQoJy4vcGFnZXMvQm9hcmQnKSk7XG5jb25zdCBCb2FyZFBvc3QgPSBsYXp5KCgpID0+IGltcG9ydCgnLi9wYWdlcy9Cb2FyZFBvc3QnKSk7XG5jb25zdCBCb2FyZEVkaXRvciA9IGxhenkoKCkgPT4gaW1wb3J0KCcuL3BhZ2VzL0JvYXJkRWRpdG9yJykpO1xuY29uc3QgU2V0dGluZ3MgPSBsYXp5KCgpID0+IGltcG9ydCgnLi9wYWdlcy9TZXR0aW5ncycpKTtcbmNvbnN0IFByb2ZpbGVTZXR0aW5ncyA9IGxhenkoKCkgPT4gaW1wb3J0KCcuL3BhZ2VzL3NldHRpbmdzL1Byb2ZpbGVTZXR0aW5ncycpKTtcbmNvbnN0IFNlY3VyaXR5U2V0dGluZ3MgPSBsYXp5KCgpID0+IGltcG9ydCgnLi9wYWdlcy9zZXR0aW5ncy9TZWN1cml0eVNldHRpbmdzJykpO1xuY29uc3QgTWVtb3J5U2V0dGluZ3MgPSBsYXp5KCgpID0+IGltcG9ydCgnLi9wYWdlcy9zZXR0aW5ncy9NZW1vcnlTZXR0aW5ncycpKTtcblxuZnVuY3Rpb24gQXBwKCkge1xuICAvLyBXaHk6IOydtOyghOyXlCB1c2VBdXRoU3RvcmUoKSDsoITssrQg6rWs64+F7Jy866GcIHRva2VuL3VzZXIvZXJyb3Ig66qo65OgIOuzgO2ZlOqwgCBBcHAg7J2EIOyerOugjOuNlO2VtFxuICAvLyBDb25maWdQcm92aWRlci9Ccm93c2VyUm91dGVyL1N1c3BlbnNlIOqwgCDsnqztj4nqsIDrkJjrqbAg65287Jqw7Yq4IO2KuOumrCDsoITssrTqsIAgcmVjb25jaWxlLlxuICAvLyBhY3Rpb24g7ZWo7IiY66eMIHN0YWJsZSDtlZjqsowgc2VsZWN0LlxuICBjb25zdCBsb2FkVXNlckZyb21TdG9yYWdlID0gdXNlQXV0aFN0b3JlKChzKSA9PiBzLmxvYWRVc2VyRnJvbVN0b3JhZ2UpO1xuXG4gIC8vIExvYWQgdXNlciBmcm9tIGxvY2FsU3RvcmFnZSBvbiBhcHAgbW91bnRcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBsb2FkVXNlckZyb21TdG9yYWdlKCk7XG4gIH0sIFtsb2FkVXNlckZyb21TdG9yYWdlXSk7XG5cbiAgLy8g64uk66W4IO2DreyXkOyEnCDroZzqt7jslYTsm4MgLyDroZzqt7jsnbjtlZjrqbQgbG9jYWxTdG9yYWdlIOydmCBUT0tFTiAvIFVTRVIg7YKk6rCAIOuwlOuAkOuLpC5cbiAgLy8g7J20IO2DreuPhCDrj5nquLDtmZTtlZjsp4Ag7JWK7Jy866m0IFwi7ZWcIO2DreyXkOyEnCDroZzqt7jslYTsm4Mg4oaSIOuLpOuluCDtg63snYAg7Jes7KCE7Z6IIOyduOymneuQqFwiIOydtCDrkJjslrRcbiAgLy8g67O07JWI7IOBIOuwlOuejOynge2VmOyngCDslYrqs6AgVVgg64+EIOyWtOq4i+uCnOuLpC4gc3RvcmFnZSDsnbTrsqTtirjrpbwg65Oj6rOgIOyDge2DnOulvCDsnqzsoIHsnqwuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3Qgb25TdG9yYWdlQ2hhbmdlID0gKGU6IFN0b3JhZ2VFdmVudCkgPT4ge1xuICAgICAgaWYgKGUua2V5ID09PSBudWxsKSB7XG4gICAgICAgIC8vIHN0b3JhZ2UuY2xlYXIoKSDtmLjstpwg4oCUIOyghOyytCDrpqzshYtcbiAgICAgICAgbG9hZFVzZXJGcm9tU3RvcmFnZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyBXaHk6IOuLpOuluCDtg63snbRcbiAgICAgIC8vIFJBRyBzZWxlY3Rpb24gKFNFTEVDVEVEX0RPQ1VNRU5UUyAvIFNFTEVDVEVEX0NBVEVHT1JJRVMgLyBTRUxFQ1RFRF9FWENMVURFRF9cbiAgICAgIC8vIERPQ1VNRU5UUykg65iQ64qUIDUgdG9vbCB0b2dnbGUgKHdlYl9zZWFyY2ggLyBjb2RlX2V4ZWN1dGlvbiAvIG1lbW9yeSAvXG4gICAgICAvLyByZXZpZXcgLyBtY3ApIOuYkOuKlCBhZG1pbiBwb2xpY3kgY2FjaGUg66W8IOuzgOqyve2VmOuptCwg7J20IO2DreydmCBpbi1tZW1vcnkgc3Rh
534dGVcbiAgICAgIC8vIOqwgCBzdGFsZSDtlZwg7LGE66GcIOuLpOydjCBjaGF0IHNlbmQg7JeQ7IScIHdyb25nLXNjb3BlIGNpdGF0aW9uIOuYkOuKlCBzaWxlbnRseVxuICAgICAgLy8g67aA7Zmc7ZWcIHdlYl9zZWFyY2gg6rCZ7J2AIGNyb3NzLXRhYiBsZWFrIOqwgOuKpS4gQ1JJVElDQUwg4oCUIFRhYiBBIOqwgCB3ZWJTZWFyY2hcbiAgICAgIC8vIE9GRiDtlojripTrjbAgVGFiIEIg6rCAIOuLpOuluCDthqDquIAg67OA6rK9IOyLnCA1IO2CpCDsnbzqtIQgc2V0SXRlbSDsnLzroZwgT0ZGIHJldml2YWwuXG4gICAgICAvLyBzdG9yYWdlIGV2ZW50IOydmCBpbmJvdW5kIHN5bmMg66GcIGluLW1lbW9yeSDsmYAgc3RvcmFnZSDsnbzqtIDshLEg67O07KG0LlxuICAgICAgY29uc3QgX1JBR19TRUxFQ1RJT05fS0VZUyA9IG5ldyBTZXQ8c3RyaW5nPihbXG4gICAgICAgIFNUT1JBR0VfS0VZUy5TRUxFQ1RFRF9ET0NVTUVOVFMsXG4gICAgICAgIFNUT1JBR0VfS0VZUy5TRUxFQ1RFRF9DQVRFR09SSUVTLFxuICAgICAgICBTVE9SQUdFX0tFWVMuU0VMRUNURURfRVhDTFVERURfRE9DVU1FTlRTLFxuICAgICAgXSk7XG4gICAgICBpZiAoZS5rZXkgJiYgX1JBR19TRUxFQ1RJT05fS0VZUy5oYXMoZS5rZXkpKSB7XG4gICAgICAgIC8vIFJBRyBzZWxlY3Rpb24g7J2YIGNyb3NzLXRhYiDqsLHsi6Ag4oCUIGRvY3VtZW50U3RvcmUg7J2YIHJlc2V0KCkg7Zi47LacIO2bhFxuICAgICAgICAvLyBzZWxlY3Rpb24g66eMIGluaXQg7Iuc7KCQ7LKY65+8IHN0b3JhZ2Ug7JeQ7IScIOyerOydveydjC4gcmVzZXQoKSDsnYAgZG9jdW1lbnRzIOyZgFxuICAgICAgICAvLyBjYXRlZ29yaWVzIOy6kOyLnOuPhCBpbnZhbGlkYXRlIO2VtCDri6TsnYwg7IKs7J2065Oc67CUIOugjOuNlOqwgCBmcmVzaCBmZXRjaC5cbiAgICAgICAgdXNlRG9jdW1lbnRTdG9yZS5nZXRTdGF0ZSgpLnJlc2V0Py4oKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gVG9vbCB0b2dnbGUgKDUgY2hhdCB0b29sKSDsnZggY3Jvc3MtdGFiIHN5bmMg64qUIOuzhOuPhCDsgqzsnbTtgbQg4oCUIGhvb2tzIHN0YXRlXG4gICAgICAvLyDqsIAg7Jm467aAIGludmFsaWRhdGUg6rCA64ql7ZWcIHp1c3RhbmQgc3RvcmUg65iQ64qUIENvbnRleHQg66GcIOyYruq4sOuKlCBkZXNpZ24g7ZWE7JqUXG4gICAgICAvLyAo6riw7KG0IHVzZVN0YXRlICsgbG9jYWxTdG9yYWdlIG1hbnVhbCDtjKjthLTsnYAgY3Jvc3MtdGFiIOygle2Zle2eiCBmaXgg7Ja066Ck7JuAKS5cbiAgICAgIC8vIOuzuCDsgqzsnbTtgbTsnYAgUkFHIHNlbGVjdGlvbiAo6rCA7J6lIGNyaXRpY2FsIHdyb25nLXNjb3BlIGNpdGF0aW9uIOyLnOuCmOumrOyYpCkg66eMLlxuICAgICAgLy8gV2h5OiBhdG9taWMgQVVUSF9TRVNTSU9OIGtleSDrj4RcbiAgICAgIC8vIOyymOumrCDigJQgVE9LRU4vVVNFUiDruYTsm5DsnpDsoIEg7JOw6riw7J2YIGh5YnJpZCBtaXNtYXRjaCDssKjri6guIGF0b21pYyBrZXkg7J2YXG4gICAgICAvLyBuZXdWYWx1ZT1udWxsIOuYkOuKlCDri6TrpbggdXNlci5pZCDrqbQgcmVzZXQg64+Z7J28IOu2hOq4sC5cbiAgICAgIGlmIChlLmtleSA9PT0gU1RPUkFHRV9LRVlTLkFVVEhfU0VTU0lPTikge1xuICAgICAgICBjb25zdCB0b2tlbkNsZWFyZWQgPSAhZS5uZXdWYWx1ZTtcbiAgICAgICAgbGV0IHVzZXJJZGVudGl0eUNoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKGUubmV3VmFsdWUpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgaW5jb21pbmcgPSBKU09OLnBhcnNlKGUubmV3VmFsdWUpIGFzIHsgdXNlcj86IHsgaWQ/OiB1bmtub3duIH0gfSB8IG51bGw7XG4gICAgICAgICAgICBjb25zdCBpbmNvbWluZ0lkID0gaW5jb21pbmc/LnVzZXIgJiYgdHlwZW9mIGluY29taW5nLnVzZXIuaWQgPT09ICdzdHJpbmcnXG4gICAgICAgICAgICAgID8gaW5jb21pbmcudXNlci5pZCA6IG51bGw7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50SWQgPSB1c2VBdXRoU3RvcmUuZ2V0U3RhdGUoKS51c2VyPy5pZCA/PyBudWxsO1xuICAgICAgICAgICAgaWYgKGluY29taW5nSWQgJiYgY3VycmVudElkICYmIGluY29taW5nSWQgIT09IGN1cnJlbnRJZCkge1xuICAgICAgICAgICAgICB1c2VySWRlbnRpdHlDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIHBhcnNlIOyLpO2MqCDrrLTsi5wg4oCUIGxvYWRVc2VyRnJvbVN0b3JhZ2Ug6rCAIOyViOyghCDsspjrpqwuXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0b2tlbkNsZWFyZWQgfHwgdXNlcklkZW50aXR5Q2hhbmdlZCkge1xuICAgICAgICAgIGNvbnN0IGNoYXRTdGF0ZSA9IHVzZUNoYXRTdG9yZS5nZXRTdGF0ZSgpO1xuICAgICAgICAgIGlmIChjaGF0U3RhdGUuaXNTdHJlYW1pbmcpIGNoYXRTdGF0ZS5jYW5jZWxTdHJlYW1pbmcoKTtcbiAgICAgICAgICBjaGF0U3RhdGUucmVzZXQ/LigpO1xuICAgICAgICAgIHVzZURvY3VtZW50U3RvcmUuZ2V0U3RhdGUoKS5yZXNldD8uKCk7XG4gICAgICAgICAgdm9pZCBpbXBvcnQoJy4vYXBpL2FkbWluJykudGhlbigobW9kKSA9PiB7XG4gICAgICAgICAgICB0cnkgeyBtb2QuaW52YWxpZGF0ZVJBR1NldHRpbmdzUHVibGljQ2FjaGUoKTsgfSBjYXRjaCB7IC8qIGJlc3QtZWZmb3J0OiDsupDsi5wg66y07Zqo7ZmUIOyLpO2MqOuKlCDrrLTsi5wgKi8gfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGxvYWRVc2VyRnJvbVN0b3JhZ2UoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGUua2V5ID09PSBTVE9SQUdFX0tFWVMuVE9LRU4gfHwgZS5rZXkgPT09IFNUT1JBR0VfS0VZUy5VU0VSKSB7XG4gICAgICAgIC8vIFdoeTog64uk66W4IO2DreyXkOyEnCDroZzqt7jslYTsm4PtlZjrqbQgVE9LRU4g7YKk6rCAIOyCreygnOuQnOuLpC4g7J20IO2DreydtCDsp4Ttlokg7KSR7J24IFNTRSDsiqTtirjrprzsnYRcbiAgICAgICAgLy8g6rCA7KeA6rOgIOyeiOycvOuptCwg7Yag7YGw7J20IOyCrOudvOynhCDsg4Htg5zroZwgZmV0Y2gg6rCAIOqzhOyGjSDssq3tgazrpbwg67Cb64uk6rCAIDQwMSDihpIg7Yag7Iqk7Yq4IOuFuOydtOymiFxuICAgICAgICAvLyDqsIAg66Gc6re47J24IO2ZlOuptOyXkCDrnKzri6QuIOy2lOqwgOuhnCBzdHJlYW1pbmdNZXNzYWdlIOqwgCB1bm1vdW50IOuQnCBDaGF0IO2KuOumrOyXkCDqs4Tsho1cbiAgICAgICAgLy8gbXV0YXRlLiDthqDtgbAg7IKt7KCcIOqwkOyngCDsi5wgY2hhdFN0b3JlIOydmC
534BzdHJlYW1pbmcg64+EIGFib3J0ICsgcmVzZXQuXG4gICAgICAgIGNvbnN0IHRva2VuQ2xlYXJlZCA9IGUua2V5ID09PSBTVE9SQUdFX0tFWVMuVE9LRU4gJiYgIWUubmV3VmFsdWU7XG4gICAgICAgIC8vIFdoeTog7IKs7Jqp7J6QIEEg6rCAIFRhYiBBIOyXkCDroZzqt7jsnbjrkJwg7IOB7YOc7JeQ7IScLCBUYWIgQiDqsIAgbG9nb3V0IOyXhuydtCDqs6frsJTroZwg64uk66W4XG4gICAgICAgIC8vIOqzhOyglSBCIOuhnCBsb2dpbiDtlZjrqbQgbG9jYWxTdG9yYWdlIOydmCBUT0tFTi9VU0VSIO2CpOuKlCAq7IKt7KCcIOyXhuydtCDsg4gg6rCS7Jy866GcIOuNruyWtOyTsOq4sCpcbiAgICAgICAgLy8g65Cc64ukLiDsnbQg6rK97JqwIHRva2VuQ2xlYXJlZD1mYWxzZSDrnbwgY2hhdFN0b3JlL2RvY3VtZW50U3RvcmUgcmVzZXQg7J20IOqxtOuEiOubsOyWtCwgVGFiIEFcbiAgICAgICAgLy8g7J2YIGluLW1lbW9yeSDsl5DripQg7Jes7KCE7Z6IIHVzZXIgQSDsnZggc2Vzc2lvbnMgLyBzZWxlY3RlZERvY3VtZW50SWRzIOqwgCDrgqjslYQg7J6I64ukLlxuICAgICAgICAvLyBsb2FkVXNlckZyb21TdG9yYWdlIOuKlCBhdXRoIOunjCB1c2VyIEIg66GcIOqwseyLoO2VmOuvgOuhnCDtl6TrjZTripQgQiwg7IKs7J2065Oc67CU64qUIEEg7J2YIOyEuOyFmOydtFxuICAgICAgICAvLyDrs7TsnbTqs6Ag7YG066atIOyLnCA0MDMvNDA0ICsgY3Jvc3MtdXNlciDrjbDsnbTthLAg64W47LacLiBlLmtleSA9PT0gVVNFUiDsnbwg65WMIOyDiCBuZXdWYWx1ZSDsnZhcbiAgICAgICAgLy8gdXNlci5pZCDqsIAg7ZiE7J6sIGluLW1lbW9yeSB1c2VyLmlkIOyZgCDri6TrpbTrqbQg64+Z7J287ZWcIHJlc2V0IOqyveuhnOulvCDtg4Dqsowg7ZWc64ukLlxuICAgICAgICBsZXQgdXNlcklkZW50aXR5Q2hhbmdlZCA9IGZhbHNlO1xuICAgICAgICBpZiAoZS5rZXkgPT09IFNUT1JBR0VfS0VZUy5VU0VSICYmIGUubmV3VmFsdWUpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgaW5jb21pbmcgPSBKU09OLnBhcnNlKGUubmV3VmFsdWUpIGFzIHsgaWQ/OiB1bmtub3duIH0gfCBudWxsO1xuICAgICAgICAgICAgY29uc3QgaW5jb21pbmdJZCA9IGluY29taW5nICYmIHR5cGVvZiBpbmNvbWluZy5pZCA9PT0gJ3N0cmluZycgPyBpbmNvbWluZy5pZCA6IG51bGw7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50SWQgPSB1c2VBdXRoU3RvcmUuZ2V0U3RhdGUoKS51c2VyPy5pZCA/PyBudWxsO1xuICAgICAgICAgICAgaWYgKGluY29taW5nSWQgJiYgY3VycmVudElkICYmIGluY29taW5nSWQgIT09IGN1cnJlbnRJZCkge1xuICAgICAgICAgICAgICB1c2VySWRlbnRpdHlDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIO2MjOyLsSDsi6TtjKjripQg66y07IucIOKAlCBsb2FkVXNlckZyb21TdG9yYWdlIOqwgCDslYTrnpjsl5DshJwg7JWI7KCE7ZWY6rKMIOyymOumrC5cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRva2VuQ2xlYXJlZCB8fCB1c2VySWRlbnRpdHlDaGFuZ2VkKSB7XG4gICAgICAgICAgY29uc3QgY2hhdFN0YXRlID0gdXNlQ2hhdFN0b3JlLmdldFN0YXRlKCk7XG4gICAgICAgICAgaWYgKGNoYXRTdGF0ZS5pc1N0cmVhbWluZykgY2hhdFN0YXRlLmNhbmNlbFN0cmVhbWluZygpO1xuICAgICAgICAgIGNoYXRTdGF0ZS5yZXNldD8uKCk7XG4gICAgICAgICAgLy8gV2h5OiBIZWFkZXIuaGFuZGxlTG9nb3V0IOydgCDqsJnsnYAg7YOt7JeQ7IScIHJlc2V0RG9jdW1lbnRzKCkg66W8IO2YuOy2nO2VtCBzZWxlY3RlZERvY3VtZW50SWRzIC9cbiAgICAgICAgICAvLyBzZWxlY3RlZENhdGVnb3J5SWRzIC8gZXhjbHVkZWREb2N1bWVudElkcyDrpbwgaW4tbWVtb3J5ICsgbG9jYWxTdG9yYWdlIOyWkeyqveyXkOyEnCDruYTsmrTri6QuXG4gICAgICAgICAgLy8g6re465+s64KYIOuLpOuluCDtg63sl5DshJwg66Gc6re47JWE7JuD7ZaI7J2EIOuVjCDsnbQgc3RvcmFnZSDtlbjrk6Trn6zripQgY2hhdFN0b3JlIOunjCByZXNldCDtlZjqs6BcbiAgICAgICAgICAvLyBkb2N1bWVudFN0b3JlIOuKlCDqt7jrjIDroZwg65GsLCDsnbQg7YOt7J2YIGluLW1lbW9yeSBzZWxlY3Rpb24g7J20IOyCtOyVhOuCqOuKlOuLpC4g64uk66W4IOyCrOyaqeyekOqwgFxuICAgICAgICAgIC8vIOqwmeydgCDruIzrnbzsmrDsoIDroZwg7J20IO2DreyXkCDroZzqt7jsnbjtlZjrqbQg7J207KCEIOyCrOyaqeyekOydmCBSQUcgc2NvcGUgKOyEoO2DnSDrrLjshJwv7Lm07YWM6rOg66asL+ygnOyZuFxuICAgICAgICAgIC8vIOusuOyEnCkg6rCAIHNpbGVudCDroZwg65Sw652865Ok7Ja06rCAIGNoYXQg64u167OA7J20IOydmOuPhOy5mCDslYrqsowg6re4IOuylOychOuhnCDtlZzsoJUgKyDtlITrnbzsnbTrsoTsi5xcbiAgICAgICAgICAvLyDriITsiJguIHRva2VuQ2xlYXJlZCDsi5wgZG9jdW1lbnRTdG9yZS5yZXNldCgpIOuPhCDtmLjstpwuXG4gICAgICAgICAgdXNlRG9jdW1lbnRTdG9yZS5nZXRTdGF0ZSgpLnJlc2V0Py4oKTtcbiAgICAgICAgICAvLyBXaHk6IHNhbWUtXG4gICAgICAgICAgLy8gdGFiIGxvZ291dCDsnZggaW52YWxpZGF0ZVJBR1NldHRpbmdzUHVibGljQ2FjaGUg7Zi47LacXG4gICAgICAgICAgLy8g7J20IGNyb3NzLXRhYiDsnLzroZwg7KCE7YyMIOyViCDrkKguIFRhYiBBIGxvZ291dCDihpIgVGFiIEIg7J2YIHN0b3JhZ2UgZXZlbnRcbiAgICAgICAgICAvLyDquYzsp4DripQgY2hhdC9kb2N1bWVudCBzdG9yZSDrp4wgcmVzZXQg7ZWY6rOgIGFkbWluIHBvbGljeSAzMHMgY2FjaGUg64qUXG4gICAgICAgICAgLy8g7J6U7KG0IOKGkiBUYWIgQiDsl5Ag64uk66W4IOyCrOyaqeyekOqwgCDqsJnsnYAgYnJvd3NlciDroZwgbG9naW4g7IucIOydtOyghCBhZG1pbiDsnZhcbiAgICAgICAgICAvLyB0b29sXypfYWxsb3dlZCBmbGFncyAvIExMTSBwcm92aWRlciDqsIAgc3RhbGUgVUkg66GcIOuFuOy2nCAoY3Jvc3MtdXNlclxuICAgICAgICAgIC8vIGFkbWluIGNvbmZpZyBsZWFrKS4gc2FtZS10YWIgc2libGluZyBkcmlmdCDssKjri6guXG4gICAgICAgICAgdm9pZCBpbXBvcnQoJy4vYXBpL2FkbWluJykudGhlbigobW9kKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBtb2QuaW52YWxpZGF0ZVJBR1NldHRpbmdzUHVibGljQ2FjaGUoKTtcbiAgICAgICAgICAgI
534H0gY2F0Y2gge1xuICAgICAgICAgICAgICAvLyBiZXN0LWVmZm9ydCDigJQgYWRtaW4gbW9kdWxlIOuvuOuhnOuTnCDtmZjqsr0gKGxvZ2luIO2ZlOuptCkg64+EIGdyYWNlZnVsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgbG9hZFVzZXJGcm9tU3RvcmFnZSgpO1xuICAgICAgfVxuICAgIH07XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3N0b3JhZ2UnLCBvblN0b3JhZ2VDaGFuZ2UpO1xuICAgIHJldHVybiAoKSA9PiB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RvcmFnZScsIG9uU3RvcmFnZUNoYW5nZSk7XG4gIH0sIFtsb2FkVXNlckZyb21TdG9yYWdlXSk7XG5cbiAgcmV0dXJuIChcbiAgICA8RXJyb3JCb3VuZGFyeT5cbiAgICAgIDxDb25maWdQcm92aWRlclxuICAgICAgICBsb2NhbGU9e2tvS1J9XG4gICAgICAgIHRoZW1lPXt7XG4gICAgICAgICAgLy8gV2h5OiDrqqjrk6Ag7IOJL+2PsO2KuC9yYWRpdXMg6rCS7J2AIHRoZW1lL3Rva2Vucy50cyDsnZggc2luZ2xlIHNvdXJjZSBvZiB0cnV0aCDsl5DshJxcbiAgICAgICAgICAvLyDqsIDsoLjsmLQuIOydtOyghOyXlCBoZXgg6rCAIOyXrOq4sCDsp4HsoJEg67CV7ZiAIOyeiOyWtCBpbmRleC5jc3MgOnJvb3Qg67OA7IiY7JmAIOuRkCDqs7Mg64+Z6riw7ZmUXG4gICAgICAgICAgLy8g7ZWE7JqUIOKAlCDsnbTsoJwgdG9rZW5zLnRzIO2VnCDqs7Prp4wg67CU6r6466m0IENvbmZpZ1Byb3ZpZGVyIOyekOuPmSDqsLHsi6AgKGluZGV4LmNzcyDsnZhcbiAgICAgICAgICAvLyA6cm9vdCDrj4Qg6rCZ7J2AIGhleCDsgqzsmqkuIHRva2Vucy50cyDso7zshJ0g7LC46rOgKS5cbiAgICAgICAgICB0b2tlbjoge1xuICAgICAgICAgICAgY29sb3JQcmltYXJ5OiBjb2xvcnMuYnJhbmQsXG4gICAgICAgICAgICBjb2xvckxpbms6IGNvbG9ycy5icmFuZCxcbiAgICAgICAgICAgIGNvbG9yTGlua0hvdmVyOiBjb2xvcnMuYnJhbmRIb3ZlcixcbiAgICAgICAgICAgIGNvbG9yQmdMYXlvdXQ6IGNvbG9ycy5zdXJmYWNlLFxuICAgICAgICAgICAgY29sb3JCb3JkZXI6IGNvbG9ycy5ib3JkZXIsXG4gICAgICAgICAgICBjb2xvckJvcmRlclNlY29uZGFyeTogY29sb3JzLmRpdmlkZXIsXG4gICAgICAgICAgICBjb2xvclRleHQ6IGNvbG9ycy50ZXh0LFxuICAgICAgICAgICAgY29sb3JUZXh0U2Vjb25kYXJ5OiBjb2xvcnMudGV4dFNlY29uZGFyeSxcbiAgICAgICAgICAgIGNvbG9yVGV4dFRlcnRpYXJ5OiBjb2xvcnMudGV4dFRlcnRpYXJ5LFxuICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiByYWRpdXMuYmFzZSxcbiAgICAgICAgICAgIGJvcmRlclJhZGl1c1NNOiByYWRpdXMuc20sXG4gICAgICAgICAgICBib3JkZXJSYWRpdXNMRzogcmFkaXVzLmxnLFxuICAgICAgICAgICAgZm9udEZhbWlseTogZm9udHMuc2FucyxcbiAgICAgICAgICAgIGZvbnRGYW1pbHlDb2RlOiBmb250cy5tb25vLFxuICAgICAgICAgICAgZm9udFNpemU6IDE0LFxuICAgICAgICAgICAgY29udHJvbEhlaWdodDogMzYsXG4gICAgICAgICAgICBjb250cm9sT3V0bGluZVdpZHRoOiAzLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgY29tcG9uZW50czoge1xuICAgICAgICAgICAgQnV0dG9uOiB7XG4gICAgICAgICAgICAgIHByaW1hcnlTaGFkb3c6ICcwIDFweCAwIHJnYmEoMTUsIDIwLCAyNSwgMC4wOCknLFxuICAgICAgICAgICAgICBmb250V2VpZ2h0OiA1MDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgQ2FyZDoge1xuICAgICAgICAgICAgICBoZWFkZXJGb250U2l6ZTogMTUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgTGF5b3V0OiB7XG4gICAgICAgICAgICAgIGhlYWRlckJnOiBjb2xvcnMuY2FyZCxcbiAgICAgICAgICAgICAgYm9keUJnOiBjb2xvcnMuc3VyZmFjZSxcbiAgICAgICAgICAgICAgc2lkZXJCZzogY29sb3JzLmNhcmQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgTWVudToge1xuICAgICAgICAgICAgICBpdGVtU2VsZWN0ZWRCZzogY29sb3JzLmJyYW5kU29mdCxcbiAgICAgICAgICAgICAgaXRlbVNlbGVjdGVkQ29sb3I6IGNvbG9ycy5icmFuZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfX1cbiAgICAgID5cbiAgICAgICAgPEJyb3dzZXJSb3V0ZXI+XG4gICAgICAgIDxTdXNwZW5zZSBmYWxsYmFjaz17PGRpdiBzdHlsZT17eyBkaXNwbGF5OiAnZmxleCcsIGp1c3RpZnlDb250ZW50OiAnY2VudGVyJywgYWxpZ25JdGVtczogJ2NlbnRlcicsIGhlaWdodDogJzEwMHZoJyB9fT48U3BpbiBzaXplPVwibGFyZ2VcIiAvPjwvZGl2Pn0+XG4gICAgICAgIDxSb3V0ZXM+XG4gICAgICAgICAgey8qIFB1YmxpYyByb3V0ZXMgKi99XG4gICAgICAgICAgPFJvdXRlIHBhdGg9XCIvbG9naW5cIiBlbGVtZW50PXs8TG9naW4gLz59IC8+XG4gICAgICAgICAgPFJvdXRlIHBhdGg9XCIvcmVnaXN0ZXJcIiBlbGVtZW50PXs8UmVnaXN0ZXIgLz59IC8+XG5cbiAgICAgICAgICB7LyogUHJvdGVjdGVkIHJvdXRlcyAqL31cbiAgICAgICAgICA8Um91dGVcbiAgICAgICAgICAgIHBhdGg9XCIvXCJcbiAgICAgICAgICAgIGVsZW1lbnQ9e1xuICAgICAgICAgICAgICA8UHJvdGVjdGVkUm91dGU+XG4gICAgICAgICAgICAgICAgPE1haW5MYXlvdXQgLz5cbiAgICAgICAgICAgICAgPC9Qcm90ZWN0ZWRSb3V0ZT5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA+XG4gICAgICAgICAgICA8Um91dGUgaW5kZXggZWxlbWVudD17PENoYXQgLz59IC8+XG4gICAgICAgICAgICB7LyogV2h5OiDsnbTsoITsl5QgYC9jaGF0YCDqsr3roZzrj4Qg67OE64+E66GcIOygleydmOuQkOuKlOuNsCDslrTrlJTshJzrj4QgbmF2aWdhdGUg7JWIIO2VqChncmVwIDDqsbQpLFxuICAgICAgICAgICAgICAgIGluZGV4IHJvdXRlIOqwgCDsnbTrr7gg6rCZ7J2AIENoYXQg7J2EIOugjOuNlO2VmOqzoCBjYXRjaC1hbGwg7J20IGAqYCDihpIgYC9gIOuhnCByZWRpcmVjdCDtlZjrr4DroZxcbiAgICAgICAgICAgICAgICDsmYTsoITtlZwgZGVhZCByb3V0ZS4g7KCc6rGw7ZW0IO2RnOuptCDstpXshowuICovfVxuICAgICAgICAgICAgPFJvdXRlIHBhdGg9XCJkb2N1bWVudHNcIiBlbGVtZW50PXs8RG9jdW1lbnRzIC8+fSAvPlxuICAgICAgICAgICAgPFJvdXRlIHBhdGg9XCJjYXRlZ29yaWVzXCIgZWxlbWVudD17PENhdGVnb3JpZXMgLz59IC8+XG4gICAgICAgICAgICB7LyogRkVBVFVSRV9CT0FSRCDqurzsp4Qg67Cw7Y+s7JeQ7ISgIO2OmOydtOyngCDsoJHqt7wg7IucIEFQSSA0MDQg4oaSIOuqqeuhneycvOuhnCDslYjrgrQuXG4gICAgICAgICAgICAgICAg64Sk67mEIO2VreuqqSDsnpDssrTripQgdXNlQm9hcmRGZWF0dXJlIHByb2JlIOuhnCDsiKjqsqjsp4Tri6QuICovfVxuICAgICAgICAgICAgPFJvdXRlIHBhdGg9XCJib2FyZFwiIGVsZW1lbnQ9ezxCb2FyZCAvPn0gLz5cbiAgICAgICAgICAgIDxSb3V0ZSBwYXRoPVwiYm9hcmQvbmV3XCIgZWxlbWVudD17PEJvYXJkRWRpdG9yIC8+fSAvPlxuICAgICAgICAgICAgPFJvdXRlIHBhdGg9XCJib2FyZC86cG9zdElkXCIgZWxlbWVudD17PEJvYXJkUG9zdCAvPn0gLz5cbiAgICAgICAgICAgIDxSb3V0ZSBwYXRoPVwiYm9hcmQvOnBvc3RJZC9lZGl0XCIgZWxlbWVudD17PEJvYXJkRWRpdG9yIC8+fSAvPlxuICAgICAgICAgICAgPFJvdXRlIHBhdGg9XCJhZG1pblwiIGVsZW1lbnQ9ezxBZG1pbiAvPn0gLz5cbiAgICAgICAgICAgIDxSb3V0ZSBwYXRoPVwic2V0dGluZ3NcIiBlbGVtZW50PXs8U2V0dGluZ3MgLz59PlxuICAgICAgICAgICAgICA8Um91dGUgaW5kZXggZWxlbWVudD17PE5hdmlnYXRlIHRvPVwicHJvZmlsZVwiIHJlcGxhY2UgLz59IC8+XG4gICAgICAgICAgICAgIDxSb3V0ZSBwYXRoPVwicHJvZmlsZVwiIGVsZW1lbnQ9ezxQcm9maWxlU2V0dGluZ3MgLz59IC8+XG4gICAgICAgICAgICAgIDxSb3V0ZSBwYXRoPVwic2VjdXJpdHlcIiBlbGVtZW50PXs8U2VjdXJpdHlTZXR0aW5ncyAvPn0gLz5cbiAgICAgICAgICAgICAgPFJvdXRlIHBhdGg9XCJtZW1vcnlcIiBlbGVtZW50PXs8TWVtb3J5U2V0dGluZ3MgLz59IC8+XG4gICAgICAgICAgICA8L1JvdXRlPlxuICAgICAgICAgIDwvUm91dGU+XG5cbiAgICAgICAgICB7LyogQ2F0Y2ggYWxsICovfVxuICAgICAgICAgIDxSb3V0ZSBwYXRoPVwiKlwiIG
534VsZW1lbnQ9ezxOYXZpZ2F0ZSB0bz1cIi9cIiByZXBsYWNlIC8+fSAvPlxuICAgICAgICAgIDwvUm91dGVzPlxuICAgICAgICA8L1N1c3BlbnNlPlxuICAgICAgICA8L0Jyb3dzZXJSb3V0ZXI+XG4gICAgICA8L0NvbmZpZ1Byb3ZpZGVyPlxuICAgIDwvRXJyb3JCb3VuZGFyeT5cbiAgKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgQXBwO1xuIl19

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.