@curless/hotel-storefront 0.55.7 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/account/fake-mall.d.ts +42 -0
- package/dist/account/fake-mall.d.ts.map +1 -0
- package/dist/account/fake-mall.js +168 -0
- package/dist/account/fake-mall.js.map +1 -0
- package/dist/account/index.d.ts +104 -0
- package/dist/account/index.d.ts.map +1 -0
- package/dist/account/index.js +845 -0
- package/dist/account/index.js.map +1 -0
- package/dist/account/mall.d.ts +83 -0
- package/dist/account/mall.d.ts.map +1 -0
- package/dist/account/mall.js +224 -0
- package/dist/account/mall.js.map +1 -0
- package/dist/account/pages.d.ts +118 -0
- package/dist/account/pages.d.ts.map +1 -0
- package/dist/account/pages.js +295 -0
- package/dist/account/pages.js.map +1 -0
- package/dist/account/requests.d.ts +68 -0
- package/dist/account/requests.d.ts.map +1 -0
- package/dist/account/requests.js +178 -0
- package/dist/account/requests.js.map +1 -0
- package/dist/account/store.d.ts +67 -0
- package/dist/account/store.d.ts.map +1 -0
- package/dist/account/store.js +151 -0
- package/dist/account/store.js.map +1 -0
- package/dist/card.generated.d.ts +1 -1
- package/dist/card.generated.js +2 -2
- package/dist/card.generated.js.map +1 -1
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/legal.d.ts.map +1 -1
- package/dist/legal.js +15 -3
- package/dist/legal.js.map +1 -1
- package/dist/otaless/backend.d.ts.map +1 -1
- package/dist/otaless/backend.js +6 -2
- package/dist/otaless/backend.js.map +1 -1
- package/dist/otaless/fake.d.ts +6 -3
- package/dist/otaless/fake.d.ts.map +1 -1
- package/dist/otaless/fake.js +19 -9
- package/dist/otaless/fake.js.map +1 -1
- package/dist/otaless/places.d.ts.map +1 -1
- package/dist/otaless/places.js +16 -4
- package/dist/otaless/places.js.map +1 -1
- package/dist/otaless/recorded-1105.d.ts +15 -0
- package/dist/otaless/recorded-1105.d.ts.map +1 -0
- package/dist/otaless/recorded-1105.js +1328 -0
- package/dist/otaless/recorded-1105.js.map +1 -0
- package/dist/server.d.ts +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +198 -45
- package/dist/server.js.map +1 -1
- package/dist/surface.d.ts.map +1 -1
- package/dist/surface.js +6 -4
- package/dist/surface.js.map +1 -1
- package/dist/tools.d.ts +240 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +21 -3
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
// The account's pages, drawn here - nothing loaded from anywhere but our own
|
|
2
|
+
// logo, no script, not framable, not cached, posting only to themselves
|
|
3
|
+
// (Nexva One's rules for its /login and /account, 2026-11-04).
|
|
4
|
+
const esc = (s) => String(s ?? '').replace(/[&<>"']/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[c] ?? c);
|
|
5
|
+
/** Every page's words, in the two languages the pages speak. `{0}` is a value. */
|
|
6
|
+
const WORDS = {
|
|
7
|
+
'Sign in to {0}': ['登录 {0} 账号', 'Sign in to {0}'],
|
|
8
|
+
'Sign-in code': ['登录码', 'Sign-in code'],
|
|
9
|
+
warnCard: [
|
|
10
|
+
'请核对这个码和对话里 {0} 卡片上的码一致。不一致,或者链接是别人发给你的,请关掉这个页面:在这里登录会把你的账号交给对方。',
|
|
11
|
+
'Check that this code matches the code on the {0} card in your chat. If it does not, or if someone sent you this link, close this page: signing in here would give them your account.',
|
|
12
|
+
],
|
|
13
|
+
warnWords: [
|
|
14
|
+
'请核对这个码和助手在对话里给你的码一致。不一致,或者链接是别人发给你的,请关掉这个页面:在这里登录会把你的账号交给对方。',
|
|
15
|
+
'Check that this code matches the code the assistant gave you in the chat. If it does not, or if someone sent you this link, close this page: signing in here would give them your account.',
|
|
16
|
+
],
|
|
17
|
+
'User name': ['用户名', 'User name'],
|
|
18
|
+
Password: ['密码', 'Password'],
|
|
19
|
+
Email: ['邮箱', 'Email'],
|
|
20
|
+
Phone: ['手机号', 'Phone'],
|
|
21
|
+
Nickname: ['昵称', 'Nickname'],
|
|
22
|
+
optional: ['选填', 'optional'],
|
|
23
|
+
phoneHint: ['带国家区号,如 +86 138 0000 0000', 'With country code, like +86 138 0000 0000'],
|
|
24
|
+
passwordHint: ['至少 6 位', 'At least 6 characters'],
|
|
25
|
+
'Sign in': ['登录', 'Sign in'],
|
|
26
|
+
'New here? Create an account': ['还没有账号?注册', 'New here? Create an account'],
|
|
27
|
+
'Create account': ['注册并登录', 'Create account'],
|
|
28
|
+
privacyNote: [
|
|
29
|
+
'密码只从这个页面发到 {0} 的账号服务。助手看不到它,我们也不保存、不记录。',
|
|
30
|
+
'Your password goes from this page to the {0} account service only. The assistant never sees it, and it is not kept or logged.',
|
|
31
|
+
],
|
|
32
|
+
'Signed in as {0}.': ['已登录:{0}', 'Signed in as {0}.'],
|
|
33
|
+
backToChat: [
|
|
34
|
+
'回到对话:几秒内就会显示已登录。',
|
|
35
|
+
'Go back to your chat: it shows you signed in within a few seconds.',
|
|
36
|
+
],
|
|
37
|
+
'View your account': ['查看账号', 'View your account'],
|
|
38
|
+
'Your {0} account': ['你的 {0} 账号', 'Your {0} account'],
|
|
39
|
+
Name: ['姓名', 'Name'],
|
|
40
|
+
'Sign out': ['退出登录', 'Sign out'],
|
|
41
|
+
signOutNote: [
|
|
42
|
+
'退出后,对话里也一起退出。这个页面 30 分钟不用会自动关闭。',
|
|
43
|
+
'Signing out here signs you out in your chat too. This page closes by itself after 30 minutes unused.',
|
|
44
|
+
],
|
|
45
|
+
'Signed out': ['已退出登录', 'Signed out'],
|
|
46
|
+
signedOutLine: [
|
|
47
|
+
'你已经退出 {0} 账号,对话里也一并退出了。',
|
|
48
|
+
'You are signed out of your {0} account, in your chat as well.',
|
|
49
|
+
],
|
|
50
|
+
Language: ['语言', 'Language'],
|
|
51
|
+
'Run by {0}.': ['{0} 运营。', 'Run by {0}.'],
|
|
52
|
+
Privacy: ['隐私', 'Privacy'],
|
|
53
|
+
'Terms of use': ['使用条款', 'Terms of use'],
|
|
54
|
+
// Why a page is not a form.
|
|
55
|
+
unknownH: ['这个登录链接无效', 'This sign-in link is not valid'],
|
|
56
|
+
again: [
|
|
57
|
+
'回到对话里重新点「登录」,或者请助手给你一个新链接。',
|
|
58
|
+
'Go back to your chat and tap Sign in again, or ask the assistant for a new link.',
|
|
59
|
+
],
|
|
60
|
+
expiredH: ['这个登录链接已过期', 'This sign-in link has expired'],
|
|
61
|
+
lasts: ['链接 5 分钟内有效。', 'Links last 5 minutes.'],
|
|
62
|
+
usedH: ['这个登录链接已经用过', 'This sign-in link has already been used'],
|
|
63
|
+
usedLine: [
|
|
64
|
+
'每个链接只能用一次。如果不是你用的,看看对话里显示的账号名,不是你的就在对话里退出登录。',
|
|
65
|
+
'Each link works once. If you did not use it, check the account name your chat shows, and sign out there if it is not yours.',
|
|
66
|
+
],
|
|
67
|
+
pendingH: ['正在登录,请稍候…', 'Signing you in, one moment…'],
|
|
68
|
+
pendingLine: ['这个页面一会儿会自己刷新。', 'This page updates by itself in a moment.'],
|
|
69
|
+
finishedH: ['已登录', 'Signed in'],
|
|
70
|
+
triesH: ['这个链接试错次数太多', 'Too many tries with this link'],
|
|
71
|
+
checkedH: ['这个请求没能核实', 'This request could not be checked'],
|
|
72
|
+
checkedLine: ['请从对话里重新打开链接。', 'Open the link from your chat again.'],
|
|
73
|
+
limitedH: ['请求太频繁', 'Too many requests just now'],
|
|
74
|
+
limitedLine: ['请等一分钟再试。', 'Wait a minute, then try again.'],
|
|
75
|
+
nosessionH: ['请从对话里打开账号', 'Open your account from your chat'],
|
|
76
|
+
nosessionLine: [
|
|
77
|
+
'账号页只在你登录的那个浏览器里打开,登录后 30 分钟内有效。也可以在对话里看账号。',
|
|
78
|
+
'This page opens only in the browser you signed in with, for 30 minutes after. Your chat shows your account too.',
|
|
79
|
+
],
|
|
80
|
+
// Refusals, in our words - never the mall's (`errorLine`).
|
|
81
|
+
sign_in_failed: ['用户名或密码不对,没能登录。', 'That user name and password did not sign in.'],
|
|
82
|
+
register_failed: [
|
|
83
|
+
'没能创建这个账号。用户名或邮箱可能已经注册过,可以试试直接登录。',
|
|
84
|
+
'That account could not be created. The user name or email may already be registered: try signing in instead.',
|
|
85
|
+
],
|
|
86
|
+
registered_not_signed_in: [
|
|
87
|
+
'账号已经创建,但没能自动登录。请用刚才的用户名和密码登录。',
|
|
88
|
+
'The account was created, but signing in failed. Sign in with that user name and password.',
|
|
89
|
+
],
|
|
90
|
+
missing_in: ['请填写用户名和密码。', 'Enter your user name and password.'],
|
|
91
|
+
missing_up: ['请填写用户名、邮箱和密码。', 'Enter a user name, an email and a password.'],
|
|
92
|
+
bad_email: ['邮箱地址格式不对。', 'That email address does not look right.'],
|
|
93
|
+
bad_mobile: [
|
|
94
|
+
'手机号要带国家区号,以 + 开头(如 +86 138 0000 0000)。',
|
|
95
|
+
'A phone number needs its country code, starting with + (like +86 138 0000 0000).',
|
|
96
|
+
],
|
|
97
|
+
short_password: ['密码至少 6 位。', 'Use a password of at least 6 characters.'],
|
|
98
|
+
too_many: [
|
|
99
|
+
'尝试次数太多,请 10 分钟后再试。',
|
|
100
|
+
'Too many attempts. Wait ten minutes and try again.',
|
|
101
|
+
],
|
|
102
|
+
busy: [
|
|
103
|
+
'{0} 的账号服务暂时没有响应,请稍后再试。',
|
|
104
|
+
'The {0} account service did not answer just now. Try again shortly.',
|
|
105
|
+
],
|
|
106
|
+
};
|
|
107
|
+
export const say = (lang, key, ...values) => WORDS[key][lang === 'zh' ? 0 : 1].replace(/\{(\d)\}/g, (_, i) => values[Number(i)] ?? '');
|
|
108
|
+
/**
|
|
109
|
+
* ⚠️ REFERRER-POLICY same-origin, NOT no-referrer (Nexva, Chrome checked
|
|
110
|
+
* 2026-11-04): under no-referrer a browser sends `Origin: null` on the page's
|
|
111
|
+
* own form posts, and the Origin check would refuse every real sign-in. Ours
|
|
112
|
+
* goes to ourselves; nothing goes to any other site - the code in
|
|
113
|
+
* /login?code=… never leaves, and the footer's links say rel="noreferrer".
|
|
114
|
+
*/
|
|
115
|
+
export const PAGE_HEADERS = {
|
|
116
|
+
'Content-Security-Policy': "default-src 'none'; style-src 'unsafe-inline'; img-src 'self'; form-action 'self'; frame-ancestors 'none'; base-uri 'none'",
|
|
117
|
+
'X-Frame-Options': 'DENY',
|
|
118
|
+
'Referrer-Policy': 'same-origin',
|
|
119
|
+
'Cache-Control': 'no-store',
|
|
120
|
+
'X-Content-Type-Options': 'nosniff',
|
|
121
|
+
'X-Robots-Tag': 'noindex, nofollow',
|
|
122
|
+
};
|
|
123
|
+
// AA everywhere: soft text 7:1, the warning 5.6:1, a field's rim 3:1 (WCAG
|
|
124
|
+
// 1.4.11). Nothing under 14px; every target 44px.
|
|
125
|
+
const CSS = `
|
|
126
|
+
:root { --bg: #f5f6f8; --card: #fff; --fg: #111827; --soft: #4b5563; --line: #e5e7eb; --rim: #8b909a;
|
|
127
|
+
--accent: #2251e0; --accent-fg: #fff; --link: #1d4ed8; --warn: #7a4f00; --warn-bg: #fdf2dc; --warn-rim: #c58a1b;
|
|
128
|
+
--bad: #b42318; --bad-bg: #fdecea; --good: #0f6b4b; --good-bg: #e3f5ec; color-scheme: light;
|
|
129
|
+
--cjk: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", "Noto Sans CJK SC" }
|
|
130
|
+
@media (prefers-color-scheme: dark) { :root { --bg: #0b0f17; --card: #141a24; --fg: #f3f4f6; --soft: #cbd0d8; --line: #262f3d; --rim: #6b7482;
|
|
131
|
+
--accent: #7aa2ff; --accent-fg: #0b1636; --link: #9dbaff; --warn: #f6d38f; --warn-bg: #2a2312; --warn-rim: #b88a2e;
|
|
132
|
+
--bad: #ff9a90; --bad-bg: #2a1514; --good: #6fd3a2; --good-bg: #0b2a20; color-scheme: dark } }
|
|
133
|
+
* { box-sizing: border-box }
|
|
134
|
+
body { margin: 0; background: var(--bg); color: var(--fg); -webkit-font-smoothing: antialiased;
|
|
135
|
+
font: 16px/1.5 -apple-system, "SF Pro Text", BlinkMacSystemFont, var(--cjk), "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif }
|
|
136
|
+
main { max-width: 480px; margin: 0 auto; padding: 20px 16px 40px }
|
|
137
|
+
.brand { display: flex; align-items: center; min-height: 40px; margin: 0 0 20px }
|
|
138
|
+
.brand img { height: 32px; width: auto; max-width: 200px }
|
|
139
|
+
.brand .wm { font-size: 20px; font-weight: 650; letter-spacing: -0.01em }
|
|
140
|
+
.brand .dark { display: none }
|
|
141
|
+
@media (prefers-color-scheme: dark) { .brand .has-dark { display: none } .brand .dark { display: block } }
|
|
142
|
+
h1 { font-size: 24px; line-height: 1.3; margin: 0 0 16px; text-wrap: balance }
|
|
143
|
+
p { margin: 0 0 12px }
|
|
144
|
+
.box { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 16px; margin: 0 0 16px }
|
|
145
|
+
.code-box { border: 2px solid var(--accent); text-align: center }
|
|
146
|
+
.code-label { font-size: 14px; font-weight: 600; color: var(--soft) }
|
|
147
|
+
.code { font: 600 34px/1.25 ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: 0.06em; margin: 4px 0 12px; overflow-wrap: anywhere }
|
|
148
|
+
.warn { text-align: left; background: var(--warn-bg); color: var(--warn); border: 1px solid var(--warn-rim); border-left-width: 5px; border-radius: 10px;
|
|
149
|
+
padding: 12px 14px; margin: 0; font-size: 15px; font-weight: 600 }
|
|
150
|
+
.msg { border-radius: 10px; padding: 12px 14px; margin: 0 0 16px; font-size: 15px }
|
|
151
|
+
.msg.err { color: var(--bad); background: var(--bad-bg) }
|
|
152
|
+
label.field { display: block; margin: 0 0 14px }
|
|
153
|
+
label.field > span { display: block; font-size: 14px; font-weight: 600; margin: 0 0 6px }
|
|
154
|
+
label.field em { font-style: normal; font-weight: 400; color: var(--soft) }
|
|
155
|
+
input { width: 100%; min-height: 44px; padding: 10px 12px; font: inherit; color: var(--fg); background: var(--card); border: 1px solid var(--rim); border-radius: 8px }
|
|
156
|
+
input::placeholder { color: var(--soft); opacity: 1 }
|
|
157
|
+
input:focus-visible, button:focus-visible, a:focus-visible, summary:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px }
|
|
158
|
+
button { font: inherit; cursor: pointer }
|
|
159
|
+
.primary { display: block; width: 100%; min-height: 48px; padding: 11px 14px; border: 1px solid var(--accent); border-radius: 8px;
|
|
160
|
+
background: var(--accent); color: var(--accent-fg); font-weight: 650; text-align: center; text-decoration: none }
|
|
161
|
+
.secondary { display: block; width: 100%; min-height: 48px; padding: 11px 14px; border: 1px solid var(--rim); border-radius: 8px;
|
|
162
|
+
background: transparent; color: var(--fg); font-weight: 600; text-align: center; text-decoration: none }
|
|
163
|
+
details.box > summary { display: flex; align-items: center; gap: 12px; min-height: 44px; color: var(--link); font-weight: 600; cursor: pointer; list-style: none }
|
|
164
|
+
details.box > summary::-webkit-details-marker { display: none }
|
|
165
|
+
details.box > summary::after { content: ""; flex: none; margin-left: auto; width: 9px; height: 9px; border: solid currentColor; border-width: 0 2px 2px 0; transform: translateY(-2px) rotate(45deg) }
|
|
166
|
+
details.box[open] > summary::after { transform: translateY(2px) rotate(-135deg) }
|
|
167
|
+
details.box[open] > summary { margin: 0 0 12px }
|
|
168
|
+
.note { font-size: 14px; color: var(--soft) }
|
|
169
|
+
.who { display: flex; align-items: center; gap: 12px; margin: 0 0 4px }
|
|
170
|
+
.av { width: 44px; height: 44px; border-radius: 50%; flex: none; display: grid; place-items: center; background: var(--accent); color: var(--accent-fg); font-weight: 700; font-size: 18px }
|
|
171
|
+
.name { font-size: 18px; font-weight: 650; overflow-wrap: anywhere }
|
|
172
|
+
dl.facts { margin: 12px 0 0; display: grid; grid-template-columns: max-content 1fr; gap: 10px 16px }
|
|
173
|
+
dl.facts dt { color: var(--soft); font-size: 15px }
|
|
174
|
+
dl.facts dd { margin: 0; font-weight: 600; overflow-wrap: anywhere }
|
|
175
|
+
nav.langs { display: flex; flex-wrap: wrap; gap: 6px; margin: 28px 0 0 }
|
|
176
|
+
nav.langs a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px; border: 1px solid var(--line); border-radius: 999px;
|
|
177
|
+
color: var(--fg); background: var(--card); text-decoration: none; font-size: 14px }
|
|
178
|
+
nav.langs a[aria-current] { border-color: var(--fg); font-weight: 600 }
|
|
179
|
+
footer { margin-top: 16px; font-size: 14px; color: var(--soft) }
|
|
180
|
+
footer p { margin: 0 }
|
|
181
|
+
footer a { display: inline-flex; align-items: center; min-height: 44px; color: var(--link); margin-right: 16px; text-underline-offset: 2px }
|
|
182
|
+
`;
|
|
183
|
+
const LANG_NAMES = { zh: '简体中文', en: 'English' };
|
|
184
|
+
export const page = (b, { lang, title, body, head = '', langHref, }) => {
|
|
185
|
+
const logo = b.logo
|
|
186
|
+
? `<img src="${esc(b.logo)}" alt="${esc(b.brand)}"${b.logoDark ? ' class="has-dark"' : ''}>${b.logoDark ? `<img src="${esc(b.logoDark)}" alt="${esc(b.brand)}" class="dark">` : ''}`
|
|
187
|
+
: `<span class="wm">${esc(b.brand)}</span>`;
|
|
188
|
+
return `<!doctype html><html lang="${lang === 'zh' ? 'zh-CN' : 'en'}"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
189
|
+
<meta name="robots" content="noindex, nofollow">${head}
|
|
190
|
+
<title>${esc(title)} · ${esc(b.brand)}</title>
|
|
191
|
+
<style>${CSS}</style>
|
|
192
|
+
<main>
|
|
193
|
+
<div class="brand">${logo}</div>
|
|
194
|
+
${body}
|
|
195
|
+
<nav class="langs" aria-label="${esc(say(lang, 'Language'))}">${['zh', 'en'].map((l) => `<a href="${esc(langHref(l))}" lang="${l === 'zh' ? 'zh-CN' : 'en'}"${l === lang ? ' aria-current="page"' : ''}>${LANG_NAMES[l]}</a>`).join('')}</nav>
|
|
196
|
+
<footer>${b.operator ? `<p>${esc(say(lang, 'Run by {0}.', b.operator))}</p>` : ''}
|
|
197
|
+
<a href="${esc(b.base)}/privacy" rel="noreferrer">${esc(say(lang, 'Privacy'))}</a><a href="${esc(b.base)}/terms" rel="noreferrer">${esc(say(lang, 'Terms of use'))}</a></footer>
|
|
198
|
+
</main></html>`;
|
|
199
|
+
};
|
|
200
|
+
const STATES = {
|
|
201
|
+
unknown: ['unknownH', 'again'],
|
|
202
|
+
expired: ['expiredH', 'lasts', 'again'],
|
|
203
|
+
used: ['usedH', 'usedLine'],
|
|
204
|
+
pending: ['pendingH', 'pendingLine'],
|
|
205
|
+
finished: ['finishedH', 'backToChat'],
|
|
206
|
+
tries: ['triesH', 'again'],
|
|
207
|
+
checked: ['checkedH', 'checkedLine'],
|
|
208
|
+
limited: ['limitedH', 'limitedLine'],
|
|
209
|
+
nosession: ['nosessionH', 'nosessionLine'],
|
|
210
|
+
signedout: ['Signed out', 'signedOutLine'],
|
|
211
|
+
};
|
|
212
|
+
export const statePage = (b, lang, state, langHref, again) => {
|
|
213
|
+
const [h, ...lines] = STATES[state];
|
|
214
|
+
return page(b, {
|
|
215
|
+
lang,
|
|
216
|
+
title: say(lang, h, b.brand),
|
|
217
|
+
langHref,
|
|
218
|
+
head: again ? `<meta http-equiv="refresh" content="2;url=${esc(again)}">` : '',
|
|
219
|
+
body: `<h1>${esc(say(lang, h, b.brand))}</h1><div class="box">${lines.map((l) => `<p>${esc(say(lang, l, b.brand))}</p>`).join('')}</div>`,
|
|
220
|
+
});
|
|
221
|
+
};
|
|
222
|
+
const hidden = (fields) => Object.entries(fields)
|
|
223
|
+
.map(([k, v]) => `<input type="hidden" name="${esc(k)}" value="${esc(v)}">`)
|
|
224
|
+
.join('');
|
|
225
|
+
export const loginPage = (b, { lang, short, code, csrf, words, error, form = 'in', values = {}, }) => {
|
|
226
|
+
const up = form === 'up';
|
|
227
|
+
const base = { code, csrf, lang };
|
|
228
|
+
const field = (label, input, optional = false) => `<label class="field"><span>${esc(say(lang, label))}${optional ? ` <em>${esc(say(lang, 'optional'))}</em>` : ''}</span>${input}</label>`;
|
|
229
|
+
const err = (which) => error && form === which ? `<p class="msg err" role="alert">${esc(error)}</p>` : '';
|
|
230
|
+
const action = `${b.base}/login`;
|
|
231
|
+
const body = `<h1>${esc(say(lang, 'Sign in to {0}', b.brand))}</h1>
|
|
232
|
+
<div class="box code-box">
|
|
233
|
+
<div class="code-label" id="codel">${esc(say(lang, 'Sign-in code'))}</div>
|
|
234
|
+
<div class="code" aria-labelledby="codel">${esc(short)}</div>
|
|
235
|
+
<p class="warn" role="note">${esc(say(lang, words ? 'warnWords' : 'warnCard', b.brand))}</p>
|
|
236
|
+
</div>
|
|
237
|
+
${err('in')}
|
|
238
|
+
<form class="box" method="post" action="${esc(action)}" autocomplete="on">${hidden({ ...base, form: 'in' })}
|
|
239
|
+
${field('User name', `<input name="account" autocomplete="username" required maxlength="120" value="${esc(up ? '' : (values.account ?? ''))}">`)}
|
|
240
|
+
${field('Password', '<input name="password" type="password" autocomplete="current-password" required maxlength="128">')}
|
|
241
|
+
<button class="primary" type="submit">${esc(say(lang, 'Sign in'))}</button>
|
|
242
|
+
</form>
|
|
243
|
+
<details class="box"${up ? ' open' : ''}><summary>${esc(say(lang, 'New here? Create an account'))}</summary>
|
|
244
|
+
${err('up')}
|
|
245
|
+
<form method="post" action="${esc(action)}" autocomplete="on">${hidden({ ...base, form: 'up' })}
|
|
246
|
+
${field('User name', `<input name="userName" autocomplete="username" required maxlength="50" value="${esc(up ? (values.userName ?? '') : '')}">`)}
|
|
247
|
+
${field('Email', `<input name="email" type="email" autocomplete="email" required maxlength="254" value="${esc(up ? (values.email ?? '') : '')}">`)}
|
|
248
|
+
${field('Password', `<input name="password" type="password" autocomplete="new-password" required minlength="6" maxlength="128" placeholder="${esc(say(lang, 'passwordHint'))}">`)}
|
|
249
|
+
${field('Phone', `<input name="mobile" type="tel" autocomplete="tel" inputmode="tel" maxlength="24" pattern="\\+[\\d\\s\\-\\(\\)\\.]{6,22}" placeholder="${esc(say(lang, 'phoneHint'))}" value="${esc(up ? (values.mobile ?? '') : '')}">`, true)}
|
|
250
|
+
${field('Nickname', `<input name="nickname" maxlength="50" autocomplete="nickname" value="${esc(up ? (values.nickname ?? '') : '')}">`, true)}
|
|
251
|
+
<button class="primary" type="submit">${esc(say(lang, 'Create account'))}</button>
|
|
252
|
+
</form>
|
|
253
|
+
</details>
|
|
254
|
+
<p class="note">${esc(say(lang, 'privacyNote', b.brand))}</p>`;
|
|
255
|
+
return page(b, {
|
|
256
|
+
lang,
|
|
257
|
+
title: say(lang, 'Sign in to {0}', b.brand),
|
|
258
|
+
body,
|
|
259
|
+
langHref: (l) => `${b.base}/login?code=${encodeURIComponent(code)}&lang=${l}`,
|
|
260
|
+
});
|
|
261
|
+
};
|
|
262
|
+
export const signedInPage = (b, { lang, name, account }) => page(b, {
|
|
263
|
+
lang,
|
|
264
|
+
title: say(lang, 'finishedH'),
|
|
265
|
+
langHref: (l) => `${b.base}/account?lang=${l}`,
|
|
266
|
+
body: `<h1>${esc(say(lang, 'Signed in as {0}.', name))}</h1>
|
|
267
|
+
<div class="box"><p>${esc(say(lang, 'backToChat'))}</p>
|
|
268
|
+
${account ? `<a class="secondary" href="${esc(b.base)}/account?lang=${lang}">${esc(say(lang, 'View your account'))}</a>` : ''}</div>`,
|
|
269
|
+
});
|
|
270
|
+
export const accountPage = (b, { lang, shown, csrf }) => {
|
|
271
|
+
const name = shown.displayName || shown.userName || '';
|
|
272
|
+
const facts = [
|
|
273
|
+
['User name', shown.userName],
|
|
274
|
+
['Name', shown.name],
|
|
275
|
+
['Email', shown.email],
|
|
276
|
+
['Phone', shown.mobile],
|
|
277
|
+
];
|
|
278
|
+
const body = `<h1>${esc(say(lang, 'Your {0} account', b.brand))}</h1>
|
|
279
|
+
<div class="box"><div class="who"><span class="av" aria-hidden="true">${esc(Array.from(name)[0]?.toUpperCase() ?? '?')}</span><span class="name">${esc(name)}</span></div>
|
|
280
|
+
<dl class="facts">${facts
|
|
281
|
+
.filter(([, v]) => !!v)
|
|
282
|
+
.map(([k, v]) => `<dt>${esc(say(lang, k))}</dt><dd>${esc(v)}</dd>`)
|
|
283
|
+
.join('')}</dl></div>
|
|
284
|
+
<form method="post" action="${esc(b.base)}/account">${hidden({ csrf, lang, action: 'signout' })}
|
|
285
|
+
<button class="secondary" type="submit">${esc(say(lang, 'Sign out'))}</button>
|
|
286
|
+
<p class="note" style="margin-top:8px">${esc(say(lang, 'signOutNote'))}</p>
|
|
287
|
+
</form>`;
|
|
288
|
+
return page(b, {
|
|
289
|
+
lang,
|
|
290
|
+
title: say(lang, 'Your {0} account', b.brand),
|
|
291
|
+
body,
|
|
292
|
+
langHref: (l) => `${b.base}/account?lang=${l}`,
|
|
293
|
+
});
|
|
294
|
+
};
|
|
295
|
+
//# sourceMappingURL=pages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pages.js","sourceRoot":"","sources":["../../src/account/pages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export declare const SIGN_IN_MS: number;
|
|
2
|
+
export declare const shortCode: () => string;
|
|
3
|
+
/** 256 bits, base64url. */
|
|
4
|
+
export declare const secret: () => string;
|
|
5
|
+
export declare const CODE: RegExp;
|
|
6
|
+
export declare const hashOf: (s: string) => string;
|
|
7
|
+
export declare const same: (a: unknown, b: unknown) => boolean;
|
|
8
|
+
export type Lang = 'zh' | 'en';
|
|
9
|
+
export type SignInRequest = {
|
|
10
|
+
codeHash: string;
|
|
11
|
+
/** The conversation it signs in (`tripKey`). Never shown, never logged whole. */
|
|
12
|
+
key: string;
|
|
13
|
+
short: string;
|
|
14
|
+
/** The page's first language - the card's, or the assistant's guess. */
|
|
15
|
+
lang?: Lang;
|
|
16
|
+
/** Its code went into the assistant's words (no card): the page says "the code the assistant gave you". */
|
|
17
|
+
words: boolean;
|
|
18
|
+
created: number;
|
|
19
|
+
expires: number;
|
|
20
|
+
state: 'open' | 'pending' | 'done' | 'dead';
|
|
21
|
+
why?: 'tries' | 'replaced' | 'cancelled';
|
|
22
|
+
tries: number;
|
|
23
|
+
doneAt?: number;
|
|
24
|
+
};
|
|
25
|
+
/** What a page with this code shows: 'open', or why not. */
|
|
26
|
+
export type RequestState = 'open' | 'pending' | 'used' | 'expired' | 'tries' | 'unknown';
|
|
27
|
+
export type SignInRequests = ReturnType<typeof createSignIns>;
|
|
28
|
+
export declare const createSignIns: ({ now, ttlMs, maxTries, keepMs, max, perKey, }?: {
|
|
29
|
+
now?: () => number;
|
|
30
|
+
ttlMs?: number;
|
|
31
|
+
maxTries?: number;
|
|
32
|
+
keepMs?: number;
|
|
33
|
+
max?: number;
|
|
34
|
+
perKey?: number;
|
|
35
|
+
}) => {
|
|
36
|
+
ttlMs: number;
|
|
37
|
+
/** A new request for this conversation - or null, the table full of open ones. */
|
|
38
|
+
create({ key, lang, words }: {
|
|
39
|
+
key: string;
|
|
40
|
+
lang?: Lang;
|
|
41
|
+
words?: boolean;
|
|
42
|
+
}): {
|
|
43
|
+
code: string;
|
|
44
|
+
short: string;
|
|
45
|
+
expiresAt: number;
|
|
46
|
+
request: SignInRequest;
|
|
47
|
+
} | null;
|
|
48
|
+
find(code: unknown): SignInRequest | null;
|
|
49
|
+
/** `signedIn`: the conversation is signed in by now - a link of its guest's is used. */
|
|
50
|
+
state(r: SignInRequest | null, signedIn: boolean): RequestState;
|
|
51
|
+
/** One more try at the page's form; past `maxTries` the request is dead. */
|
|
52
|
+
tried(r: SignInRequest): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* ⚠️ ONE POST AT A TIME (Nexva's review P2-1): two sign-ins sent at once on
|
|
55
|
+
* one link both reached the mall. The first takes it before it waits.
|
|
56
|
+
*/
|
|
57
|
+
begin(r: SignInRequest): boolean;
|
|
58
|
+
reopen(r: SignInRequest): void;
|
|
59
|
+
/** Used, once - and every other open request of the conversation is dead. */
|
|
60
|
+
done(r: SignInRequest): void;
|
|
61
|
+
/** A sign-out: every open request of the conversation is dead. One being posted finishes. */
|
|
62
|
+
cancelFor(key: string): void;
|
|
63
|
+
/** The conversation's newest request still open - what the card's sign-in page waits on. */
|
|
64
|
+
openFor(key: string): SignInRequest | null;
|
|
65
|
+
size: () => number;
|
|
66
|
+
open: () => number;
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=requests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../src/account/requests.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,UAAU,QAAa,CAAC;AAGrC,eAAO,MAAM,SAAS,QAAO,MAI5B,CAAC;AACF,2BAA2B;AAC3B,eAAO,MAAM,MAAM,QAAO,MAA+C,CAAC;AAC1E,eAAO,MAAM,IAAI,QAAwB,CAAC;AAC1C,eAAO,MAAM,MAAM,GAAI,GAAG,MAAM,KAAG,MAA4D,CAAC;AAChG,eAAO,MAAM,IAAI,GAAI,GAAG,OAAO,EAAE,GAAG,OAAO,KAAG,OAI7C,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/B,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,2GAA2G;IAC3G,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAC5C,GAAG,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,WAAW,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,4DAA4D;AAC5D,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAEzF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAE9D,eAAO,MAAM,aAAa,GAAI,iDAO3B;IACD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACZ;;IAgCF,kFAAkF;iCAC7C;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;;;;;;eA2BvE,OAAO,GAAG,aAAa,GAAG,IAAI;IAIzC,wFAAwF;aAC/E,aAAa,GAAG,IAAI,YAAY,OAAO,GAAG,YAAY;IAS/D,4EAA4E;aACnE,aAAa,GAAG,OAAO;IAShC;;;OAGG;aACM,aAAa,GAAG,OAAO;cAKtB,aAAa,GAAG,IAAI;IAG9B,6EAA6E;YACrE,aAAa,GAAG,IAAI;IAS5B,6FAA6F;mBAC9E,MAAM,GAAG,IAAI;IAO5B,4FAA4F;iBAC/E,MAAM,GAAG,aAAa,GAAG,IAAI;gBAKhC,MAAM;gBACN,MAAM;CAEnB,CAAC"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { createHash, randomBytes, randomInt, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
// One-time sign-in requests - Nexva One's (marketplace server/web-signin.mjs
|
|
3
|
+
// createSignIns, two security reviews by 总线程), for a conversation instead
|
|
4
|
+
// of a cart.
|
|
5
|
+
//
|
|
6
|
+
// The card's "Sign in" (or the assistant, where no card is drawn) asks for one:
|
|
7
|
+
// a long code - the link's secret - and a short code to compare by eye. The
|
|
8
|
+
// page at /login?code=… shows the short code too; the guest signs in or makes
|
|
9
|
+
// an account there, never in the chat, and the conversation is then signed in.
|
|
10
|
+
//
|
|
11
|
+
// ⚠️ IN MEMORY ONLY, KEPT BY THEIR HASH: the table holds no code that opens
|
|
12
|
+
// anything, and a restart means asking again.
|
|
13
|
+
//
|
|
14
|
+
// open → pending (a POST of its page is at the mall; back to open if refused)
|
|
15
|
+
// → done (used: once)
|
|
16
|
+
// → dead (too many tries; the conversation signed in or out meanwhile)
|
|
17
|
+
// → expired (5 minutes)
|
|
18
|
+
// A used or dead one is kept 30 minutes more, so its page says "used" rather
|
|
19
|
+
// than "not valid". At most `perKey` open per conversation.
|
|
20
|
+
export const SIGN_IN_MS = 5 * 60_000;
|
|
21
|
+
/** 8 letters a reader cannot confuse (no I, no O), shown XXXX-XXXX. For the eye only: it opens nothing. */
|
|
22
|
+
const SHORT = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
|
|
23
|
+
export const shortCode = () => {
|
|
24
|
+
let s = '';
|
|
25
|
+
for (let i = 0; i < 8; i++)
|
|
26
|
+
s += SHORT[randomInt(SHORT.length)];
|
|
27
|
+
return `${s.slice(0, 4)}-${s.slice(4)}`;
|
|
28
|
+
};
|
|
29
|
+
/** 256 bits, base64url. */
|
|
30
|
+
export const secret = () => randomBytes(32).toString('base64url');
|
|
31
|
+
export const CODE = /^[A-Za-z0-9_-]{43}$/;
|
|
32
|
+
export const hashOf = (s) => createHash('sha256').update(s).digest('base64url');
|
|
33
|
+
export const same = (a, b) => {
|
|
34
|
+
const x = Buffer.from(String(a ?? ''));
|
|
35
|
+
const y = Buffer.from(String(b ?? ''));
|
|
36
|
+
return x.length === y.length && timingSafeEqual(x, y);
|
|
37
|
+
};
|
|
38
|
+
export const createSignIns = ({ now = () => Date.now(), ttlMs = SIGN_IN_MS, maxTries = 10, keepMs = 30 * 60_000, max = 20_000, perKey = 5, } = {}) => {
|
|
39
|
+
const byCode = new Map(); // oldest first
|
|
40
|
+
const byKey = new Map();
|
|
41
|
+
const forget = (r) => {
|
|
42
|
+
byCode.delete(r.codeHash);
|
|
43
|
+
const s = byKey.get(r.key);
|
|
44
|
+
if (s) {
|
|
45
|
+
s.delete(r);
|
|
46
|
+
if (!s.size)
|
|
47
|
+
byKey.delete(r.key);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const isOpen = (r) => r.state === 'open' && now() <= r.expires;
|
|
51
|
+
const live = (r) => (r.state === 'open' || r.state === 'pending') && now() <= r.expires;
|
|
52
|
+
// Past their 30 minutes: gone. Full: everything not live goes, oldest first.
|
|
53
|
+
// ⚠️ A FULL TABLE NEVER PUSHES OUT AN OPEN REQUEST (Nexva's review P2-3): with
|
|
54
|
+
// only open ones left a new one is refused - a flood of sign-ins must not
|
|
55
|
+
// void a guest's link while they type.
|
|
56
|
+
const sweep = () => {
|
|
57
|
+
const t = now();
|
|
58
|
+
for (const r of byCode.values()) {
|
|
59
|
+
if (t - r.created > keepMs)
|
|
60
|
+
forget(r);
|
|
61
|
+
else
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
if (byCode.size < max)
|
|
65
|
+
return;
|
|
66
|
+
for (const r of [...byCode.values()]) {
|
|
67
|
+
if (byCode.size < max)
|
|
68
|
+
break;
|
|
69
|
+
if (!live(r))
|
|
70
|
+
forget(r);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
ttlMs,
|
|
75
|
+
/** A new request for this conversation - or null, the table full of open ones. */
|
|
76
|
+
create({ key, lang, words = false }) {
|
|
77
|
+
sweep();
|
|
78
|
+
if (byCode.size >= max)
|
|
79
|
+
return null;
|
|
80
|
+
const code = secret();
|
|
81
|
+
const r = {
|
|
82
|
+
codeHash: hashOf(code),
|
|
83
|
+
key,
|
|
84
|
+
short: shortCode(),
|
|
85
|
+
...(lang ? { lang } : {}),
|
|
86
|
+
words,
|
|
87
|
+
created: now(),
|
|
88
|
+
expires: now() + ttlMs,
|
|
89
|
+
state: 'open',
|
|
90
|
+
tries: 0,
|
|
91
|
+
};
|
|
92
|
+
const mine = byKey.get(key) ?? new Set();
|
|
93
|
+
// The oldest of this conversation's open ones goes dead past `perKey`.
|
|
94
|
+
const open = [...mine].filter(isOpen);
|
|
95
|
+
for (const o of open.slice(0, Math.max(0, open.length - perKey + 1))) {
|
|
96
|
+
o.state = 'dead';
|
|
97
|
+
o.why = 'replaced';
|
|
98
|
+
}
|
|
99
|
+
mine.add(r);
|
|
100
|
+
byKey.set(key, mine);
|
|
101
|
+
byCode.set(r.codeHash, r);
|
|
102
|
+
return { code, short: r.short, expiresAt: r.expires, request: r };
|
|
103
|
+
},
|
|
104
|
+
find(code) {
|
|
105
|
+
const c = String(code ?? '');
|
|
106
|
+
return CODE.test(c) ? (byCode.get(hashOf(c)) ?? null) : null;
|
|
107
|
+
},
|
|
108
|
+
/** `signedIn`: the conversation is signed in by now - a link of its guest's is used. */
|
|
109
|
+
state(r, signedIn) {
|
|
110
|
+
if (!r)
|
|
111
|
+
return 'unknown';
|
|
112
|
+
if (r.state === 'pending')
|
|
113
|
+
return 'pending';
|
|
114
|
+
if (r.state === 'done')
|
|
115
|
+
return 'used';
|
|
116
|
+
if (r.state === 'dead')
|
|
117
|
+
return r.why === 'tries' ? 'tries' : 'expired';
|
|
118
|
+
if (now() > r.expires)
|
|
119
|
+
return 'expired';
|
|
120
|
+
if (signedIn)
|
|
121
|
+
return 'used';
|
|
122
|
+
return 'open';
|
|
123
|
+
},
|
|
124
|
+
/** One more try at the page's form; past `maxTries` the request is dead. */
|
|
125
|
+
tried(r) {
|
|
126
|
+
r.tries++;
|
|
127
|
+
if (r.tries > maxTries) {
|
|
128
|
+
r.state = 'dead';
|
|
129
|
+
r.why = 'tries';
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
return true;
|
|
133
|
+
},
|
|
134
|
+
/**
|
|
135
|
+
* ⚠️ ONE POST AT A TIME (Nexva's review P2-1): two sign-ins sent at once on
|
|
136
|
+
* one link both reached the mall. The first takes it before it waits.
|
|
137
|
+
*/
|
|
138
|
+
begin(r) {
|
|
139
|
+
if (r.state !== 'open' || now() > r.expires)
|
|
140
|
+
return false;
|
|
141
|
+
r.state = 'pending';
|
|
142
|
+
return true;
|
|
143
|
+
},
|
|
144
|
+
reopen(r) {
|
|
145
|
+
if (r.state === 'pending')
|
|
146
|
+
r.state = 'open';
|
|
147
|
+
},
|
|
148
|
+
/** Used, once - and every other open request of the conversation is dead. */
|
|
149
|
+
done(r) {
|
|
150
|
+
r.state = 'done';
|
|
151
|
+
r.doneAt = now();
|
|
152
|
+
for (const o of byKey.get(r.key) ?? [])
|
|
153
|
+
if (o !== r && o.state === 'open') {
|
|
154
|
+
o.state = 'dead';
|
|
155
|
+
o.why = 'replaced';
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
/** A sign-out: every open request of the conversation is dead. One being posted finishes. */
|
|
159
|
+
cancelFor(key) {
|
|
160
|
+
for (const o of byKey.get(key) ?? [])
|
|
161
|
+
if (o.state === 'open') {
|
|
162
|
+
o.state = 'dead';
|
|
163
|
+
o.why = 'cancelled';
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
/** The conversation's newest request still open - what the card's sign-in page waits on. */
|
|
167
|
+
openFor(key) {
|
|
168
|
+
let newest = null;
|
|
169
|
+
for (const o of byKey.get(key) ?? [])
|
|
170
|
+
if (isOpen(o) || o.state === 'pending')
|
|
171
|
+
newest = o;
|
|
172
|
+
return newest;
|
|
173
|
+
},
|
|
174
|
+
size: () => byCode.size,
|
|
175
|
+
open: () => [...byCode.values()].filter(isOpen).length,
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
//# sourceMappingURL=requests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requests.js","sourceRoot":"","sources":["../../src/account/requests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAElF,6EAA6E;AAC7E,0EAA0E;AAC1E,aAAa;AACb,EAAE;AACF,gFAAgF;AAChF,4EAA4E;AAC5E,8EAA8E;AAC9E,+EAA+E;AAC/E,EAAE;AACF,4EAA4E;AAC5E,8CAA8C;AAC9C,EAAE;AACF,gFAAgF;AAChF,gCAAgC;AAChC,iFAAiF;AACjF,+BAA+B;AAC/B,6EAA6E;AAC7E,4DAA4D;AAE5D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAG,MAAM,CAAC;AACrC,2GAA2G;AAC3G,MAAM,KAAK,GAAG,0BAA0B,CAAC;AACzC,MAAM,CAAC,MAAM,SAAS,GAAG,GAAW,EAAE;IACpC,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;QAAE,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1C,CAAC,CAAC;AACF,2BAA2B;AAC3B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAW,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,IAAI,GAAG,qBAAqB,CAAC;AAC1C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AAChG,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAU,EAAE,CAAU,EAAW,EAAE;IACtD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AA0BF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAC5B,GAAG,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EACtB,KAAK,GAAG,UAAU,EAClB,QAAQ,GAAG,EAAE,EACb,MAAM,GAAG,EAAE,GAAG,MAAM,EACpB,GAAG,GAAG,MAAM,EACZ,MAAM,GAAG,CAAC,MAQR,EAAE,EAAE,EAAE;IACR,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC,CAAC,eAAe;IAChE,MAAM,KAAK,GAAG,IAAI,GAAG,EAA8B,CAAC;IACpD,MAAM,MAAM,GAAG,CAAC,CAAgB,EAAQ,EAAE;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,EAAE,CAAC;YACN,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACZ,IAAI,CAAC,CAAC,CAAC,IAAI;gBAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC;IACH,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,CAAC,CAAgB,EAAW,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,IAAI,GAAG,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC;IACvF,MAAM,IAAI,GAAG,CAAC,CAAgB,EAAW,EAAE,CACzC,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,IAAI,GAAG,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC;IACtE,6EAA6E;IAC7E,+EAA+E;IAC/E,0EAA0E;IAC1E,uCAAuC;IACvC,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;QAChB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YAChC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,GAAG,MAAM;gBAAE,MAAM,CAAC,CAAC,CAAC,CAAC;;gBACjC,MAAM;QACb,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,GAAG,GAAG;YAAE,OAAO;QAC9B,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;YACrC,IAAI,MAAM,CAAC,IAAI,GAAG,GAAG;gBAAE,MAAM;YAC7B,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;gBAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CAAC;IACF,OAAO;QACL,KAAK;QACL,kFAAkF;QAClF,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,EAAiD;YAChF,KAAK,EAAE,CAAC;YACR,IAAI,MAAM,CAAC,IAAI,IAAI,GAAG;gBAAE,OAAO,IAAI,CAAC;YACpC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC;YACtB,MAAM,CAAC,GAAkB;gBACvB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC;gBACtB,GAAG;gBACH,KAAK,EAAE,SAAS,EAAE;gBAClB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzB,KAAK;gBACL,OAAO,EAAE,GAAG,EAAE;gBACd,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK;gBACtB,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,CAAC;aACT,CAAC;YACF,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAiB,CAAC;YACxD,uEAAuE;YACvE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACtC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrE,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC;gBACjB,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC;YACrB,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACZ,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACrB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YAC1B,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QACpE,CAAC;QACD,IAAI,CAAC,IAAa;YAChB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;YAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/D,CAAC;QACD,wFAAwF;QACxF,KAAK,CAAC,CAAuB,EAAE,QAAiB;YAC9C,IAAI,CAAC,CAAC;gBAAE,OAAO,SAAS,CAAC;YACzB,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAC5C,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;gBAAE,OAAO,MAAM,CAAC;YACtC,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;gBAAE,OAAO,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;YACvE,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC,OAAO;gBAAE,OAAO,SAAS,CAAC;YACxC,IAAI,QAAQ;gBAAE,OAAO,MAAM,CAAC;YAC5B,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,4EAA4E;QAC5E,KAAK,CAAC,CAAgB;YACpB,CAAC,CAAC,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,CAAC,KAAK,GAAG,QAAQ,EAAE,CAAC;gBACvB,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC;gBACjB,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC;gBAChB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD;;;WAGG;QACH,KAAK,CAAC,CAAgB;YACpB,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC,OAAO;gBAAE,OAAO,KAAK,CAAC;YAC1D,CAAC,CAAC,KAAK,GAAG,SAAS,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,CAAC,CAAgB;YACrB,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;gBAAE,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC;QAC9C,CAAC;QACD,6EAA6E;QAC7E,IAAI,CAAC,CAAgB;YACnB,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC;YACjB,CAAC,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACjB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE;gBACpC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;oBAClC,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC;oBACjB,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC;gBACrB,CAAC;QACL,CAAC;QACD,6FAA6F;QAC7F,SAAS,CAAC,GAAW;YACnB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE;gBAClC,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;oBACvB,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC;oBACjB,CAAC,CAAC,GAAG,GAAG,WAAW,CAAC;gBACtB,CAAC;QACL,CAAC;QACD,4FAA4F;QAC5F,OAAO,CAAC,GAAW;YACjB,IAAI,MAAM,GAAyB,IAAI,CAAC;YACxC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE;gBAAE,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;oBAAE,MAAM,GAAG,CAAC,CAAC;YACzF,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,EAAE,GAAW,EAAE,CAAC,MAAM,CAAC,IAAI;QAC/B,IAAI,EAAE,GAAW,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM;KAC/D,CAAC;AACJ,CAAC,CAAC"}
|