@gotcos/glasses-server 6.98.0 → 6.99.12
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/CHANGELOG.md +158 -0
- package/package.json +2 -1
- package/server/index.ts +147 -9
- package/server/lib/api-auth.ts +31 -14
- package/server/lib/claude-bridge.ts +21 -2
- package/server/lib/codex-bridge.ts +21 -2
- package/server/lib/display-bus.ts +3 -0
- package/server/lib/drop-destinations.ts +134 -0
- package/server/lib/drop-history-search.ts +97 -0
- package/server/lib/drop-p2-boot.ts +60 -0
- package/server/lib/drop-p2-runtime.ts +237 -0
- package/server/lib/drop-p2-settings.ts +174 -0
- package/server/lib/drop-resolution.ts +168 -0
- package/server/lib/drop-router.ts +325 -0
- package/server/lib/drop-service.ts +739 -0
- package/server/lib/drop-settings.ts +45 -0
- package/server/lib/drop-store.ts +428 -0
- package/server/lib/drop-when.ts +265 -0
- package/server/lib/glasses-pairing.ts +15 -0
- package/server/lib/learning-needs-you.ts +111 -0
- package/server/lib/live-cues-v2-data.ts +336 -26
- package/server/lib/live-cues-v2-settings.ts +2 -1
- package/server/lib/live-cues-v2.ts +9 -5
- package/server/lib/meeting-consolidation-run.ts +169 -0
- package/server/lib/meeting-store.ts +61 -0
- package/server/lib/meeting-title-steer.ts +200 -0
- package/server/lib/network-policy.ts +84 -6
- package/server/lib/permission-broker.ts +11 -0
- package/server/lib/ping-budget.ts +149 -0
- package/server/lib/ping-engine.ts +245 -0
- package/server/lib/ping-feed-sink.ts +33 -0
- package/server/lib/ping-sources.ts +192 -0
- package/server/lib/query-job-coordinator.ts +5 -2
- package/server/lib/query-job-runtime.ts +45 -4
- package/server/lib/query-job-types.ts +10 -1
- package/server/lib/reminder-scheduler.ts +153 -0
- package/server/lib/tailnet-self-name.ts +103 -0
- package/server/lib/tailscale-nudge.ts +40 -2
- package/server/lib/task-store.ts +32 -0
- package/server/lib/web-ask-admission.ts +56 -0
- package/server/lib/web-live-chunks.ts +273 -0
- package/server/lib/web-memories-bridge.ts +323 -0
- package/server/lib/web-session-auth.ts +492 -0
- package/server/lib/web-usage-bridge.ts +154 -0
- package/server/lib/work-search.ts +14 -1
- package/server/lib/your-move-count.ts +58 -0
- package/server/routes/display.ts +11 -1
- package/server/routes/drops.ts +260 -0
- package/server/routes/health.ts +16 -0
- package/server/routes/live-cues.ts +5 -4
- package/server/routes/meeting.ts +61 -5
- package/server/routes/permission-broker.ts +23 -3
- package/server/routes/transcribe-stream.ts +34 -3
- package/server/routes/web-control.ts +569 -0
- package/server/routes/welcome-context.ts +2 -1
- package/server/web-control/app.css +519 -0
- package/server/web-control/app.js +3643 -0
- package/server/web-control/control.css +312 -0
- package/server/web-control/fonts/DMSans.ttf +0 -0
- package/server/web-control/fonts/Fraunces.ttf +0 -0
- package/server/web-control/fonts/JetBrainsMono.ttf +0 -0
- package/server/web-control/index.html +275 -0
- package/server/web-control/mark.svg +1 -0
- package/server/web-control/memories/d3.min.js +2 -0
- package/server/web-control/memories/graph-explorer.css +200 -0
- package/server/web-control/memories/graph-explorer.js +748 -0
- package/server/web-control/memories/memories-app.js +1561 -0
- package/server/web-control/memories/memories-theme.css +73 -0
- package/server/web-control/memories/memories.html +72 -0
- package/server/web-control/memories/memory-stewardship.js +63 -0
- package/server/web-control/memories/memory-workspace.js +216 -0
- package/server/web-control/panes/cos-chat.css +157 -0
- package/server/web-control/panes/cos-chat.js +973 -0
- package/server/web-control/panes/dictation.js +173 -0
- package/server/web-control/panes/meetings.css +257 -0
- package/server/web-control/panes/meetings.js +2264 -0
- package/server/web-control/panes/messages.js +711 -0
- package/server/web-control/panes/questions.css +32 -0
- package/server/web-control/panes/questions.js +275 -0
- package/server/web-control/panes/sessions.css +452 -0
- package/server/web-control/panes/settings.js +292 -0
- package/server/web-control/panes/speakers.css +269 -0
- package/server/web-control/panes/speakers.js +2755 -0
- package/server/web-control/panes/threads.js +200 -0
- package/server/web-control/panes/work.css +261 -0
- package/server/web-control/panes/work.js +1667 -0
- package/server/web-control/shell.js +294 -0
- package/server/web-control/theme.js +25 -0
- package/server/web-control/vendor/qrcode-encoder.js +10 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/* COS Control Web: the shell around the panes, mirroring Control's Activity window.
|
|
2
|
+
- The rail's story line under each pane name (TodayHome.story, Models.swift 14738-14800).
|
|
3
|
+
- The navigation bar off Today: Home, Back, "COS Control > Section > Detail", Settings.
|
|
4
|
+
- The server line at the foot of the rail: "Server connected" or "Server not reachable".
|
|
5
|
+
Stories read the same server routes Control's helper reads. They load with the shell, then
|
|
6
|
+
every five minutes while the page is visible, and again when it comes back into view. */
|
|
7
|
+
(function () {
|
|
8
|
+
'use strict';
|
|
9
|
+
var W = window.COSWeb;
|
|
10
|
+
var $ = W.$, esc = W.esc, api = W.api;
|
|
11
|
+
|
|
12
|
+
// ── stories ───────────────────────────────────────────
|
|
13
|
+
var FALLBACK = {
|
|
14
|
+
today: 'Reading',
|
|
15
|
+
messages: 'Questions and answers from your glasses',
|
|
16
|
+
speakers: 'Voices from your meetings',
|
|
17
|
+
meetings: 'Saved meetings by day',
|
|
18
|
+
memories: 'What your COS can recall',
|
|
19
|
+
threads: 'Work that develops over time',
|
|
20
|
+
sessions: 'Claude, Codex and Cursor on this Mac',
|
|
21
|
+
work: 'Your tasks and meeting follow-ups',
|
|
22
|
+
dictation: 'Dictate anywhere on this Mac'
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function setStory(name, text, hot) {
|
|
26
|
+
document.querySelectorAll('[data-story="' + name + '"]').forEach(function (el) {
|
|
27
|
+
el.textContent = text;
|
|
28
|
+
el.classList.toggle('hot', !!hot);
|
|
29
|
+
});
|
|
30
|
+
document.querySelectorAll('.rail-btn[data-pane="' + name + '"]').forEach(function (b) {
|
|
31
|
+
b.classList.toggle('hot', !!hot);
|
|
32
|
+
b.title = (W.titles[name] || name) + ', ' + text;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function sameDay(a, b) { return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate(); }
|
|
37
|
+
function clock(d) { return d.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' }); }
|
|
38
|
+
function monthDay(d) { return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' }); }
|
|
39
|
+
function toDate(v) {
|
|
40
|
+
if (v == null || v === '') return null;
|
|
41
|
+
var n = typeof v === 'number' ? v : (/^\d+$/.test(String(v)) ? Number(v) : NaN);
|
|
42
|
+
var d = !isNaN(n) ? new Date(n > 1e10 ? n : n * 1000) : new Date(v);
|
|
43
|
+
return isNaN(d.getTime()) ? null : d;
|
|
44
|
+
}
|
|
45
|
+
function clip(s, n) { s = String(s || ''); return s.length > n ? s.slice(0, n - 1).trimEnd() + '…' : s; }
|
|
46
|
+
function plural(n, one, many) { return n === 1 ? one : many; }
|
|
47
|
+
// Quiet hours (Control 0.5.361): after 6 PM and on weekends, what needs you can wait until tomorrow.
|
|
48
|
+
function quietNow(now) { var d = now.getDay(); return d === 0 || d === 6 || now.getHours() >= 18; }
|
|
49
|
+
function soft(p) { return p.then(function (d) { return d; }, function () { return null; }); }
|
|
50
|
+
|
|
51
|
+
// A meeting the Speakers pane would list as needing names (Control: Meetings to review).
|
|
52
|
+
function needsNames(m) {
|
|
53
|
+
var r = m && (m.voiceReview || m.review);
|
|
54
|
+
return !!(r && Number(r.unattributedVoices) > 0 && !r.humanTouched);
|
|
55
|
+
}
|
|
56
|
+
function meetingDate(m) {
|
|
57
|
+
var d = toDate(m && (m.date && m.time ? m.date + ' ' + m.time : m.date));
|
|
58
|
+
return d;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
var storyTimer = null;
|
|
62
|
+
var storiesAt = 0;
|
|
63
|
+
// The stories share the browser's 6 connections to the Mac with the pane in use, and four of their reads take 8 to
|
|
64
|
+
// 11 s on a busy Mac. They go through this lane, STORY_LANE at a time, so the pane always has connections free.
|
|
65
|
+
// Measured 2026-11-04 at 1440 px: with all 14 sent at once, a meeting opened 4 s after sign-in waited 10 to 14 s for
|
|
66
|
+
// its first read, and /api/health took 6.2 s. The unfolded Duo (about 1000 px) loads the stories the same way.
|
|
67
|
+
var STORY_LANE = 2, storyActive = 0, storyQueue = [];
|
|
68
|
+
function nextStory() { while (storyActive < STORY_LANE && storyQueue.length) storyQueue.shift()(); }
|
|
69
|
+
function storyApi(path, opts) {
|
|
70
|
+
return new Promise(function (resolve, reject) {
|
|
71
|
+
storyQueue.push(function () {
|
|
72
|
+
storyActive++;
|
|
73
|
+
api(path, opts).then(resolve, reject).then(function () { storyActive--; nextStory(); });
|
|
74
|
+
});
|
|
75
|
+
nextStory();
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// About 16 reads: never two runs at once, never more than one a minute, two at a time through storyApi, and never
|
|
79
|
+
// ahead of the pane the person just opened (Safari keeps 6 connections to the Mac over HTTP/1.1).
|
|
80
|
+
// On the closed Duo (below 600px) the stories show only inside the section menu, so they load
|
|
81
|
+
// when the menu opens rather than costing the pane its connections on every visit.
|
|
82
|
+
function loadStories(force) {
|
|
83
|
+
if (!force && W.isPhone()) return;
|
|
84
|
+
if (Date.now() - storiesAt < 60000) return;
|
|
85
|
+
storiesAt = Date.now();
|
|
86
|
+
var now = new Date();
|
|
87
|
+
var quiet = quietNow(now);
|
|
88
|
+
|
|
89
|
+
// Sessions and Today share the sessions list and Work's your move.
|
|
90
|
+
Promise.all([
|
|
91
|
+
soft(storyApi('/api/agent-sessions?limit=80&sort=updated')),
|
|
92
|
+
soft(storyApi('/api/work-board/your-move')),
|
|
93
|
+
soft(storyApi('/api/meetings/live-chunks'))
|
|
94
|
+
]).then(function (res) {
|
|
95
|
+
var rows = (res[0] && res[0].sessions) || [];
|
|
96
|
+
var moves = (res[1] && res[1].items) || [];
|
|
97
|
+
var live = (res[2] && res[2].sessions) || [];
|
|
98
|
+
// Control's rule (Models.swift isWorking / isWaiting) through the Sessions pane's own state:
|
|
99
|
+
// working is running; waiting is waiting or failed; warm-up sessions never count.
|
|
100
|
+
var real = rows.filter(function (s) { return !(W.isKeepWarm && W.isKeepWarm(s)); });
|
|
101
|
+
var stateOf = W.sessionState || function (s) { return s.running_active || s.agent_state === 'running' ? 'running' : s.agent_state === 'waiting' ? 'waiting' : 'recent'; };
|
|
102
|
+
var working = real.filter(function (s) { return stateOf(s) === 'running'; }).length;
|
|
103
|
+
var waiting = real.filter(function (s) { var st = stateOf(s); return st === 'waiting' || st === 'error'; }).length;
|
|
104
|
+
if (res[0]) {
|
|
105
|
+
if (!waiting && !working) setStory('sessions', 'No agents running', false);
|
|
106
|
+
else setStory('sessions', [waiting ? waiting + ' waiting on you' : '', working ? working + ' working' : ''].filter(Boolean).join(', '), waiting > 0);
|
|
107
|
+
} else setStory('sessions', FALLBACK.sessions, false);
|
|
108
|
+
|
|
109
|
+
var needs = waiting + moves.length;
|
|
110
|
+
var folded = quiet ? needs : 0;
|
|
111
|
+
// A fresh file is not proof of a recording: a meeting saved a minute ago still has one.
|
|
112
|
+
// Ask each recent session the way Today does (live-chunks read: not ended, active lately).
|
|
113
|
+
var recent = live.filter(function (s) { return Date.now() - (s.mtimeMs || 0) < 5 * 60000; }).slice(0, 3);
|
|
114
|
+
Promise.all(recent.map(function (f) {
|
|
115
|
+
return soft(storyApi('/api/meetings/live-chunks?sessionId=' + encodeURIComponent(f.sessionId) + '&since=1000000')).then(function (r) {
|
|
116
|
+
var read = r && r.read;
|
|
117
|
+
return !!(read && !read.ended && Date.now() - Number(read.lastActivityAt || 0) < 5 * 60000);
|
|
118
|
+
});
|
|
119
|
+
})).then(function (flags) {
|
|
120
|
+
var recordings = flags.filter(Boolean).length;
|
|
121
|
+
var waitNow = needs - folded;
|
|
122
|
+
var needText = waitNow > 0 ? (waitNow === 1 ? '1 needs you' : waitNow + ' need you')
|
|
123
|
+
: folded > 0 ? folded + ' can wait until tomorrow'
|
|
124
|
+
: (res[0] || res[1]) ? 'Nothing needs you' : "Couldn't read your Mac";
|
|
125
|
+
if (recordings > 0) setStory('today', [recordings + ' recording', waitNow > 0 ? needText : ''].filter(Boolean).join(', '), true);
|
|
126
|
+
else setStory('today', [needText, working ? working + ' running' : ''].filter(Boolean).join(', '), waitNow > 0);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Work: your move (minus the sessions already counted as waiting), and the older-to-sort count.
|
|
130
|
+
Promise.all([soft(storyApi('/api/work-intake')), soft(storyApi('/api/work-board'))]).then(function (w) {
|
|
131
|
+
var items = (w[0] && (w[0].items || w[0].suggestions)) || [];
|
|
132
|
+
// The local day, as Work's Sort uses (toISOString is UTC: after 6 PM Central it is tomorrow).
|
|
133
|
+
var today = now.getFullYear() + '-' + String(now.getMonth() + 1).padStart(2, '0') + '-' + String(now.getDate()).padStart(2, '0');
|
|
134
|
+
var olderIntake = items.filter(function (it) {
|
|
135
|
+
var st = it.status || it.state;
|
|
136
|
+
if (st && ['suggested', 'review', 'ask'].indexOf(st) < 0) return false;
|
|
137
|
+
var day = String((it.meeting && (it.meeting.filename || it.meeting.date)) || it.meetingFile || it.date || '').match(/\d{4}-\d{2}-\d{2}/);
|
|
138
|
+
return !day || day[0] !== today;
|
|
139
|
+
}).length;
|
|
140
|
+
var tasks = (w[1] && (w[1].tasks || w[1].cards)) || [];
|
|
141
|
+
var mentioned = tasks.filter(function (t) {
|
|
142
|
+
if (t.workStage !== 'mentioned' || t.checked) return false;
|
|
143
|
+
var ref = (t.meetingRefs && t.meetingRefs[0]) || (t.meetings && t.meetings[0]) || null;
|
|
144
|
+
var day = String((ref && (ref.filename || ref.date)) || '').match(/\d{4}-\d{2}-\d{2}/);
|
|
145
|
+
return !day || day[0] !== today;
|
|
146
|
+
}).length;
|
|
147
|
+
var older = w[0] || w[1] ? olderIntake + mentioned : null;
|
|
148
|
+
var needsWork = moves.length;
|
|
149
|
+
var foldedWork = quiet ? needsWork : 0;
|
|
150
|
+
var needsNow = Math.max(0, needsWork - foldedWork);
|
|
151
|
+
var bits = [];
|
|
152
|
+
if (needsNow > 0) bits.push(needsNow === 1 ? '1 needs you' : needsNow + ' need you');
|
|
153
|
+
if (foldedWork > 0) bits.push(foldedWork + ' can wait');
|
|
154
|
+
if (older) bits.push(older + ' older to sort');
|
|
155
|
+
if (bits.length) setStory('work', bits.join(', '), needsNow > 0);
|
|
156
|
+
else setStory('work', older == null || !res[1] ? FALLBACK.work : 'Nothing to sort', false);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Messages: the morning brief that reached the glasses today, else the last message today.
|
|
161
|
+
Promise.all([soft(storyApi('/api/morning-brief')), soft(storyApi('/api/sessions/today/all-messages?limit=5'))]).then(function (res) {
|
|
162
|
+
var runs = (res[0] && res[0].runs) || [];
|
|
163
|
+
var brief = runs.filter(function (r) { return r.status === 'completed'; })
|
|
164
|
+
.map(function (r) { return toDate(r.firedAt); }).filter(Boolean)
|
|
165
|
+
.sort(function (a, b) { return b - a; })[0];
|
|
166
|
+
if (brief && sameDay(brief, now)) return setStory('messages', 'Morning brief reached the glasses at ' + clock(brief), false);
|
|
167
|
+
var msgs = (res[1] && res[1].messages) || [];
|
|
168
|
+
var last = msgs.map(function (m) { return toDate(m.timestamp); }).filter(Boolean).sort(function (a, b) { return b - a; })[0];
|
|
169
|
+
if (last && sameDay(last, now)) return setStory('messages', 'Last from the glasses at ' + clock(last), false);
|
|
170
|
+
setStory('messages', FALLBACK.messages, false);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Speakers (TodayHome.things): each held voice counts one; today's meetings count their
|
|
174
|
+
// unnamed voices (up to three meetings); every other meeting with unnamed voices counts one.
|
|
175
|
+
Promise.all([soft(storyApi('/api/voice/held-groups')), soft(storyApi('/api/meetings?limit=30'))]).then(function (res) {
|
|
176
|
+
if (!res[0] && !res[1]) return setStory('speakers', FALLBACK.speakers, false);
|
|
177
|
+
var groups = (res[0] && res[0].groups) || [];
|
|
178
|
+
var meetings = ((res[1] && res[1].meetings) || []).filter(function (m) { return m.sessionId && needsNames(m); });
|
|
179
|
+
var n = groups.length, todayRows = 0;
|
|
180
|
+
meetings.forEach(function (m) {
|
|
181
|
+
var d = meetingDate(m);
|
|
182
|
+
if (todayRows < 3 && d && sameDay(d, now)) { todayRows += 1; n += Math.max(1, Number((m.voiceReview || m.review).unattributedVoices) || 1); }
|
|
183
|
+
else n += 1;
|
|
184
|
+
});
|
|
185
|
+
setStory('speakers', n > 0 ? (n === 1 ? '1 voice to name' : n + ' voices to name') : 'Every voice has a name', n > 0);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Meetings: reviews ready, then the next calendar event (it counts until an hour past its start).
|
|
189
|
+
Promise.all([soft(storyApi('/api/work-reviews')), soft(storyApi('/api/welcome-context'))]).then(function (res) {
|
|
190
|
+
var reviews = (res[0] && (res[0].reviews || res[0].items)) || [];
|
|
191
|
+
var ready = reviews.filter(function (r) { return r.status === 'ready'; }).length;
|
|
192
|
+
var ev = res[1] && res[1].nextEvent;
|
|
193
|
+
var start = ev && toDate(ev.time || ev.start || ev.startDate);
|
|
194
|
+
var bits = [];
|
|
195
|
+
if (ready > 0) bits.push(ready + ' ready to review');
|
|
196
|
+
if (start && Date.now() - start.getTime() < 3600000) bits.push((bits.length ? 'next at ' : 'Next at ') + clock(start));
|
|
197
|
+
setStory('meetings', bits.length ? bits.join(', ') : FALLBACK.meetings, false);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Threads: "N active, newest <name>". Newest is the unresolved thread seen most recently.
|
|
201
|
+
Promise.all([soft(storyApi('/api/context/status')), soft(storyApi('/api/threads?limit=50'))]).then(function (res) {
|
|
202
|
+
var t = res[0] && res[0].threads;
|
|
203
|
+
var active = t && t.available ? Number(t.active) || 0 : 0;
|
|
204
|
+
if (!active) return setStory('threads', FALLBACK.threads, false);
|
|
205
|
+
var list = ((res[1] && res[1].threads) || []).filter(function (x) { return !x.is_resolved; });
|
|
206
|
+
list.sort(function (a, b) { return String(b.last_seen || b.created_at || '').localeCompare(String(a.last_seen || a.created_at || '')); });
|
|
207
|
+
setStory('threads', active + ' active' + (list[0] && list[0].name ? ', newest ' + clip(list[0].name, 40) : ''), false);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// Memories (TodayHome.memoriesStory): n is the gated needs-you count (capped, from the
|
|
211
|
+
// bridge's status, which runs the same CLI Control's helper runs); total is the number of
|
|
212
|
+
// rows to review. "Next n of total" when there are more rows than n, else "n to review".
|
|
213
|
+
Promise.all([
|
|
214
|
+
soft(storyApi('/api/web-bridge/memories', { method: 'POST', body: { id: 'rail-status', op: 'status', args: {} } })),
|
|
215
|
+
soft(storyApi('/api/context/learning/review?limit=200'))
|
|
216
|
+
]).then(function (res) {
|
|
217
|
+
var n = res[0] && res[0].details ? res[0].details.learningToReview : null;
|
|
218
|
+
if (typeof n !== 'number') return setStory('memories', FALLBACK.memories, false);
|
|
219
|
+
if (n <= 0) return setStory('memories', 'Nothing to review', false);
|
|
220
|
+
var total = res[1] && Array.isArray(res[1].events) ? res[1].events.length : null;
|
|
221
|
+
setStory('memories', total != null && total > n ? 'Next ' + n + ' of ' + total : n + ' to review', true);
|
|
222
|
+
});
|
|
223
|
+
// Dictation lives on the Mac (its history and suggestions are local files).
|
|
224
|
+
setStory('dictation', FALLBACK.dictation, false);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// ── server line ───────────────────────────────────────
|
|
228
|
+
function setServer(ok) {
|
|
229
|
+
document.querySelectorAll('[data-host-dot]').forEach(function (d) { d.classList.toggle('ok', ok); d.classList.toggle('bad', !ok); });
|
|
230
|
+
document.querySelectorAll('[data-server-text]').forEach(function (t) { t.textContent = ok ? 'Server connected' : 'Server not reachable'; });
|
|
231
|
+
document.querySelectorAll('[data-server-line]').forEach(function (l) { l.classList.toggle('down', !ok); });
|
|
232
|
+
}
|
|
233
|
+
function checkServer() {
|
|
234
|
+
return api('/api/health').then(function (h) {
|
|
235
|
+
setServer(!!h && h.status !== 'down');
|
|
236
|
+
// 6.99.10: the same read tells the pinned COS chat whether Drop it is on, and refreshes the Messages badge.
|
|
237
|
+
if (W.cosChat) W.cosChat.fromHealth(h);
|
|
238
|
+
}, function () { setServer(false); });
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// ── navigation bar (Home, Back, breadcrumb, Settings) ──
|
|
242
|
+
function paintNavbar(r) {
|
|
243
|
+
var bar = $('navbar');
|
|
244
|
+
if (!bar) return;
|
|
245
|
+
var onToday = r.pane === 'today';
|
|
246
|
+
bar.classList.toggle('hidden', onToday);
|
|
247
|
+
document.body.classList.toggle('has-navbar', !onToday);
|
|
248
|
+
var crumbs = $('crumbs');
|
|
249
|
+
var section = r.pane === 'usage' ? 'Sessions' : (W.titles[r.pane] || '');
|
|
250
|
+
var detail = W.crumb();
|
|
251
|
+
var parts = ['<li class="crumb root">COS Control</li>'];
|
|
252
|
+
if (r.pane === 'settings') parts.push('<li class="crumb current">Settings</li>');
|
|
253
|
+
else {
|
|
254
|
+
parts.push('<li class="crumb' + (detail || r.pane === 'usage' ? ' dim' : ' current') + '">' + esc(section) + '</li>');
|
|
255
|
+
if (r.pane === 'usage') parts.push('<li class="crumb' + (detail ? ' dim' : ' current') + '">Usage</li>');
|
|
256
|
+
if (detail) parts.push('<li class="crumb current detail">' + esc(detail) + '</li>');
|
|
257
|
+
}
|
|
258
|
+
crumbs.innerHTML = parts.join('');
|
|
259
|
+
$('nav-back').disabled = onToday;
|
|
260
|
+
// The phone top bar names the detail too, so a reader says where it is.
|
|
261
|
+
var label = $('section-name');
|
|
262
|
+
if (label && detail && W.isPhone()) label.textContent = detail;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
document.addEventListener('click', function (e) {
|
|
266
|
+
if (e.target.closest('#section-btn')) loadStories(true);
|
|
267
|
+
var t = e.target.closest('#nav-home,#nav-back,#nav-settings');
|
|
268
|
+
if (!t) return;
|
|
269
|
+
if (t.id === 'nav-home') W.go('today');
|
|
270
|
+
else if (t.id === 'nav-back') W.goBack();
|
|
271
|
+
else W.go('settings');
|
|
272
|
+
});
|
|
273
|
+
document.addEventListener('keydown', function (e) {
|
|
274
|
+
if (!(e.metaKey || e.ctrlKey) || e.altKey) return;
|
|
275
|
+
var tag = (e.target && e.target.tagName) || '';
|
|
276
|
+
if (/^(INPUT|TEXTAREA|SELECT)$/.test(tag)) return;
|
|
277
|
+
// ⌘0 Today, ⌘1 to ⌘8 the panes in rail order, ⌘← Back, ⌘⇧H Home (Control's shortcuts).
|
|
278
|
+
var order = ['messages', 'speakers', 'meetings', 'memories', 'threads', 'sessions', 'work', 'dictation'];
|
|
279
|
+
if (e.key === '0') { e.preventDefault(); W.go('today'); }
|
|
280
|
+
else if (/^[1-8]$/.test(e.key)) { e.preventDefault(); W.go(order[Number(e.key) - 1]); }
|
|
281
|
+
else if (e.key === 'ArrowLeft') { e.preventDefault(); W.goBack(); }
|
|
282
|
+
else if (e.shiftKey && (e.key === 'h' || e.key === 'H')) { e.preventDefault(); W.go('today'); }
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
W.onRoute(paintNavbar);
|
|
286
|
+
W.onShell(function () {
|
|
287
|
+
Object.keys(FALLBACK).forEach(function (k) { setStory(k, FALLBACK[k], false); });
|
|
288
|
+
setTimeout(function () { loadStories(); checkServer(); }, 2500);
|
|
289
|
+
clearInterval(storyTimer);
|
|
290
|
+
storyTimer = setInterval(function () { if (!document.hidden) { loadStories(); checkServer(); } }, 5 * 60000);
|
|
291
|
+
});
|
|
292
|
+
document.addEventListener('visibilitychange', function () { if (!document.hidden && document.querySelector('#app-shell:not(.hidden)')) { loadStories(); checkServer(); } });
|
|
293
|
+
W.refreshStories = loadStories;
|
|
294
|
+
})();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* Runs before first paint so the page never flashes the wrong theme. Choice: system | light | dark. */
|
|
2
|
+
(function () {
|
|
3
|
+
var KEY = 'cos_web_theme';
|
|
4
|
+
var media = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;
|
|
5
|
+
function read() { try { var v = localStorage.getItem(KEY); return v === 'light' || v === 'dark' ? v : 'system'; } catch (_e) { return 'system'; } }
|
|
6
|
+
function resolve(choice) { return choice === 'system' ? (media && media.matches ? 'dark' : 'light') : choice; }
|
|
7
|
+
function apply(choice) {
|
|
8
|
+
var mode = resolve(choice);
|
|
9
|
+
document.documentElement.setAttribute('data-theme', mode);
|
|
10
|
+
var frame = document.getElementById('memories-frame');
|
|
11
|
+
if (frame) frame.style.colorScheme = mode;
|
|
12
|
+
return mode;
|
|
13
|
+
}
|
|
14
|
+
window.CosTheme = {
|
|
15
|
+
choice: read,
|
|
16
|
+
mode: function () { return resolve(read()); },
|
|
17
|
+
set: function (choice) {
|
|
18
|
+
try { if (choice === 'system') localStorage.removeItem(KEY); else localStorage.setItem(KEY, choice); } catch (_e) {}
|
|
19
|
+
return apply(choice);
|
|
20
|
+
},
|
|
21
|
+
apply: function () { return apply(read()); }
|
|
22
|
+
};
|
|
23
|
+
apply(read());
|
|
24
|
+
if (media && media.addEventListener) media.addEventListener('change', function () { if (read() === 'system') apply('system'); });
|
|
25
|
+
})();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*! COS Control Web QR encoder: the encoder of qrcode 1.5.4 (MIT, (c) Ryan Day, https://github.com/soldair/node-qrcode)
|
|
2
|
+
with dijkstrajs (MIT, (c) Thomas Cort), bundled by esbuild into one file the page serves itself
|
|
3
|
+
(CSP script-src self). Exposes window.COSQR.matrix(text) -> { size, data } and nothing else. */
|
|
4
|
+
(()=>{var g=(n,t)=>()=>{try{return t||n((t={exports:{}}).exports,t),t.exports}catch(e){throw t=0,e}};var B=g(I=>{var rt,pe=[0,26,44,70,100,134,172,196,242,292,346,404,466,532,581,655,733,815,901,991,1085,1156,1258,1364,1474,1588,1706,1828,1921,2051,2185,2323,2465,2611,2761,2876,3034,3196,3362,3532,3706];I.getSymbolSize=function(t){if(!t)throw new Error('"version" cannot be null or undefined');if(t<1||t>40)throw new Error('"version" should be in range from 1 to 40');return t*4+17};I.getSymbolTotalCodewords=function(t){return pe[t]};I.getBCHDigit=function(n){let t=0;for(;n!==0;)t++,n>>>=1;return t};I.setToSJISFunction=function(t){if(typeof t!="function")throw new Error('"toSJISFunc" is not a valid function.');rt=t};I.isKanjiModeEnabled=function(){return typeof rt!="undefined"};I.toSJIS=function(t){return rt(t)}});var Y=g(w=>{w.L={bit:1};w.M={bit:0};w.Q={bit:3};w.H={bit:2};function we(n){if(typeof n!="string")throw new Error("Param is not a string");switch(n.toLowerCase()){case"l":case"low":return w.L;case"m":case"medium":return w.M;case"q":case"quartile":return w.Q;case"h":case"high":return w.H;default:throw new Error("Unknown EC Level: "+n)}}w.isValid=function(t){return t&&typeof t.bit!="undefined"&&t.bit>=0&&t.bit<4};w.from=function(t,e){if(w.isValid(t))return t;try{return we(t)}catch(r){return e}}});var It=g((un,Tt)=>{function Nt(){this.buffer=[],this.length=0}Nt.prototype={get:function(n){let t=Math.floor(n/8);return(this.buffer[t]>>>7-n%8&1)===1},put:function(n,t){for(let e=0;e<t;e++)this.putBit((n>>>t-e-1&1)===1)},getLengthInBits:function(){return this.length},putBit:function(n){let t=Math.floor(this.length/8);this.buffer.length<=t&&this.buffer.push(0),n&&(this.buffer[t]|=128>>>this.length%8),this.length++}};Tt.exports=Nt});var St=g((cn,Mt)=>{function D(n){if(!n||n<1)throw new Error("BitMatrix size must be defined and greater than 0");this.size=n,this.data=new Uint8Array(n*n),this.reservedBit=new Uint8Array(n*n)}D.prototype.set=function(n,t,e,r){let o=n*this.size+t;this.data[o]=e,r&&(this.reservedBit[o]=!0)};D.prototype.get=function(n,t){return this.data[n*this.size+t]};D.prototype.xor=function(n,t,e){this.data[n*this.size+t]^=e};D.prototype.isReserved=function(n,t){return this.reservedBit[n*this.size+t]};Mt.exports=D});var Pt=g(G=>{var Ee=B().getSymbolSize;G.getRowColCoords=function(t){if(t===1)return[];let e=Math.floor(t/7)+2,r=Ee(t),o=r===145?26:Math.ceil((r-13)/(2*e-2))*2,i=[r-7];for(let s=1;s<e-1;s++)i[s]=i[s-1]-o;return i.push(6),i.reverse()};G.getPositions=function(t){let e=[],r=G.getRowColCoords(t),o=r.length;for(let i=0;i<o;i++)for(let s=0;s<o;s++)i===0&&s===0||i===0&&s===o-1||i===o-1&&s===0||e.push([r[i],r[s]]);return e}});var Lt=g(Rt=>{var Ce=B().getSymbolSize,bt=7;Rt.getPositions=function(t){let e=Ce(t);return[[0,0],[e-bt,0],[0,e-bt]]}});var _t=g(f=>{f.Patterns={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var M={N1:3,N2:3,N3:40,N4:10};f.isValid=function(t){return t!=null&&t!==""&&!isNaN(t)&&t>=0&&t<=7};f.from=function(t){return f.isValid(t)?parseInt(t,10):void 0};f.getPenaltyN1=function(t){let e=t.size,r=0,o=0,i=0,s=null,u=null;for(let c=0;c<e;c++){o=i=0,s=u=null;for(let l=0;l<e;l++){let d=t.get(c,l);d===s?o++:(o>=5&&(r+=M.N1+(o-5)),s=d,o=1),d=t.get(l,c),d===u?i++:(i>=5&&(r+=M.N1+(i-5)),u=d,i=1)}o>=5&&(r+=M.N1+(o-5)),i>=5&&(r+=M.N1+(i-5))}return r};f.getPenaltyN2=function(t){let e=t.size,r=0;for(let o=0;o<e-1;o++)for(let i=0;i<e-1;i++){let s=t.get(o,i)+t.get(o,i+1)+t.get(o+1,i)+t.get(o+1,i+1);(s===4||s===0)&&r++}return r*M.N2};f.getPenaltyN3=function(t){let e=t.size,r=0,o=0,i=0;for(let s=0;s<e;s++){o=i=0;for(let u=0;u<e;u++)o=o<<1&2047|t.get(s,u),u>=10&&(o===1488||o===93)&&r++,i=i<<1&2047|t.get(u,s),u>=10&&(i===1488||i===93)&&r++}return r*M.N3};f.getPenaltyN4=function(t){let e=0,r=t.data.length;for(let i=0;i<r;i++)e+=t.data[i];return Math.abs(Math.ceil(e*100/r/5)-10)*M.N4};function me(n,t,e){switch(n){case f.Patterns.PATTERN000:return(t+e)%2===0;case f.Patterns.PATTERN001:return t%2===0;case f.Patterns.PATTERN010:return e%3===0;case f.Patterns.PATTERN011:return(t+e)%3===0;case f.Patterns.PATTERN100:return(Math.floor(t/2)+Math.floor(e/3))%2===0;case f.Patterns.PATTERN101:return t*e%2+t*e%3===0;case f.Patterns.PATTERN110:return(t*e%2+t*e%3)%2===0;case f.Patterns.PATTERN111:return(t*e%3+(t+e)%2)%2===0;default:throw new Error("bad maskPattern:"+n)}}f.applyMask=function(t,e){let r=e.size;for(let o=0;o<r;o++)for(let i=0;i<r;i++)e.isReserved(i,o)||e.xor(i,o,me(t,i,o))};f.getBestMask=function(t,e){let r=Object.keys(f.Patterns).length,o=0,i=1/0;for(let s=0;s<r;s++){e(s),f.applyMask(s,t);let u=f.getPenaltyN1(t)+f.getPenaltyN2(t)+f.getPenaltyN3(t)+f.getPenaltyN4(t);f.applyMask(s,t),u<i&&(i=u,o=s)}return o}});var it=g(ot=>{var A=Y(),O=[1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,4,1,2,4,4,2,4,4,4,2,4,6,5,2,4,6,6,2,5,8,8,4,5,8,8,4,5,8,11,4,8,10,11,4,9,12,16,4,9,16,16,6,10,12,18,6,10,17,16,6,11,16,19,6,13,18,21,7,14,21,25,8,16,20,25,8,17,23,25,9,17,23,34,9,18,25,30,10,20,27,32,12,21,29,35,12,23,34,37,12,25,34,40,13,26,35,42,14,28,38,45,15,29,40,48,16,31,43,51,17,33,45,54,18,35,48,57,19,37,51,60,19,38,53,63,20,40,56,66,21,43,59,70,22,45,62,74,24,47,65,77,25,49,68,81],Q=[7,10,13,17,10,16,22,28,15,26,36,44,20,36,52,64,26,48,72,88,36,64,96,112,40,72,108,130,48,88,132,156,60,110,160,192,72,130,192,224,80,150,224,264,96,176,260,308,104,198,288,352,120,216,320,384,132,240,360,432,144,280,408,480,168,308,448,532,180,338,504,588,196,364,546,650,224,416,600,700,224,442,644,750,252,476,690,816,270,504,750,900,300,560,810,960,312,588,870,1050,336,644,952,1110,360,700,1020,1200,390,728,1050,1260,420,784,1140,1350,450,812,1200,1440,480,868,1290,1530,510,924,1350,1620,540,980,1440,1710,570,1036,1530,1800,570,1064,1590,1890,600,1120,1680,1980,630,1204,1770,2100,660,1260,1860,2220,720,1316,1950,2310,750,1372,2040,2430];ot.getBlocksCount=function(t,e){switch(e){case A.L:return O[(t-1)*4+0];case A.M:return O[(t-1)*4+1];case A.Q:return O[(t-1)*4+2];case A.H:return O[(t-1)*4+3];default:return}};ot.getTotalCodewordsCount=function(t,e){switch(e){case A.L:return Q[(t-1)*4+0];case A.M:return Q[(t-1)*4+1];case A.Q:return Q[(t-1)*4+2];case A.H:return Q[(t-1)*4+3];default:return}}});var xt=g($=>{var F=new Uint8Array(512),j=new Uint8Array(256);(function(){let t=1;for(let e=0;e<255;e++)F[e]=t,j[t]=e,t<<=1,t&256&&(t^=285);for(let e=255;e<512;e++)F[e]=F[e-255]})();$.log=function(t){if(t<1)throw new Error("log("+t+")");return j[t]};$.exp=function(t){return F[t]};$.mul=function(t,e){return t===0||e===0?0:F[j[t]+j[e]]}});var Ut=g(z=>{var st=xt();z.mul=function(t,e){let r=new Uint8Array(t.length+e.length-1);for(let o=0;o<t.length;o++)for(let i=0;i<e.length;i++)r[o+i]^=st.mul(t[o],e[i]);return r};z.mod=function(t,e){let r=new Uint8Array(t);for(;r.length-e.length>=0;){let o=r[0];for(let s=0;s<e.length;s++)r[s]^=st.mul(e[s],o);let i=0;for(;i<r.length&&r[i]===0;)i++;r=r.slice(i)}return r};z.generateECPolynomial=function(t){let e=new Uint8Array([1]);for(let r=0;r<t;r++)e=z.mul(e,new Uint8Array([1,st.exp(r)]));return e}});var Ft=g((pn,Dt)=>{var qt=Ut();function ut(n){this.genPoly=void 0,this.degree=n,this.degree&&this.initialize(this.degree)}ut.prototype.initialize=function(t){this.degree=t,this.genPoly=qt.generateECPolynomial(this.degree)};ut.prototype.encode=function(t){if(!this.genPoly)throw new Error("Encoder not initialized");let e=new Uint8Array(t.length+this.degree);e.set(t);let r=qt.mod(e,this.genPoly),o=this.degree-r.length;if(o>0){let i=new Uint8Array(this.degree);return i.set(r,o),i}return r};Dt.exports=ut});var ct=g(zt=>{zt.isValid=function(t){return!isNaN(t)&&t>=1&&t<=40}});var at=g(m=>{var kt="[0-9]+",ye="[A-Z $%*+\\-./:]+",k="(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+";k=k.replace(/u/g,"\\u");var Be="(?:(?![A-Z0-9 $%*+\\-./:]|"+k+`)(?:.|[\r
|
|
5
|
+
]))+`;m.KANJI=new RegExp(k,"g");m.BYTE_KANJI=new RegExp("[^A-Z0-9 $%*+\\-./:]+","g");m.BYTE=new RegExp(Be,"g");m.NUMERIC=new RegExp(kt,"g");m.ALPHANUMERIC=new RegExp(ye,"g");var Ae=new RegExp("^"+k+"$"),Ne=new RegExp("^"+kt+"$"),Te=new RegExp("^[A-Z0-9 $%*+\\-./:]+$");m.testKanji=function(t){return Ae.test(t)};m.testNumeric=function(t){return Ne.test(t)};m.testAlphanumeric=function(t){return Te.test(t)}});var N=g(h=>{var Ie=ct(),lt=at();h.NUMERIC={id:"Numeric",bit:1,ccBits:[10,12,14]};h.ALPHANUMERIC={id:"Alphanumeric",bit:2,ccBits:[9,11,13]};h.BYTE={id:"Byte",bit:4,ccBits:[8,16,16]};h.KANJI={id:"Kanji",bit:8,ccBits:[8,10,12]};h.MIXED={bit:-1};h.getCharCountIndicator=function(t,e){if(!t.ccBits)throw new Error("Invalid mode: "+t);if(!Ie.isValid(e))throw new Error("Invalid version: "+e);return e>=1&&e<10?t.ccBits[0]:e<27?t.ccBits[1]:t.ccBits[2]};h.getBestModeForData=function(t){return lt.testNumeric(t)?h.NUMERIC:lt.testAlphanumeric(t)?h.ALPHANUMERIC:lt.testKanji(t)?h.KANJI:h.BYTE};h.toString=function(t){if(t&&t.id)return t.id;throw new Error("Invalid mode")};h.isValid=function(t){return t&&t.bit&&t.ccBits};function Me(n){if(typeof n!="string")throw new Error("Param is not a string");switch(n.toLowerCase()){case"numeric":return h.NUMERIC;case"alphanumeric":return h.ALPHANUMERIC;case"kanji":return h.KANJI;case"byte":return h.BYTE;default:throw new Error("Unknown mode: "+n)}}h.from=function(t,e){if(h.isValid(t))return t;try{return Me(t)}catch(r){return e}}});var Yt=g(S=>{var Z=B(),Se=it(),Vt=Y(),T=N(),ft=ct(),Kt=7973,Ht=Z.getBCHDigit(Kt);function Pe(n,t,e){for(let r=1;r<=40;r++)if(t<=S.getCapacity(r,e,n))return r}function Jt(n,t){return T.getCharCountIndicator(n,t)+4}function be(n,t){let e=0;return n.forEach(function(r){let o=Jt(r.mode,t);e+=o+r.getBitsLength()}),e}function Re(n,t){for(let e=1;e<=40;e++)if(be(n,e)<=S.getCapacity(e,t,T.MIXED))return e}S.from=function(t,e){return ft.isValid(t)?parseInt(t,10):e};S.getCapacity=function(t,e,r){if(!ft.isValid(t))throw new Error("Invalid QR Code version");typeof r=="undefined"&&(r=T.BYTE);let o=Z.getSymbolTotalCodewords(t),i=Se.getTotalCodewordsCount(t,e),s=(o-i)*8;if(r===T.MIXED)return s;let u=s-Jt(r,t);switch(r){case T.NUMERIC:return Math.floor(u/10*3);case T.ALPHANUMERIC:return Math.floor(u/11*2);case T.KANJI:return Math.floor(u/13);case T.BYTE:default:return Math.floor(u/8)}};S.getBestVersionForData=function(t,e){let r,o=Vt.from(e,Vt.M);if(Array.isArray(t)){if(t.length>1)return Re(t,o);if(t.length===0)return 1;r=t[0]}else r=t;return Pe(r.mode,r.getLength(),o)};S.getEncodedBits=function(t){if(!ft.isValid(t)||t<7)throw new Error("Invalid QR Code version");let e=t<<12;for(;Z.getBCHDigit(e)-Ht>=0;)e^=Kt<<Z.getBCHDigit(e)-Ht;return t<<12|e}});var jt=g(Qt=>{var gt=B(),Ot=1335,Le=21522,Gt=gt.getBCHDigit(Ot);Qt.getEncodedBits=function(t,e){let r=t.bit<<3|e,o=r<<10;for(;gt.getBCHDigit(o)-Gt>=0;)o^=Ot<<gt.getBCHDigit(o)-Gt;return(r<<10|o)^Le}});var Zt=g((Bn,$t)=>{var _e=N();function L(n){this.mode=_e.NUMERIC,this.data=n.toString()}L.getBitsLength=function(t){return 10*Math.floor(t/3)+(t%3?t%3*3+1:0)};L.prototype.getLength=function(){return this.data.length};L.prototype.getBitsLength=function(){return L.getBitsLength(this.data.length)};L.prototype.write=function(t){let e,r,o;for(e=0;e+3<=this.data.length;e+=3)r=this.data.substr(e,3),o=parseInt(r,10),t.put(o,10);let i=this.data.length-e;i>0&&(r=this.data.substr(e),o=parseInt(r,10),t.put(o,i*3+1))};$t.exports=L});var vt=g((An,Xt)=>{var xe=N(),dt=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"," ","$","%","*","+","-",".","/",":"];function _(n){this.mode=xe.ALPHANUMERIC,this.data=n}_.getBitsLength=function(t){return 11*Math.floor(t/2)+6*(t%2)};_.prototype.getLength=function(){return this.data.length};_.prototype.getBitsLength=function(){return _.getBitsLength(this.data.length)};_.prototype.write=function(t){let e;for(e=0;e+2<=this.data.length;e+=2){let r=dt.indexOf(this.data[e])*45;r+=dt.indexOf(this.data[e+1]),t.put(r,11)}this.data.length%2&&t.put(dt.indexOf(this.data[e]),6)};Xt.exports=_});var te=g((Nn,Wt)=>{var Ue=N();function x(n){this.mode=Ue.BYTE,typeof n=="string"?this.data=new TextEncoder().encode(n):this.data=new Uint8Array(n)}x.getBitsLength=function(t){return t*8};x.prototype.getLength=function(){return this.data.length};x.prototype.getBitsLength=function(){return x.getBitsLength(this.data.length)};x.prototype.write=function(n){for(let t=0,e=this.data.length;t<e;t++)n.put(this.data[t],8)};Wt.exports=x});var ne=g((Tn,ee)=>{var qe=N(),De=B();function U(n){this.mode=qe.KANJI,this.data=n}U.getBitsLength=function(t){return t*13};U.prototype.getLength=function(){return this.data.length};U.prototype.getBitsLength=function(){return U.getBitsLength(this.data.length)};U.prototype.write=function(n){let t;for(t=0;t<this.data.length;t++){let e=De.toSJIS(this.data[t]);if(e>=33088&&e<=40956)e-=33088;else if(e>=57408&&e<=60351)e-=49472;else throw new Error("Invalid SJIS character: "+this.data[t]+`
|
|
6
|
+
Make sure your charset is UTF-8`);e=(e>>>8&255)*192+(e&255),n.put(e,13)}};ee.exports=U});var re=g((In,ht)=>{"use strict";var V={single_source_shortest_paths:function(n,t,e){var r={},o={};o[t]=0;var i=V.PriorityQueue.make();i.push(t,0);for(var s,u,c,l,d,y,p,J,P;!i.empty();){s=i.pop(),u=s.value,l=s.cost,d=n[u]||{};for(c in d)d.hasOwnProperty(c)&&(y=d[c],p=l+y,J=o[c],P=typeof o[c]=="undefined",(P||J>p)&&(o[c]=p,i.push(c,p),r[c]=u))}if(typeof e!="undefined"&&typeof o[e]=="undefined"){var b=["Could not find a path from ",t," to ",e,"."].join("");throw new Error(b)}return r},extract_shortest_path_from_predecessor_list:function(n,t){for(var e=[],r=t,o;r;)e.push(r),o=n[r],r=n[r];return e.reverse(),e},find_path:function(n,t,e){var r=V.single_source_shortest_paths(n,t,e);return V.extract_shortest_path_from_predecessor_list(r,e)},PriorityQueue:{make:function(n){var t=V.PriorityQueue,e={},r;n=n||{};for(r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e.queue=[],e.sorter=n.sorter||t.default_sorter,e},default_sorter:function(n,t){return n.cost-t.cost},push:function(n,t){var e={value:n,cost:t};this.queue.push(e),this.queue.sort(this.sorter)},pop:function(){return this.queue.shift()},empty:function(){return this.queue.length===0}}};typeof ht!="undefined"&&(ht.exports=V)});var fe=g(q=>{var a=N(),se=Zt(),ue=vt(),ce=te(),ae=ne(),H=at(),X=B(),Fe=re();function oe(n){return unescape(encodeURIComponent(n)).length}function K(n,t,e){let r=[],o;for(;(o=n.exec(e))!==null;)r.push({data:o[0],index:o.index,mode:t,length:o[0].length});return r}function le(n){let t=K(H.NUMERIC,a.NUMERIC,n),e=K(H.ALPHANUMERIC,a.ALPHANUMERIC,n),r,o;return X.isKanjiModeEnabled()?(r=K(H.BYTE,a.BYTE,n),o=K(H.KANJI,a.KANJI,n)):(r=K(H.BYTE_KANJI,a.BYTE,n),o=[]),t.concat(e,r,o).sort(function(s,u){return s.index-u.index}).map(function(s){return{data:s.data,mode:s.mode,length:s.length}})}function pt(n,t){switch(t){case a.NUMERIC:return se.getBitsLength(n);case a.ALPHANUMERIC:return ue.getBitsLength(n);case a.KANJI:return ae.getBitsLength(n);case a.BYTE:return ce.getBitsLength(n)}}function ze(n){return n.reduce(function(t,e){let r=t.length-1>=0?t[t.length-1]:null;return r&&r.mode===e.mode?(t[t.length-1].data+=e.data,t):(t.push(e),t)},[])}function ke(n){let t=[];for(let e=0;e<n.length;e++){let r=n[e];switch(r.mode){case a.NUMERIC:t.push([r,{data:r.data,mode:a.ALPHANUMERIC,length:r.length},{data:r.data,mode:a.BYTE,length:r.length}]);break;case a.ALPHANUMERIC:t.push([r,{data:r.data,mode:a.BYTE,length:r.length}]);break;case a.KANJI:t.push([r,{data:r.data,mode:a.BYTE,length:oe(r.data)}]);break;case a.BYTE:t.push([{data:r.data,mode:a.BYTE,length:oe(r.data)}])}}return t}function Ve(n,t){let e={},r={start:{}},o=["start"];for(let i=0;i<n.length;i++){let s=n[i],u=[];for(let c=0;c<s.length;c++){let l=s[c],d=""+i+c;u.push(d),e[d]={node:l,lastCount:0},r[d]={};for(let y=0;y<o.length;y++){let p=o[y];e[p]&&e[p].node.mode===l.mode?(r[p][d]=pt(e[p].lastCount+l.length,l.mode)-pt(e[p].lastCount,l.mode),e[p].lastCount+=l.length):(e[p]&&(e[p].lastCount=l.length),r[p][d]=pt(l.length,l.mode)+4+a.getCharCountIndicator(l.mode,t))}}o=u}for(let i=0;i<o.length;i++)r[o[i]].end=0;return{map:r,table:e}}function ie(n,t){let e,r=a.getBestModeForData(n);if(e=a.from(t,r),e!==a.BYTE&&e.bit<r.bit)throw new Error('"'+n+'" cannot be encoded with mode '+a.toString(e)+`.
|
|
7
|
+
Suggested mode is: `+a.toString(r));switch(e===a.KANJI&&!X.isKanjiModeEnabled()&&(e=a.BYTE),e){case a.NUMERIC:return new se(n);case a.ALPHANUMERIC:return new ue(n);case a.KANJI:return new ae(n);case a.BYTE:return new ce(n)}}q.fromArray=function(t){return t.reduce(function(e,r){return typeof r=="string"?e.push(ie(r,null)):r.data&&e.push(ie(r.data,r.mode)),e},[])};q.fromString=function(t,e){let r=le(t,X.isKanjiModeEnabled()),o=ke(r),i=Ve(o,e),s=Fe.find_path(i.map,"start","end"),u=[];for(let c=1;c<s.length-1;c++)u.push(i.table[s[c]].node);return q.fromArray(ze(u))};q.rawSplit=function(t){return q.fromArray(le(t,X.isKanjiModeEnabled()))}});var de=g(ge=>{var W=B(),wt=Y(),He=It(),Ke=St(),Je=Pt(),Ye=Lt(),mt=_t(),yt=it(),Ge=Ft(),v=Yt(),Oe=jt(),Qe=N(),Et=fe();function je(n,t){let e=n.size,r=Ye.getPositions(t);for(let o=0;o<r.length;o++){let i=r[o][0],s=r[o][1];for(let u=-1;u<=7;u++)if(!(i+u<=-1||e<=i+u))for(let c=-1;c<=7;c++)s+c<=-1||e<=s+c||(u>=0&&u<=6&&(c===0||c===6)||c>=0&&c<=6&&(u===0||u===6)||u>=2&&u<=4&&c>=2&&c<=4?n.set(i+u,s+c,!0,!0):n.set(i+u,s+c,!1,!0))}}function $e(n){let t=n.size;for(let e=8;e<t-8;e++){let r=e%2===0;n.set(e,6,r,!0),n.set(6,e,r,!0)}}function Ze(n,t){let e=Je.getPositions(t);for(let r=0;r<e.length;r++){let o=e[r][0],i=e[r][1];for(let s=-2;s<=2;s++)for(let u=-2;u<=2;u++)s===-2||s===2||u===-2||u===2||s===0&&u===0?n.set(o+s,i+u,!0,!0):n.set(o+s,i+u,!1,!0)}}function Xe(n,t){let e=n.size,r=v.getEncodedBits(t),o,i,s;for(let u=0;u<18;u++)o=Math.floor(u/3),i=u%3+e-8-3,s=(r>>u&1)===1,n.set(o,i,s,!0),n.set(i,o,s,!0)}function Ct(n,t,e){let r=n.size,o=Oe.getEncodedBits(t,e),i,s;for(i=0;i<15;i++)s=(o>>i&1)===1,i<6?n.set(i,8,s,!0):i<8?n.set(i+1,8,s,!0):n.set(r-15+i,8,s,!0),i<8?n.set(8,r-i-1,s,!0):i<9?n.set(8,15-i-1+1,s,!0):n.set(8,15-i-1,s,!0);n.set(r-8,8,1,!0)}function ve(n,t){let e=n.size,r=-1,o=e-1,i=7,s=0;for(let u=e-1;u>0;u-=2)for(u===6&&u--;;){for(let c=0;c<2;c++)if(!n.isReserved(o,u-c)){let l=!1;s<t.length&&(l=(t[s]>>>i&1)===1),n.set(o,u-c,l),i--,i===-1&&(s++,i=7)}if(o+=r,o<0||e<=o){o-=r,r=-r;break}}}function We(n,t,e){let r=new He;e.forEach(function(c){r.put(c.mode.bit,4),r.put(c.getLength(),Qe.getCharCountIndicator(c.mode,n)),c.write(r)});let o=W.getSymbolTotalCodewords(n),i=yt.getTotalCodewordsCount(n,t),s=(o-i)*8;for(r.getLengthInBits()+4<=s&&r.put(0,4);r.getLengthInBits()%8!==0;)r.putBit(0);let u=(s-r.getLengthInBits())/8;for(let c=0;c<u;c++)r.put(c%2?17:236,8);return tn(r,n,t)}function tn(n,t,e){let r=W.getSymbolTotalCodewords(t),o=yt.getTotalCodewordsCount(t,e),i=r-o,s=yt.getBlocksCount(t,e),u=r%s,c=s-u,l=Math.floor(r/s),d=Math.floor(i/s),y=d+1,p=l-d,J=new Ge(p),P=0,b=new Array(s),Bt=new Array(s),tt=0,he=new Uint8Array(n.buffer);for(let R=0;R<s;R++){let nt=R<c?d:y;b[R]=he.slice(P,P+nt),Bt[R]=J.encode(b[R]),P+=nt,tt=Math.max(tt,nt)}let et=new Uint8Array(r),At=0,E,C;for(E=0;E<tt;E++)for(C=0;C<s;C++)E<b[C].length&&(et[At++]=b[C][E]);for(E=0;E<p;E++)for(C=0;C<s;C++)et[At++]=Bt[C][E];return et}function en(n,t,e,r){let o;if(Array.isArray(n))o=Et.fromArray(n);else if(typeof n=="string"){let l=t;if(!l){let d=Et.rawSplit(n);l=v.getBestVersionForData(d,e)}o=Et.fromString(n,l||40)}else throw new Error("Invalid data");let i=v.getBestVersionForData(o,e);if(!i)throw new Error("The amount of data is too big to be stored in a QR Code");if(!t)t=i;else if(t<i)throw new Error(`
|
|
8
|
+
The chosen QR Code version cannot contain this amount of data.
|
|
9
|
+
Minimum version required to store current data is: `+i+`.
|
|
10
|
+
`);let s=We(t,e,o),u=W.getSymbolSize(t),c=new Ke(u);return je(c,t),$e(c),Ze(c,t),Ct(c,e,0),t>=7&&Xe(c,t),ve(c,s),isNaN(r)&&(r=mt.getBestMask(c,Ct.bind(null,c,e))),mt.applyMask(r,c),Ct(c,e,r),{modules:c,version:t,errorCorrectionLevel:e,maskPattern:r,segments:o}}ge.create=function(t,e){if(typeof t=="undefined"||t==="")throw new Error("No input text");let r=wt.M,o,i;return typeof e!="undefined"&&(r=wt.from(e.errorCorrectionLevel,wt.M),o=v.from(e.version),i=mt.from(e.maskPattern),e.toSJISFunc&&W.setToSJISFunction(e.toSJISFunc)),en(t,o,r,i)}});var nn=de();window.COSQR={matrix:function(n){let t=nn.create(String(n),{errorCorrectionLevel:"M"});return{size:t.modules.size,data:Array.prototype.slice.call(t.modules.data)}}};})();
|