dsh-aha-tutor 1.0.0 → 1.2.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/AGENTS.md +5 -3
- package/CHANGELOG.md +28 -0
- package/README.en.md +6 -5
- package/README.md +7 -6
- package/THIRD_PARTY_NOTICES.md +9 -0
- package/assets/fonts/OFL-Caveat.txt +93 -0
- package/assets/fonts/OFL-LXGWWenKaiGB.txt +94 -0
- package/assets/fonts/caveat-latin-d0b7b931.woff2 +0 -0
- package/assets/fonts/wenkai-gb-0-88f1a875.woff2 +0 -0
- package/assets/fonts/wenkai-gb-1-78a38e72.woff2 +0 -0
- package/assets/fonts/wenkai-gb-2-2a649892.woff2 +0 -0
- package/assets/fonts/wenkai-gb-3-6949c050.woff2 +0 -0
- package/assets/fonts/wenkai-gb-4-375dc3b3.woff2 +0 -0
- package/assets/fonts/wenkai-gb-5-d0359bbc.woff2 +0 -0
- package/assets/fonts/wenkai-gb-6-a238b41c.woff2 +0 -0
- package/docs/guide.zh-CN.md +16 -6
- package/lib/agent.js +1 -1
- package/lib/client.js +73 -32
- package/lib/index.js +611 -118
- package/lib/{runtime-CiA2I7-X.js → runtime-ywaTyu56.js} +96 -9
- package/package.json +2 -1
- package/samples/bayes-thinking.aha-course.json +51 -51
- package/samples/harmonic-motion.aha-course.json +56 -56
package/lib/index.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as intakeSummary, A as emptyProgress, B as passageRange, C as summaryPrompt, D as generateText, E as generateSteps, F as readMaterials, G as recommendNext, H as applyEvidence, I as readProfile, J as conceptIndex, K as boardToPlainText, L as readProgress, M as materialImages, N as materialsSummary, O as streamCounter, P as passagesFor, Q as insertLesson, R as documentParts, S as shortPrompt, T as generateJson, U as createConceptState, V as spreadPassages, W as masteryPercent, X as findLesson, Y as courseProgress, Z as flattenLessons, _ as projectsPrompt, a as blueprintPrompt, at as normalizePractice, b as reexplainPrompt, c as digestPartPrompt, ct as outlineForPrompt, d as gradePrompt, dt as assertId, et as lessonAfter, f as lessonPrompt, ft as newId, g as projectReviewPrompt, h as profilePrompt, i as assistPrompt, it as normalizeCheatsheet, j as masteryFor, k as EMPTY_PROFILE, l as digestPrompt, lt as safeRelativePath, m as practicePrompt, n as publishRuntime, nt as normalizeBlueprint, o as cheatsheetPrompt, ot as normalizeProject, p as materialBriefPrompt, q as normalizeBoard, r as askPrompt, rt as normalizeCards, s as detectLanguage, st as normalizeQuestionnaire, tt as nextLesson, u as flashcardsPrompt, ut as text, v as questionnairePrompt, w as TutorError, x as revisePrompt, y as quizPrompt, z as formatPassages } from "./runtime-ywaTyu56.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { dirname, join, relative, sep } from "node:path";
|
|
4
4
|
import { credentialKey } from "@deepseek-ai/dsh-credentials";
|
|
5
|
+
import { lstat, mkdir, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
6
|
+
import { lookup } from "node:dns";
|
|
7
|
+
import http from "node:http";
|
|
8
|
+
import https from "node:https";
|
|
9
|
+
import { isIP } from "node:net";
|
|
10
|
+
import { pipeline } from "node:stream";
|
|
11
|
+
import zlib from "node:zlib";
|
|
5
12
|
import { spawn } from "node:child_process";
|
|
6
13
|
import { existsSync } from "node:fs";
|
|
7
|
-
import { lstat, mkdir, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
8
14
|
import { fileURLToPath } from "node:url";
|
|
9
15
|
import { homedir } from "node:os";
|
|
10
16
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -268,6 +274,7 @@ function createCourses({ store, llm, jobs, now = () => /* @__PURE__ */ new Date(
|
|
|
268
274
|
progress,
|
|
269
275
|
intake,
|
|
270
276
|
jobs: {
|
|
277
|
+
questions: jobs.running(`questions:${courseId}`),
|
|
271
278
|
blueprint: jobs.running(`blueprint:${courseId}`),
|
|
272
279
|
confirm: jobs.running(`confirm:${courseId}`)
|
|
273
280
|
},
|
|
@@ -327,7 +334,10 @@ function createCourses({ store, llm, jobs, now = () => /* @__PURE__ */ new Date(
|
|
|
327
334
|
courseId,
|
|
328
335
|
questionnaire
|
|
329
336
|
};
|
|
330
|
-
}, {
|
|
337
|
+
}, {
|
|
338
|
+
key: `questions:${courseId}`,
|
|
339
|
+
meta: { courseId }
|
|
340
|
+
});
|
|
331
341
|
}
|
|
332
342
|
function submitIntake({ courseId, answers = {}, timeline = "balanced", weeklyMinutes, deadline }) {
|
|
333
343
|
assertId(courseId, "crs");
|
|
@@ -350,7 +360,7 @@ function createCourses({ store, llm, jobs, now = () => /* @__PURE__ */ new Date(
|
|
|
350
360
|
weeklyMinutes: clampMinutes(weeklyMinutes),
|
|
351
361
|
deadline: /^\d{4}-\d{2}-\d{2}$/u.test(String(deadline ?? "")) ? deadline : null
|
|
352
362
|
};
|
|
353
|
-
api.progress(0,
|
|
363
|
+
api.progress(0, 0, "blueprint");
|
|
354
364
|
const blueprint = await generateJson(llm, {
|
|
355
365
|
purpose: "teach",
|
|
356
366
|
prompt: blueprintPrompt({
|
|
@@ -365,6 +375,7 @@ function createCourses({ store, llm, jobs, now = () => /* @__PURE__ */ new Date(
|
|
|
365
375
|
images: llm.supportsImages?.("teach") ? await materialImages(store, materials) : void 0,
|
|
366
376
|
maxTokens: 16e3,
|
|
367
377
|
signal: api.signal,
|
|
378
|
+
onText: streamCounter("\"estMinutes\"", (count) => api.progress(count, 0, "blueprint")),
|
|
368
379
|
normalize: (raw) => attachProjectUnits(raw, normalizeBlueprint(raw, { language: course.language }))
|
|
369
380
|
});
|
|
370
381
|
const next = {
|
|
@@ -375,7 +386,6 @@ function createCourses({ store, llm, jobs, now = () => /* @__PURE__ */ new Date(
|
|
|
375
386
|
settings
|
|
376
387
|
};
|
|
377
388
|
await saveCourse(next);
|
|
378
|
-
api.progress(1, 1, "blueprint");
|
|
379
389
|
return { course: next };
|
|
380
390
|
}, {
|
|
381
391
|
key: `blueprint:${courseId}`,
|
|
@@ -388,23 +398,26 @@ function createCourses({ store, llm, jobs, now = () => /* @__PURE__ */ new Date(
|
|
|
388
398
|
return jobs.start("craft/revise", async (api) => {
|
|
389
399
|
const course = await readCourse(courseId);
|
|
390
400
|
if (!course.units) throw new TutorError("invalid", "There is no blueprint to revise yet");
|
|
401
|
+
const current = {
|
|
402
|
+
title: course.title,
|
|
403
|
+
subtitle: course.subtitle,
|
|
404
|
+
emoji: course.emoji,
|
|
405
|
+
summary: course.summary,
|
|
406
|
+
level: course.level,
|
|
407
|
+
units: course.units,
|
|
408
|
+
projects: course.projects
|
|
409
|
+
};
|
|
410
|
+
api.progress(0, 0, "blueprint");
|
|
391
411
|
const revised = await generateJson(llm, {
|
|
392
412
|
purpose: "teach",
|
|
393
413
|
prompt: revisePrompt({
|
|
394
|
-
blueprint:
|
|
395
|
-
title: course.title,
|
|
396
|
-
subtitle: course.subtitle,
|
|
397
|
-
emoji: course.emoji,
|
|
398
|
-
summary: course.summary,
|
|
399
|
-
level: course.level,
|
|
400
|
-
units: course.units,
|
|
401
|
-
projects: course.projects
|
|
402
|
-
},
|
|
414
|
+
blueprint: current,
|
|
403
415
|
instruction: request,
|
|
404
416
|
language: course.language
|
|
405
417
|
}),
|
|
406
418
|
maxTokens: 16e3,
|
|
407
419
|
signal: api.signal,
|
|
420
|
+
onText: streamCounter("\"estMinutes\"", (count) => api.progress(count, 0, "blueprint")),
|
|
408
421
|
normalize: (raw) => attachProjectUnits(raw, normalizeBlueprint(raw, { language: course.language }))
|
|
409
422
|
});
|
|
410
423
|
const next = {
|
|
@@ -438,11 +451,40 @@ function createCourses({ store, llm, jobs, now = () => /* @__PURE__ */ new Date(
|
|
|
438
451
|
await saveCourse(next);
|
|
439
452
|
return { course: next };
|
|
440
453
|
}
|
|
454
|
+
async function writeLecturePractice({ course, lecture, lessons = lecture.lessons, materials, signal }) {
|
|
455
|
+
const query = lessons.map((lesson) => `${lesson.title} ${lesson.objectives.join(" ")}`).join(" ");
|
|
456
|
+
const sources = materials ?? await readMaterials(store, course.materialIds ?? []);
|
|
457
|
+
const sets = await generateJson(llm, {
|
|
458
|
+
purpose: "teach",
|
|
459
|
+
prompt: practicePrompt({
|
|
460
|
+
course,
|
|
461
|
+
lecture,
|
|
462
|
+
lessons,
|
|
463
|
+
language: course.language,
|
|
464
|
+
passages: passagesFor(sources, query, 5e3)
|
|
465
|
+
}),
|
|
466
|
+
maxTokens: Math.min(16e3, 3e3 + lessons.length * 2200),
|
|
467
|
+
signal,
|
|
468
|
+
normalize: (raw) => raw?.lessons ?? raw
|
|
469
|
+
});
|
|
470
|
+
const written = {};
|
|
471
|
+
for (const lesson of lessons) {
|
|
472
|
+
const set = normalizePractice(sets?.[lesson.id] ?? sets?.[lesson.title] ?? (lessons.length === 1 ? Object.values(sets ?? {})[0] : void 0) ?? { items: [] }, lesson.concepts.map((concept) => concept.id));
|
|
473
|
+
if (!set.items.length) continue;
|
|
474
|
+
written[lesson.id] = {
|
|
475
|
+
lessonId: lesson.id,
|
|
476
|
+
...set,
|
|
477
|
+
createdAt: stamp()
|
|
478
|
+
};
|
|
479
|
+
await store.writeJson(store.paths.practice(course.id, lesson.id), written[lesson.id]);
|
|
480
|
+
}
|
|
481
|
+
return written;
|
|
482
|
+
}
|
|
441
483
|
function confirm({ courseId }) {
|
|
442
484
|
return jobs.start("craft/confirm", async (api) => {
|
|
443
485
|
const course = await readCourse(courseId);
|
|
444
486
|
if (!course.units) throw new TutorError("invalid", "Generate a blueprint first");
|
|
445
|
-
const lectures = course.units.flatMap((unit) => unit.lectures.map((lecture) => ({
|
|
487
|
+
const lectures = course.units.slice(0, 1).flatMap((unit) => unit.lectures.map((lecture) => ({
|
|
446
488
|
unit,
|
|
447
489
|
lecture
|
|
448
490
|
})));
|
|
@@ -489,29 +531,12 @@ function createCourses({ store, llm, jobs, now = () => /* @__PURE__ */ new Date(
|
|
|
489
531
|
api.signal.throwIfAborted();
|
|
490
532
|
const { lecture } = queue.shift();
|
|
491
533
|
try {
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
lecture,
|
|
498
|
-
lessons: lecture.lessons,
|
|
499
|
-
language: course.language,
|
|
500
|
-
passages: passagesFor(materials, query, 5e3)
|
|
501
|
-
}),
|
|
502
|
-
maxTokens: 9e3,
|
|
503
|
-
signal: api.signal,
|
|
504
|
-
normalize: (raw) => raw?.lessons ?? raw
|
|
534
|
+
await writeLecturePractice({
|
|
535
|
+
course,
|
|
536
|
+
lecture,
|
|
537
|
+
materials,
|
|
538
|
+
signal: api.signal
|
|
505
539
|
});
|
|
506
|
-
for (const lesson of lecture.lessons) {
|
|
507
|
-
const conceptIds = lesson.concepts.map((concept) => concept.id);
|
|
508
|
-
const set = normalizePractice(sets?.[lesson.id] ?? sets?.[lesson.title] ?? { items: [] }, conceptIds);
|
|
509
|
-
if (set.items.length) await store.writeJson(store.paths.practice(course.id, lesson.id), {
|
|
510
|
-
lessonId: lesson.id,
|
|
511
|
-
...set,
|
|
512
|
-
createdAt: stamp()
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
540
|
} catch (error) {
|
|
516
541
|
if (api.signal.aborted) throw error;
|
|
517
542
|
warnings.push(lecture.id);
|
|
@@ -618,6 +643,7 @@ function createCourses({ store, llm, jobs, now = () => /* @__PURE__ */ new Date(
|
|
|
618
643
|
submitIntake,
|
|
619
644
|
revise,
|
|
620
645
|
saveBlueprint,
|
|
646
|
+
writeLecturePractice,
|
|
621
647
|
confirm,
|
|
622
648
|
update,
|
|
623
649
|
remove,
|
|
@@ -663,12 +689,297 @@ function safeFileName(value) {
|
|
|
663
689
|
return /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/iu.test(cleaned) || !cleaned ? "course" : cleaned;
|
|
664
690
|
}
|
|
665
691
|
//#endregion
|
|
692
|
+
//#region src/core/board-fonts.js
|
|
693
|
+
const BOARD_FONT_FILES = Object.freeze([
|
|
694
|
+
Object.freeze({
|
|
695
|
+
family: "Aha Hand Latin",
|
|
696
|
+
file: "caveat-latin-d0b7b931.woff2",
|
|
697
|
+
bytes: 48836,
|
|
698
|
+
unicodeRange: "U+0,U+D,U+20-7E,U+A0-FF,U+131,U+152-153,U+20AC,U+2122"
|
|
699
|
+
}),
|
|
700
|
+
Object.freeze({
|
|
701
|
+
family: "Aha Hand",
|
|
702
|
+
file: "wenkai-gb-0-88f1a875.woff2",
|
|
703
|
+
bytes: 93632,
|
|
704
|
+
unicodeRange: "U+20-7E,U+A0-AC,U+AE-FF,U+101,U+113,U+11B,U+12B,U+14D,U+16B,U+1CE,U+1D0,U+1D2,U+1D4,U+1D6,U+1D8,U+1DA,U+1DC,U+2C7,U+2C9,U+391-3A1,U+3A3-3A9,U+3B1-3C1,U+3C3-3C9,U+401,U+410-44F,U+451,U+2010-2016,U+2018-2022,U+2025-2027,U+2030-2037,U+2039-203F,U+2042,U+2044,U+2047-2049,U+2051-2052,U+205A,U+205D,U+2100-2101,U+2103,U+2105-2106,U+2109-210A,U+210E-210F,U+2113,U+2116-2117,U+211E,U+2120-2122,U+2126-2127,U+2129-212B,U+212E,U+2132,U+2135,U+213B,U+2141-2144,U+214B,U+214D-214E,U+2150-218B,U+2190-2199,U+21B6-21B9,U+21C4-21C6,U+21CB-21D0,U+21D2,U+21D4,U+21E6-21EA,U+21F5,U+2200-220D,U+220F,U+2211-2213,U+2215-2216,U+2219-2220,U+2223-2230,U+2234-2237,U+223C-223E,U+2242-2243,U+2245,U+2248,U+224B-224C,U+2251-2253,U+225C,U+2260-2262,U+2264-226B,U+226E-226F,U+2272-2273,U+2276-2277,U+2282-228B,U+2295-2299,U+229C-229E,U+22A0,U+22A2-22A5,U+22BF-22C5,U+22DA-22DB,U+22EE-22F1,U+2312,U+2460-249F,U+2500-25AB,U+25B1-25B3,U+25B6-25B7,U+25BC-25BD,U+25C0-25C1,U+25C6-25C7,U+25C9-25CC,U+25CE-25D3,U+25E2-25E6,U+25EF,U+25FB-25FC,U+2605-2606,U+2640,U+2642,U+3000-302D,U+3030,U+3033-303F,U+3041-3093,U+30A1-30F6,U+30FB,U+3105-3129,U+3220-3229,U+FF01-FF5E,U+FFE0-FFE1,U+FFE3,U+FFE5"
|
|
705
|
+
}),
|
|
706
|
+
Object.freeze({
|
|
707
|
+
family: "Aha Hand",
|
|
708
|
+
file: "wenkai-gb-1-78a38e72.woff2",
|
|
709
|
+
bytes: 315108,
|
|
710
|
+
unicodeRange: "U+4E01,U+4E0D,U+4E11,U+4E19,U+4E1B-4E1C,U+4E22,U+4E2A,U+4E30,U+4E32,U+4E39,U+4E4E-4E4F,U+4E56,U+4E58,U+4E8C,U+4E92,U+4EA4-4EA5,U+4EA7-4EA8,U+4EC7,U+4ECE,U+4ED3,U+4ED8,U+4EE3,U+4EF6-4EF7,U+4EFD,U+4EFF,U+4F0E-4F10,U+4F19-4F1A,U+4F20,U+4F2F-4F30,U+4F34,U+4F43,U+4F46,U+4F4E,U+4F55,U+4F5B,U+4F70,U+4F73,U+4F88,U+4F97,U+4F9B,U+4FA7,U+4FAF,U+4FBF,U+4FC3-4FC4,U+4FD8,U+4FDD,U+4FED,U+4FEF,U+4FFA,U+500D,U+5012,U+5019,U+5021,U+5047,U+5065,U+507F,U+5085,U+508D,U+50A3,U+50A8,U+50AC,U+50B2,U+50F5,U+513F,U+5145,U+5149,U+5151,U+515A,U+515C,U+516B-516C,U+5171,U+5173,U+5175,U+5178,U+517C,U+5180,U+5188,U+518C,U+51A0,U+51AC,U+51AF-51B0,U+51B2,U+51BB,U+51CB,U+51CF,U+51D1,U+51E0-51E1,U+51E4,U+51F0,U+51F3,U+51F9-51FB,U+51FD,U+5200-5201,U+5206,U+5212,U+521A-521B,U+521D,U+522B,U+522E,U+5230,U+523A,U+523D,U+5241-5242,U+5250-5251,U+5265,U+526A,U+526F,U+5272,U+529E-52A0,U+52A8,U+52C3,U+52FE,U+5305-5306,U+5316-5317,U+5319,U+5320,U+532A,U+5349-534A,U+534E,U+5351,U+5355,U+535A,U+535C,U+535E,U+5373,U+5382,U+5384,U+5395,U+539A,U+53A8,U+53C2,U+53C9-53CA,U+53CD,U+53D1,U+53D8,U+53E0,U+53E4,U+53ED-53EE,U+53F7,U+53FC,U+5403-5404,U+5408-540A,U+540E,U+5420,U+5426-5429,U+542B,U+5435,U+5439,U+543C,U+5446,U+5448,U+544A,U+5475,U+547C,U+548C,U+5490,U+5495,U+54C0,U+54C4,U+54C6,U+54C8,U+54CE,U+54D7,U+54E5,U+54FA,U+54FC,U+5507,U+5509,U+5524,U+552C,U+5531,U+554A,U+5561,U+5589-558A,U+5598,U+559D,U+5609,U+560E,U+5632,U+563F,U+5676,U+568E,U+56DE,U+56E4,U+56F1,U+56FA,U+56FD,U+572D,U+5730,U+573A,U+573E,U+574A,U+574F,U+575A,U+575D,U+575F,U+5782,U+579B,U+57A2,U+57AB,U+57C2-57C3,U+57CE,U+57E0,U+57FA,U+5806,U+5815,U+5821,U+5824,U+5835,U+58A9,U+58C1,U+58D5,U+58F6,U+5904,U+5907,U+590D,U+591A,U+591F,U+5927,U+592B,U+592F,U+5939-593A,U+5949,U+594B,U+5954,U+5956,U+5960,U+5965,U+5978,U+597D,U+5987,U+5992-5993,U+59A8,U+59D1,U+59DC,U+59EC,U+5A25,U+5A5A,U+5AC1,U+5AC9,U+5AE1,U+5B58,U+5B63-5B64,U+5B69,U+5B75,U+5B89,U+5B8F,U+5B98,U+5B9A,U+5B9D,U+5BA0,U+5BA6,U+5BAB,U+5BB3,U+5BB6,U+5BBE,U+5BC2,U+5BC4,U+5BCC,U+5BD2,U+5BDF,U+5BE1,U+5BF8-5BF9,U+5BFC,U+5C01,U+5C06,U+5C14,U+5C16,U+5C18,U+5C1D,U+5C3A,U+5C42,U+5C94,U+5C97,U+5C9B,U+5CB8,U+5CE8,U+5CF0,U+5D07,U+5D14,U+5D29,U+5DDD,U+5DE2,U+5DE5,U+5DE9,U+5DEE,U+5DF1,U+5DF4,U+5E01,U+5E03,U+5E06,U+5E1B,U+5E1D,U+5E26,U+5E2E,U+5E38,U+5E45,U+5E4C,U+5E62,U+5E72,U+5E76,U+5E7B,U+5E7F,U+5E87,U+5E8A,U+5E95,U+5E97,U+5E9A,U+5E9C,U+5E9F,U+5EA6,U+5EFA,U+5F0A,U+5F13,U+5F17-5F18,U+5F1B,U+5F1F,U+5F27,U+5F39,U+5F52-5F53,U+5F69-5F6A,U+5F6C,U+5F7B-5F7C,U+5F85,U+5F88,U+5F8A,U+5F97,U+5FB7,U+5FBD,U+5FC5,U+5FCC,U+5FF1,U+5FFD,U+5FFF-6000,U+6016,U+6020,U+6025,U+602A,U+604D,U+6052,U+6062,U+6068-6069,U+606B,U+606D,U+6076,U+608D,U+6094,U+60A3,U+60B2,U+60B8,U+60BC,U+60D1,U+60E0,U+60E6,U+60E8-60E9,U+60EB,U+60ED-60F0,U+60F6,U+6101,U+611F,U+6124,U+6148,U+614C,U+6167,U+618B,U+61A8,U+61BE,U+61C2,U+61CA,U+6208,U+6210,U+6216,U+6233-6234,U+6237,U+623F,U+6241,U+624D,U+6252-6253,U+626E-626F,U+6273,U+6276,U+627C,U+627F-6280,U+6284,U+628A,U+6296,U+629A,U+62A4-62A5,U+62B1,U+62B5,U+62BD,U+62C2,U+62C5-62C6,U+62CC,U+62D0,U+62D4,U+62DC,U+62E3,U+62E8,U+62F1,U+6301-6302,U+6309,U+6321,U+6324-6325,U+6328,U+632B,U+634C-634D,U+6355,U+6361-6363,U+6376,U+6382,U+6387,U+6389,U+63A3,U+63AA,U+63B8,U+63BA,U+63D2,U+63E3,U+6400-6401,U+640F-6410,U+6413,U+641E,U+642C-642D,U+643D,U+6446,U+6448,U+6467,U+6491,U+64A4,U+64AD-64AE,U+64BC,U+64CD,U+64E6,U+6539,U+653B,U+653E,U+6545,U+654C,U+6556,U+655D-655E,U+6562,U+6566,U+6577,U+658C,U+6591,U+6597,U+65A5,U+65A7,U+65AD,U+65B9,U+65E2,U+65E6,U+65F1,U+6602,U+660C,U+660F,U+6625,U+6643,U+6666,U+6668,U+6697,U+66B4,U+66F4,U+66F9,U+670D,U+671D,U+672C,U+6735,U+673A,U+6746,U+6750-6751,U+675C,U+6760,U+676D,U+676F,U+677F,U+6781,U+6784,U+679C,U+67AB,U+67B6-67B7,U+67C4,U+67CF,U+67D1,U+67DC,U+67E5,U+67EC,U+67F4,U+6807,U+680B,U+6838-6839,U+683C,U+6842,U+6848,U+6853,U+6863,U+6868,U+6886,U+6897,U+68C0,U+68CD,U+68D2,U+68D8,U+68FA,U+6912,U+693D,U+693F,U+695A,U+6982,U+699C,U+69D0,U+69DB,U+69FD,U+6A0A,U+6A2A,U+6A59,U+6A71,U+6B21-6B22,U+6B4C,U+6B64-6B65,U+6B79,U+6B7C,U+6B86,U+6B8B,U+6BB5,U+6BBF,U+6BC1,U+6BD2,U+6BD4-6BD6,U+6BD9,U+6BEB,U+6C1B,U+6C1F,U+6C26,U+6C28,U+6C2E,U+6C47,U+6C49,U+6C57,U+6C5E-6C60,U+6C72,U+6C7E,U+6C89,U+6C9F,U+6CA7,U+6CAA,U+6CB3,U+6CB8,U+6CBD,U+6CCA,U+6CD5,U+6CDB,U+6CE2,U+6CF5,U+6D1E,U+6D2A,U+6D31,U+6D3B,U+6D46-6D47,U+6D4B,U+6D4E,U+6D51,U+6D69,U+6D6E,U+6D77,U+6DA3-6DA4,U+6DA7,U+6DAA,U+6DB5,U+6DB8,U+6DC0,U+6DE1,U+6DEC,U+6DEE,U+6DF3,U+6DF7,U+6E10,U+6E21,U+6E24,U+6E2F,U+6E56,U+6E85,U+6E89,U+6EC1,U+6EC7,U+6ED1,U+6EDA,U+6EE8,U+6EF4,U+6F6E,U+6F84,U+6F88,U+6FB3,U+6FC0,U+6FD2,U+704C,U+706B,U+706F-7070,U+707F,U+708A,U+7092,U+70B3,U+70B9,U+70BD,U+70D8,U+70E6,U+70E9,U+70FD,U+710A,U+7115,U+7119-711A,U+7126,U+714C,U+714E,U+71AC,U+7206,U+7231,U+7236,U+7238-7239,U+7248,U+728A,U+72AF,U+72C4,U+72C8,U+72D0,U+72D7,U+72E0,U+72EC,U+7316,U+731C,U+7334,U+733E,U+73AF,U+73BB,U+73D0,U+73ED,U+745A,U+7470,U+74DC,U+74E3,U+74F7,U+7518,U+752B,U+752D,U+7532,U+7535,U+7538,U+753B,U+7545,U+756A,U+7574,U+7578,U+7586,U+7599,U+75A4,U+75AE-75AF,U+75B5,U+75BE,U+75C5,U+75D5,U+75D8,U+75EA,U+75F4,U+75F9,U+7601,U+7629-762A,U+764C,U+7678,U+767B,U+767D-767E,U+7684,U+7687,U+768B,U+7691,U+76CE,U+76D1-76D2,U+76D6-76D7,U+76EF,U+76FE,U+7763,U+776C,U+7779,U+7785,U+77AA,U+77D7,U+77ED-77EE,U+77FE,U+7840,U+7845,U+7877,U+7889,U+788D,U+7891,U+7898,U+789F,U+78A7,U+78B1,U+78B4,U+78C1,U+78C5,U+78CB,U+78FA,U+7901,U+796D,U+7977-7978,U+798F,U+79BE,U+79C6,U+79C9,U+79E4,U+79EF-79F0,U+79FD,U+7A0B,U+7A17,U+7A20,U+7A3B-7A3D,U+7A3F,U+7A7F,U+7A97,U+7A9C,U+7AEF,U+7AFF,U+7B06,U+7B14,U+7B1B,U+7B26,U+7B28,U+7B2C,U+7B3A,U+7B49,U+7B4F,U+7B54,U+7B56,U+7B79,U+7B80,U+7B8D,U+7B94-7B95,U+7BA1,U+7BAD,U+7BD9,U+7BE1,U+7C07,U+7C27,U+7C3F,U+7C4D,U+7C89,U+7C97,U+7CAA,U+7CB9,U+7CCA,U+7CD5,U+7CD9,U+7E41,U+7EA2,U+7EA7,U+7EAA,U+7EAF,U+7EB2,U+7EB7,U+7EBA,U+7ECA,U+7ED1,U+7ED8-7ED9,U+7EE7,U+7EE9,U+7EF0,U+7EF7-7EF8,U+7F04,U+7F09,U+7F0E,U+7F13-7F14,U+7F16,U+7F1A,U+7F1D,U+7F20,U+7F38,U+7F50,U+7F55,U+7F5A,U+7F62,U+7F94,U+7FB9,U+7FC5,U+7FDF-7FE0,U+7FF0-7FF1,U+7FFB,U+800C,U+8015,U+8017,U+8019,U+8033,U+803B,U+803D,U+803F,U+806A,U+808C,U+809A-809B,U+809D,U+80A0-80A1,U+80A4-80A5,U+80A9-80AA,U+80AE,U+80BA,U+80C6,U+80CC,U+80DE,U+80E1,U+80F3,U+80F6,U+80FA,U+8106,U+810A,U+8116,U+812F,U+8150-8151,U+8179,U+8180,U+818A,U+818F,U+8198,U+81C2,U+81E3,U+81ED,U+822A,U+822C,U+8230-8231,U+8235-8236,U+8239,U+8270,U+827E,U+82AC-82AD,U+82B1,U+82B3,U+82CD,U+82DE-82DF,U+82EF,U+8303,U+8327-8328,U+832C,U+8336,U+8349,U+8350,U+8352,U+835A,U+8361,U+8364,U+8377,U+83B7,U+83C7,U+83CF,U+83DC,U+83E0,U+83F2,U+845B,U+8463,U+846B,U+8471,U+8482,U+848B,U+84D6,U+84DF,U+8521,U+853C-853D,U+8549,U+8584,U+85CF,U+85E9,U+864E,U+866B,U+8679,U+868C,U+8695,U+86CA-86CB,U+86D4,U+86E4,U+86FE,U+8702,U+8749,U+8757,U+8774,U+8776,U+8822,U+8861,U+8865,U+8868,U+886C,U+8884,U+888B,U+88AB,U+88B1,U+88C1,U+88F9,U+8902,U+8910,U+8912,U+8986,U+89C1-89C2,U+89C4,U+89E6,U+8BA1-8BA3,U+8BA5,U+8BB0,U+8BB2-8BB3,U+8BB9,U+8BBD,U+8BBF,U+8BCD,U+8BDA,U+8BDD-8BDE,U+8BE1,U+8BE5,U+8BE7,U+8BF2,U+8BFB,U+8BFD,U+8C03,U+8C0D-8C0E,U+8C17,U+8C24,U+8C37,U+8C41,U+8C46,U+8C62,U+8C6A,U+8C79-8C7A,U+8C89,U+8D1D,U+8D1F,U+8D21-8D22,U+8D25,U+8D27,U+8D29,U+8D2C-8D2D,U+8D2F-8D31,U+8D35,U+8D37,U+8D39-8D3A,U+8D3E-8D3F,U+8D4B-8D4C,U+8D50,U+8D63-8D64,U+8D6B,U+8D74,U+8D76,U+8D81,U+8D85,U+8DCB-8DCC,U+8DDF,U+8DEA,U+8DF5,U+8DFA,U+8E0C,U+8E29,U+8E48,U+8E66,U+8E6C-8E6D,U+8E72,U+8E7F,U+8E87,U+8EAC,U+8EB2,U+8F66,U+8F68,U+8F70,U+8F85,U+8F88-8F8A,U+8F90-8F91,U+8F9C,U+8F9E-8F9F,U+8FA8-8FA9,U+8FAB,U+8FB0,U+8FB9,U+8FBE,U+8FC7,U+8FD4,U+8FD8,U+8FDF,U+8FEA,U+8FED,U+8FF8-8FF9,U+9012,U+9017,U+901B,U+901E,U+9022,U+902E,U+903C,U+9041,U+904D,U+904F,U+9053,U+907F,U+9093,U+90A6,U+90AF,U+90CA,U+90DD,U+90E8,U+90ED,U+90F4,U+90F8,U+90FD,U+9102,U+9119,U+915A,U+9163,U+916C,U+9171,U+9187,U+918B,U+91C7,U+91DC,U+9274,U+9489,U+9492-9493,U+9499,U+949D-949E,U+94A1-94A2,U+94A9,U+94B5,U+94BE,U+94C2,U+94EC,U+94F2,U+9504-9505,U+950B,U+9519,U+9524,U+952D-952E,U+953B,U+9540,U+9550-9551,U+957F,U+95ED,U+95EF,U+95F4,U+95FA,U+9600-9602,U+9610,U+961C,U+961F,U+9632,U+963F,U+9644-9645,U+9648,U+964D,U+965B,U+9661,U+9664,U+9694,U+9698,U+96C6-96C7,U+96CC,U+96CF,U+96D5,U+96F9,U+970D,U+9738,U+975B,U+975E,U+9769,U+9776,U+978D,U+97AD,U+97E9,U+9876,U+987E-987F,U+9881,U+988A,U+989D,U+98A0,U+98A4,U+98CE,U+98DE,U+9910,U+9965,U+996D,U+996F,U+9971,U+9975,U+997C,U+997F,U+9986,U+998B,U+9A70,U+9A73,U+9A7E,U+9A84,U+9A87,U+9A8B,U+9AA8,U+9AB8,U+9AD8,U+9B3C,U+9B42,U+9C8D,U+9CD6,U+9E21,U+9E3D,U+9E3F,U+9E45,U+9E64,U+9EC4,U+9ED1,U+9F0E,U+9F13,U+9F3B,U+9F7F,U+9F9A,U+9F9F"
|
|
711
|
+
}),
|
|
712
|
+
Object.freeze({
|
|
713
|
+
family: "Aha Hand",
|
|
714
|
+
file: "wenkai-gb-2-2a649892.woff2",
|
|
715
|
+
bytes: 317648,
|
|
716
|
+
unicodeRange: "U+4E03,U+4E09-4E0A,U+4E14,U+4E16,U+4E18,U+4E24,U+4E27,U+4E34,U+4E3D-4E3E,U+4E43,U+4E45,U+4E48,U+4E50,U+4E52-4E54,U+4E5D-4E5E,U+4E70-4E71,U+4E73,U+4E7E,U+4E86,U+4E8B,U+4E8F,U+4E95,U+4EA2,U+4EA9,U+4EAC,U+4EAE,U+4EB2,U+4EBA,U+4EC0-4EC1,U+4EC5-4EC6,U+4ECA-4ECB,U+4ECD,U+4ED1,U+4ED5,U+4EDF,U+4EE4,U+4EEC,U+4EFB,U+4F01,U+4F1E,U+4F24,U+4F26,U+4F36,U+4F38,U+4F60,U+4F69,U+4F6C,U+4F7F,U+4F8B,U+4F8D,U+4FA3,U+4FA5,U+4FA8-4FA9,U+4FB5,U+4FCA,U+4FCF-4FD0,U+4FE9,U+4FF1,U+5014,U+501F,U+5026,U+502A,U+503E,U+504F,U+5076,U+5080,U+5088,U+50BB,U+50DA,U+50E7,U+50FB,U+5112,U+5121,U+514B,U+514D,U+5162,U+5165,U+5168,U+516D,U+5170,U+5176-5177,U+5185,U+5189,U+5192,U+5195,U+5197,U+519B-519C,U+51B3,U+51B5,U+51B7,U+51C0,U+51C4,U+51C9,U+51CC,U+51DB,U+51DD,U+51ED,U+51EF,U+5203,U+5207,U+520A,U+5217-5218,U+5220,U+5224,U+5228-5229,U+5238-5239,U+523B,U+524D,U+5256,U+5267,U+5269,U+527F,U+5288,U+529B,U+529D,U+52A3,U+52AA-52AB,U+52B1-52B3,U+52BF,U+52C9,U+52D2,U+52D8,U+52DF,U+52E4,U+52FA,U+5321,U+5339-533A,U+533F,U+5341,U+5343,U+5347,U+5356-5357,U+5361-5362,U+5364,U+536F,U+5374-5375,U+5377,U+537F,U+5386,U+5389,U+5398,U+53A9,U+53BB,U+53C1,U+53D6-53D7,U+53DB,U+53E3,U+53E5-53E6,U+53EB,U+53EF,U+53F2,U+540D,U+540F,U+5415,U+5417,U+541B,U+541D,U+542D,U+542F,U+5450,U+5455,U+545B,U+5462,U+5478,U+547B,U+547D,U+5480,U+5486,U+548E,U+5496,U+5499,U+54AF,U+54B3,U+54C1,U+54E6,U+54E8-54EA,U+54ED,U+552E,U+5543,U+5546,U+5564-5566,U+556A,U+556E,U+5580,U+5584,U+5587,U+55B7,U+55D3,U+55DC,U+561B,U+5668,U+566C,U+56B7,U+56BC,U+56CA,U+56DA,U+56F0,U+5703,U+5708,U+5723,U+5747,U+574E,U+5751,U+5757,U+5761,U+5764,U+576A,U+576F,U+5777,U+5783-5784,U+5792,U+57A6,U+57AE,U+57CB,U+57D4,U+57F9,U+5811,U+582A,U+585E,U+5883,U+5892-5893,U+5899,U+58A8,U+58E4,U+58EB-58EC,U+58F0,U+58F3,U+5931,U+5938,U+5947-5948,U+594E,U+5951,U+5962,U+5973-5974,U+5976,U+5982,U+5988,U+598A,U+5999,U+59AE,U+59B9,U+59BB,U+59C6,U+59CB,U+59D0,U+59E5,U+5A04,U+5A07,U+5A18,U+5A1C,U+5A1F-5A20,U+5A29,U+5A36,U+5A46,U+5A6A,U+5A76,U+5A92,U+5A9A,U+5AC2,U+5AE9,U+5B54,U+5B5F,U+5B6A,U+5B7A,U+5B7D,U+5B81,U+5B88,U+5B9E,U+5BA1-5BA2,U+5BA4,U+5BB9,U+5BBD,U+5BC6-5BC7,U+5BD0,U+5BDD-5BDE,U+5BE5,U+5BFF,U+5C04,U+5C11,U+5C1A,U+5C31,U+5C38,U+5C3C-5C3D,U+5C3F-5C41,U+5C45,U+5C48,U+5C4A,U+5C4E-5C4F,U+5C61,U+5C65,U+5C71,U+5C82,U+5CAD,U+5CBF,U+5CE6,U+5CED,U+5CFB,U+5D0E,U+5D4C,U+5DE7-5DE8,U+5DFE,U+5E02,U+5E08,U+5E15,U+5E18,U+5E3D,U+5E42,U+5E55,U+5E73-5E74,U+5E86,U+5E90,U+5E93,U+5E99,U+5E9E,U+5EB7,U+5EC9-5ECA,U+5ED3,U+5ED6,U+5F00,U+5F03-5F04,U+5F0F,U+5F25,U+5F31,U+5F3A,U+5F55,U+5F6D,U+5F84,U+5F8B,U+5F98,U+5FCD,U+5FD9,U+5FEB,U+5FF5,U+6012,U+6015,U+601C,U+602F,U+6043,U+604B,U+6050,U+6070,U+6073,U+607C,U+6084,U+60A8,U+60AF,U+60C5,U+60CA,U+60E7,U+60F9,U+6127,U+614E,U+6151,U+6155,U+6162,U+6168,U+6177,U+61D2,U+61E6,U+620E,U+6212,U+621A,U+622A,U+622E,U+6247,U+624B,U+6251,U+6254,U+625B,U+6263,U+6266,U+6269,U+626B,U+626D,U+6270,U+6279,U+6289,U+6297,U+629B,U+62A0-62A2,U+62A8,U+62AB,U+62B9,U+62BF,U+62C7-62C9,U+62CD-62CE,U+62D2,U+62D8,U+62DF,U+62E2,U+62E6-62E7,U+62EC-62ED,U+62F3,U+62F7,U+62FC,U+62FE-62FF,U+630E,U+631B,U+6320,U+632A,U+6346,U+634E-6350,U+635E,U+6367,U+636E,U+6377,U+637B,U+6388,U+6390,U+6392,U+6398,U+63A0,U+63A5,U+63A7,U+63B3,U+63C9,U+63CF,U+63E9-63EA,U+63ED,U+63FD,U+6402,U+6405,U+6414,U+6444,U+6469,U+6478-6479,U+6482,U+6485,U+6487,U+6492,U+64A9,U+64AC,U+64B5,U+64C2,U+64C5,U+64CE,U+64D2,U+6500,U+6518,U+652B,U+6536,U+654F,U+6551,U+6559,U+655B,U+6563,U+656C,U+6572,U+6599,U+65A4,U+65BD,U+65C1,U+65C5,U+65D7,U+65E5,U+65E7,U+65F6-65F7,U+6606,U+660E,U+6627,U+662F,U+664B-664C,U+6652,U+666E-666F,U+6674,U+6676,U+667E,U+6696,U+66AE,U+66DD,U+66F2,U+66FC,U+670B,U+6717,U+671F,U+6728,U+672B,U+6734,U+6740,U+6743,U+6749,U+674E,U+6765,U+6770,U+6797,U+679A,U+67AA,U+67AF,U+67D0,U+67D2-67D4,U+67E0,U+67EF,U+67F3,U+67FF,U+680F,U+6816-6817,U+6846,U+6851,U+6854,U+6865,U+6881,U+6885,U+68A2,U+68A6,U+68A8,U+68C9,U+68CB,U+68DA,U+68EE,U+68F1,U+68F5,U+695E,U+6977,U+697C,U+6994,U+69B4,U+69B7,U+6A21,U+6A47,U+6AAC,U+6B20,U+6B27,U+6B3A,U+6B3E,U+6B49,U+6B67,U+6BB4,U+6BCD,U+6BCF,U+6BD7,U+6BDB,U+6C0F,U+6C11,U+6C13-6C14,U+6C16,U+6C22,U+6C2F-6C30,U+6C42,U+6C55,U+6C5D,U+6C7D,U+6C81,U+6C88,U+6C8F,U+6C99,U+6C9B,U+6CA1,U+6CA4-6CA6,U+6CAB,U+6CAE,U+6CC5,U+6CC9,U+6CCC,U+6CDE,U+6CE1,U+6CE3,U+6CE5,U+6CEA,U+6CFC,U+6D01,U+6D12,U+6D1B,U+6D25,U+6D3D-6D3E,U+6D41,U+6D45,U+6D53,U+6D5A,U+6D66,U+6D6A,U+6D78,U+6D85,U+6D89,U+6D9D,U+6D9F,U+6DA6,U+6DA9,U+6DCB,U+6DD6,U+6DF1,U+6E05,U+6E17,U+6E20,U+6E34,U+6E3A,U+6E43,U+6E7F,U+6E83,U+6E9C,U+6EB6,U+6EBA,U+6EE1,U+6EE4-6EE6,U+6F02,U+6F06,U+6F0F,U+6F13,U+6F20,U+6F2B,U+6F58,U+6F5C,U+6F5E,U+6F66,U+6F8E,U+6F9C,U+7011,U+706D,U+7075,U+7078,U+7089,U+7094-7095,U+70AC,U+70AE-70AF,U+70BC,U+70C2,U+70C8,U+70D9,U+70E4,U+70E7,U+70EC-70ED,U+70F9,U+7136,U+715E,U+7164,U+717D,U+7194,U+71C3,U+71CE,U+722C,U+7235,U+7247,U+724C,U+725B,U+725F,U+7261-7262,U+7267,U+7272,U+7275,U+7281,U+72AC,U+72C2,U+72D9,U+72DE,U+72E1,U+72EE,U+72F8,U+72FC,U+730E,U+731B,U+732B,U+7387,U+7396,U+739B,U+73AB,U+73B2,U+73CA,U+7403,U+7405-7406,U+7409,U+7433-7436,U+743C,U+745E-745F,U+7483,U+74E2,U+74E4,U+74F6,U+751A,U+751F,U+7525,U+7533,U+7537,U+754C,U+7554,U+7559,U+7565-7566,U+7597,U+759A,U+759F,U+75A5,U+75B2,U+75BD,U+75C9-75CA,U+75DE,U+75E2,U+7624,U+7638,U+7686,U+76AE,U+76BF,U+76C6,U+76D4,U+76D8,U+76DB,U+76DF,U+76EE,U+76F2,U+76FC,U+7701,U+7709,U+770B,U+7720,U+772F,U+7736-7737,U+775B,U+7766,U+776B,U+7784,U+7792,U+77A5,U+77A7,U+77DB,U+77E2,U+77E9,U+77EB,U+77F3,U+77FF,U+7801-7802,U+780C-780D,U+7812,U+7830,U+7834,U+7837,U+783E,U+786B,U+786E,U+787C,U+788C,U+78B0,U+78BE,U+78CA,U+78D0,U+78D5,U+78E8,U+78F7,U+793A,U+793C,U+793E,U+7941,U+7948,U+795E,U+7968,U+7981,U+7984,U+79BB,U+79BD,U+79CB,U+79D1-79D2,U+79D8,U+79E6,U+79F8,U+7A0D,U+7A46,U+7A76-7A77,U+7A7A,U+7A83,U+7A8D,U+7A96,U+7A98,U+7A9F,U+7AA5,U+7ABF,U+7ACB,U+7ADE-7ADF,U+7AE3,U+7AED,U+7B3C,U+7B4B,U+7B50,U+7B5B,U+7B77,U+7B7E,U+7BA9,U+7BC7,U+7BD3,U+7BEE,U+7BF1,U+7BF7,U+7C73,U+7C7B,U+7C92,U+7C95,U+7CAE,U+7CB1,U+7CB3,U+7CBE,U+7CDC,U+7CE0,U+7CEF,U+7D27,U+7D2F,U+7EA0,U+7EAB,U+7EB1,U+7EB3,U+7EB6,U+7EBD,U+7EC3,U+7EC5,U+7ECD,U+7ECF,U+7ED2-7ED3,U+7ED5,U+7EDC-7EDE,U+7EE2,U+7EF3,U+7EF5,U+7EFF,U+7F05-7F06,U+7F15,U+7F2E,U+7F34,U+7F3A,U+7F57,U+7F8C,U+7F8E,U+7F9A,U+7FA4,U+7FD8,U+8001,U+8003,U+8010,U+802A,U+8042,U+804A-804B,U+8054,U+8058,U+805A,U+8089,U+808B,U+80AF,U+80BE,U+80D6,U+80DA,U+80DC,U+80EF,U+80FD,U+8109,U+8110-8111,U+8113,U+811A,U+8138,U+813E,U+814A,U+8154,U+816E,U+817B,U+819C,U+81A8,U+81B3,U+81FC,U+8205,U+820C-820D,U+826F,U+8272,U+8282,U+828D,U+8292,U+82A5-82A6,U+82B9,U+82D7,U+82DB,U+82E5-82E6,U+82EB,U+82F9,U+8302,U+8304-8305,U+830E,U+832B,U+8338-8339,U+8346,U+8354,U+8363,U+8386,U+8389,U+838E,U+83AB,U+83B1-83B2,U+83BD,U+83CA,U+83CC,U+83E9,U+83F1,U+840C-840D,U+841D,U+8428,U+843D,U+8461,U+8475,U+8499,U+84B2,U+84C9,U+84DD,U+84EC,U+8511,U+8513,U+852B,U+8537,U+854A,U+857E,U+85C9,U+85D0,U+85D5,U+8611,U+864F-8651,U+8671,U+8680,U+8682,U+86C6-86C7,U+86EE,U+871C,U+8721,U+878D,U+879F,U+87BA,U+8815,U+8857,U+886B,U+888D,U+88C2,U+88D9,U+88E4,U+88F3-88F4,U+88F8,U+8925,U+895F,U+89C5-89C6,U+89C8-89C9,U+89D2,U+89E3,U+8A93,U+8B66,U+8B6C,U+8BA4,U+8BA9,U+8BAB,U+8BBA,U+8BBE,U+8BC0,U+8BC4,U+8BC6,U+8BD5,U+8BD7,U+8BEB,U+8BF7,U+8BFA,U+8BFE,U+8C05,U+8C0B,U+8C1C,U+8C26,U+8C28-8C29,U+8C2C,U+8C30-8C31,U+8C34,U+8C8C,U+8D2B,U+8D38,U+8D41-8D42,U+8D4A,U+8D4F,U+8D54,U+8D56,U+8D5B,U+8D61,U+8D66,U+8D77,U+8D8B,U+8DA3,U+8DB4,U+8DD1,U+8DDD,U+8DE8,U+8DEF,U+8E1E,U+8EAB,U+8EAF,U+8F6E-8F6F,U+8F7B,U+8F7F,U+8F83,U+8F86,U+8FA3,U+8FB1,U+8FBD,U+8FC1,U+8FC4,U+8FC8,U+8FD1,U+8FDB,U+8FDE,U+8FEB,U+8FF7,U+9002,U+9006,U+901D,U+903B,U+9063,U+90A3,U+90B1,U+90B5,U+90BB,U+90CE,U+90E1,U+914B,U+914D,U+9152,U+916A,U+9175-9177,U+917F,U+919A-919B,U+91CA,U+91CC,U+91CF,U+91D1,U+948E,U+94A0,U+94A6-94A7,U+94AE,U+94B1,U+94B3,U+94C3,U+94C5-94C6,U+94DD,U+94ED,U+94F0,U+94FA,U+94FE,U+9510,U+951A,U+9523,U+9526,U+952F-9530,U+9539,U+9541,U+954A,U+954D,U+955C,U+9563,U+956D,U+9570,U+95E8,U+95EA,U+95F0,U+95F7,U+95F9,U+95FD,U+9611,U+9614,U+962E,U+9636,U+9646-9647,U+964B-964C,U+9655,U+966A,U+9675,U+9686,U+96B6,U+96BE,U+96C0,U+96F6-96F7,U+9709,U+9713,U+9716,U+9732,U+9739,U+9752,U+9756,U+9759,U+9760-9762,U+9773,U+9798,U+97A0,U+97E7,U+97ED,U+97F6,U+9877,U+9885-9888,U+9891,U+9897,U+98A7,U+98D8,U+98DF,U+9970,U+9976,U+997A,U+9981,U+9988,U+998F,U+9992,U+9996,U+9A6C,U+9A71,U+9A74,U+9A76,U+9A79,U+9A82,U+9A86,U+9A8F,U+9A91,U+9A97,U+9A9A,U+9AA1,U+9B41,U+9B44,U+9B54,U+9C81,U+9CA4,U+9CB8,U+9CC3,U+9CDE,U+9E1F,U+9E23,U+9E25,U+9E43,U+9E4A,U+9E4F,U+9E7F,U+9E93,U+9EA6,U+9EBB,U+9ECE,U+9ED4,U+9ED8,U+9F50,U+9F84,U+9F8B,U+9F99"
|
|
717
|
+
}),
|
|
718
|
+
Object.freeze({
|
|
719
|
+
family: "Aha Hand",
|
|
720
|
+
file: "wenkai-gb-3-6949c050.woff2",
|
|
721
|
+
bytes: 311704,
|
|
722
|
+
unicodeRange: "U+4E00,U+4E07-4E08,U+4E0B,U+4E0E,U+4E13,U+4E1A,U+4E1D,U+4E25,U+4E2B,U+4E2D,U+4E38,U+4E3A-4E3B,U+4E49,U+4E4B-4E4D,U+4E59,U+4E5F-4E61,U+4E66,U+4E88-4E89,U+4E8E,U+4E91,U+4E94,U+4E9A-4E9B,U+4EA1,U+4EA6,U+4EAB,U+4EAD,U+4EBF,U+4ED4,U+4ED6-4ED7,U+4ED9,U+4EE5,U+4EEA,U+4EF0,U+4EF2,U+4F0A,U+4F0D,U+4F11,U+4F17-4F18,U+4F1F,U+4F2A,U+4F3A,U+4F3C,U+4F4D,U+4F4F-4F51,U+4F53,U+4F59,U+4F5C,U+4F63,U+4F6F,U+4F84,U+4F9D,U+4FA0,U+4FA6,U+4FAE,U+4FD7,U+4FDE,U+4FE1,U+4FEE,U+5018,U+501A,U+503A,U+503C,U+505A,U+505C,U+5077,U+50CF,U+50F3,U+5141,U+5143-5144,U+5146,U+5148,U+5154,U+5174,U+5179,U+517B,U+517D,U+518D,U+5199,U+51A4,U+51B6,U+51C6,U+51F6,U+51F8,U+51FF,U+5211,U+5219,U+5236-5237,U+5243,U+524A,U+5254,U+52A1,U+52A9,U+52C7,U+52CB,U+52FF-5300,U+5308,U+531D,U+5323,U+533B,U+5348,U+534F,U+5352-5353,U+5360,U+5367,U+536B,U+5370-5371,U+5378,U+5385,U+538B-538C,U+539F,U+53A2,U+53A6,U+53BF,U+53C8,U+53CB-53CC,U+53D4,U+53D9,U+53EA,U+53EC,U+53F0,U+53F3,U+53F6,U+53F8-53F9,U+5401,U+540C,U+5410-5411,U+5413,U+541E-541F,U+542C,U+542E,U+5431,U+5434,U+5438,U+543B,U+543E,U+5440,U+5458,U+545C,U+5468,U+5473,U+548B,U+548F,U+5492,U+54A8,U+54AC,U+54B1,U+54B8,U+54BD,U+54C7,U+54C9,U+54CD,U+54D1,U+54DF,U+54EE,U+54F2,U+5501,U+5506,U+5510,U+552F,U+553E,U+5544,U+5578,U+557C,U+5582,U+559C,U+55A7,U+55B3,U+55BB,U+55C5,U+55E1,U+55E3,U+55FD,U+5618,U+5631,U+5634,U+5636,U+563B,U+564E,U+566A,U+568F,U+56A3,U+56DB,U+56E0,U+56E2,U+56ED,U+56F4,U+56FE,U+5706,U+571F,U+5728,U+5740,U+574D,U+5750,U+575B,U+575E,U+5760,U+5766,U+578B,U+57A3,U+57DF,U+5802,U+5830,U+584C,U+5851,U+5854,U+5858,U+586B,U+5885,U+589E-589F,U+58EE,U+58F9,U+590F,U+5915-5916,U+591C,U+5929-592A,U+592E,U+5934,U+5937,U+5944,U+594F,U+5957,U+5979,U+5984,U+5986,U+5996,U+59A5,U+59D3-59D4,U+59DA,U+59E8,U+59FB,U+59FF,U+5A01,U+5A03,U+5A31,U+5A49,U+5A74,U+5A7F,U+5AB3,U+5ACC,U+5B50,U+5B55,U+5B57,U+5B59,U+5B5C-5B5D,U+5B66,U+5B70,U+5B83,U+5B85,U+5B87,U+5B8B-5B8C,U+5B97,U+5B99,U+5B9B-5B9C,U+5BA3,U+5BAA,U+5BB0,U+5BB4-5BB5,U+5BBF,U+5BC5,U+5BD3,U+5BE8,U+5BFA-5BFB,U+5C09-5C0A,U+5C0F,U+5C24,U+5C27,U+5C39,U+5C3E,U+5C49,U+5C4B,U+5C51,U+5C55,U+5C5E,U+5C60,U+5C6F,U+5C79,U+5C7F,U+5C81,U+5CA9,U+5CB3,U+5CD9,U+5CE1,U+5CEA,U+5D16,U+5D2D,U+5DCD,U+5DDE,U+5DE1,U+5DE6,U+5DEB,U+5DF2-5DF3,U+5DF7,U+5E05,U+5E0C,U+5E10,U+5E16,U+5E1A,U+5E1C,U+5E27,U+5E2D,U+5E78,U+5E7C-5E7D,U+5E84,U+5E8F,U+5E94,U+5EA7,U+5EAD,U+5EB6,U+5EB8,U+5EF6-5EF7,U+5F02,U+5F15,U+5F20,U+5F26,U+5F2F,U+5F5D,U+5F62,U+5F64,U+5F66,U+5F70-5F71,U+5F79,U+5F80-5F81,U+5F90,U+5F92,U+5FA1,U+5FAA,U+5FAE,U+5FC3,U+5FC6,U+5FD7-5FD8,U+5FE0,U+5FE7,U+5FFB,U+6001-6002,U+600E,U+6014,U+601D,U+6027-6028,U+603B,U+6055,U+6064,U+606C,U+606F,U+607F,U+6089,U+609F-60A0,U+60A6,U+60AC,U+60CB,U+60D5,U+60DC,U+60DF,U+60F3,U+60FA,U+6108-6109,U+610F,U+611A,U+613F,U+6170,U+618E,U+61C8,U+620A,U+620C-620D,U+620F,U+6211,U+6218,U+6240,U+624E,U+6258,U+6267,U+626C,U+627E,U+6291-6293,U+6295,U+6298,U+62AC,U+62BC,U+62C4,U+62D3,U+62D6,U+62D9,U+62DB,U+62E5,U+62E9,U+62EF,U+62F4,U+62FD,U+6307,U+6311,U+6316,U+631A,U+631D-631F,U+6323,U+632F,U+633A,U+633D,U+6342,U+6345,U+6349,U+635F,U+6380,U+638C,U+638F,U+6396,U+63A2,U+63A8-63A9,U+63B7,U+63CD,U+63D0,U+63D6,U+63E1,U+63F4,U+641C,U+642A,U+643A,U+6447,U+644A,U+6454,U+6458,U+6495,U+649E,U+64B0,U+64DE,U+6512,U+652F,U+653F,U+6548,U+6570,U+6574,U+6587,U+658B,U+659C,U+659F,U+65A1,U+65A9,U+65AF-65B0,U+65CB,U+65CF,U+65E0,U+65E8-65E9,U+65EC-65ED,U+65FA,U+6613-6614,U+661F-6620,U+6628,U+662D,U+663C,U+663E,U+6653,U+6655,U+665A,U+6664,U+6670,U+667A,U+6682,U+6687,U+6691,U+66D9,U+66F0,U+66F3,U+66FE-6700,U+6708-6709,U+6714,U+671B,U+672A,U+672D,U+672F,U+6731,U+673D,U+6742,U+674F,U+6756,U+675F,U+6761,U+6768,U+677E,U+6789,U+6790,U+6795,U+679D,U+67A2-67A3,U+67DE,U+67F1,U+6805,U+6808,U+6811,U+6813,U+6821,U+682A,U+6837,U+683D,U+6843,U+6845,U+684C,U+6850,U+6869,U+6876,U+68A7,U+68AD,U+68AF-68B0,U+68B3,U+68D5,U+68E0,U+6905,U+690D-690E,U+692D,U+6930,U+6954,U+6986,U+69A8,U+6A1F,U+6A31,U+6A61,U+6A80,U+6A84,U+6B23,U+6B32,U+6B47,U+6B62-6B63,U+6B66,U+6B6A,U+6B7B,U+6B83,U+6B89-6B8A,U+6B96,U+6BB7,U+6BC5,U+6BCB,U+6BE1,U+6BEF,U+6C27,U+6C34,U+6C38,U+6C40-6C41,U+6C50,U+6C5B,U+6C61,U+6C64,U+6C6A,U+6C70,U+6C79,U+6C82-6C83,U+6CB9,U+6CBB-6CBC,U+6CBE-6CBF,U+6CC4,U+6CE8,U+6CF0,U+6CF3,U+6CFB,U+6CFD,U+6D0B,U+6D17,U+6D32,U+6D3C,U+6D4A,U+6D59,U+6D74,U+6D82,U+6D88,U+6D8C,U+6D8E,U+6D95,U+6D9B,U+6DA1,U+6DA8,U+6DAF,U+6DB2,U+6DC4,U+6DC6,U+6DCC,U+6DD1,U+6DD8,U+6DE4,U+6DEB,U+6DF9,U+6DFB,U+6E0A,U+6E0D,U+6E14,U+6E1D,U+6E23,U+6E29,U+6E2D,U+6E38,U+6E4D,U+6E58,U+6E5B,U+6E7E,U+6E90,U+6EA2,U+6EAA,U+6EAF,U+6ECB,U+6ED3-6ED4,U+6EDE,U+6EE9,U+6F14,U+6F31,U+6F33,U+6F3E,U+6F4D,U+6F6D,U+6FA1,U+7076,U+707C,U+707E,U+708E,U+7099,U+70AD,U+70B8,U+70C1,U+70C3,U+70DB,U+70DF,U+70EB,U+70EF,U+70F7,U+7109,U+7130,U+7167,U+716E,U+7184,U+718A,U+718F,U+7199,U+719F,U+71D5,U+71E5,U+722A,U+7237,U+723D,U+7259,U+7269,U+7279-727A,U+7280,U+72B6,U+72B9,U+72ED,U+72F0-72F1,U+7329-732A,U+732E,U+733F,U+736D,U+7384,U+7389,U+738B,U+73A9,U+73B0,U+73CD,U+73E0,U+7410,U+7422,U+7476,U+74E6,U+74EE,U+7504,U+751C,U+7528-7529,U+7530-7531,U+754F,U+755C,U+758F,U+7591,U+75A1,U+75AB,U+75B9,U+75BC,U+75C7-75C8,U+75D2,U+75D4,U+75DB,U+75F0,U+761F,U+7626,U+762B,U+7634,U+7663,U+7682,U+7696,U+76B1,U+76C2,U+76C5,U+76C8,U+76CA,U+76CF-76D0,U+76F4,U+76F8,U+771F,U+7728-7729,U+773A,U+773C,U+7740-7741,U+7761,U+778E,U+77A9,U+77AC,U+77B3,U+77BB,U+77E3,U+77E5,U+77FD,U+7814,U+7816,U+781A,U+7827,U+7838,U+7852,U+7855,U+785D,U+786C,U+788E,U+7897,U+78B3,U+7956,U+795D,U+795F,U+7965,U+79B9,U+79C0-79C1,U+79C3,U+79CD,U+79DF,U+79E7,U+79E9,U+79FB,U+7A00,U+7A0E,U+7A1A,U+7A33,U+7A57,U+7A74,U+7A81,U+7A84,U+7A91-7A92,U+7A9D,U+7AD6,U+7AD9,U+7AE0,U+7AE5,U+7AF9,U+7B0B,U+7B11,U+7B51-7B52,U+7B97,U+7BB1,U+7BC6,U+7C7D,U+7C98,U+7C9F,U+7CA4-7CA5,U+7CD6,U+7CDF,U+7CFB,U+7D0A,U+7D20,U+7D22,U+7D2B,U+7D6E,U+7E82,U+7EA4,U+7EA6,U+7EAC,U+7EB5,U+7EB8-7EB9,U+7EBF,U+7EC4,U+7EC6-7EC8,U+7ECE,U+7EDA,U+7EDF,U+7EE3,U+7EE5-7EE6,U+7EEA,U+7EED,U+7EF4,U+7EFC-7EFD,U+7F00,U+7F18,U+7F28-7F29,U+7F51,U+7F69-7F6A,U+7F6E,U+7F72,U+7F8A,U+7F9E,U+7FA1,U+7FBD,U+7FC1,U+7FCC,U+7FD4,U+7FFC,U+8000,U+8005,U+800D,U+8018,U+8036,U+8038,U+804C,U+8083-8084,U+8086-8087,U+8096,U+8098,U+80A2,U+80B2,U+80BF-80C1,U+80C3,U+80CE,U+80F0,U+80F8,U+8102,U+810F,U+8131,U+8146,U+814B,U+8155,U+8165,U+8170,U+817A,U+817E-817F,U+819B,U+819D,U+81C0,U+81C3,U+81C6,U+81EA,U+81F3-81F4,U+81FB,U+8200,U+8206,U+8212,U+8214,U+821C,U+821E-821F,U+8237,U+8247,U+8258,U+8273,U+827A,U+828B,U+829C-829D,U+82AF,U+82BD,U+82C7,U+82CF,U+82D1,U+82D4,U+82F1,U+8301,U+8335,U+8367,U+836B,U+836F,U+83B9,U+8404,U+840E,U+8424-8425,U+8427,U+8457,U+846C,U+849C,U+84B8,U+84C4,U+84D1,U+8517,U+851A,U+852C,U+8574,U+859B,U+85AA,U+85AF,U+85E4,U+85FB,U+8638,U+865A,U+865E,U+867D-867E,U+8681,U+868A,U+869C,U+86A4,U+86C0,U+86D9,U+86DB,U+86F0,U+86F9,U+8700,U+8712,U+8715,U+8717-8718,U+8747,U+874E,U+87F9,U+8840,U+8845,U+884C-884D,U+8854,U+8859,U+8863,U+8870,U+8877,U+8881,U+8892,U+8896,U+889C,U+88AD,U+88C5,U+88D4-88D5,U+892A,U+8944,U+897F,U+8981,U+8A00,U+8A79,U+8A89-8A8A,U+8BA8,U+8BAD-8BAF,U+8BB6,U+8BB8,U+8BBC,U+8BC1,U+8BC5,U+8BC8-8BCA,U+8BCC,U+8BD1,U+8BDB,U+8BE2-8BE3,U+8BE6,U+8BEC-8BED,U+8BEF,U+8BF1,U+8BF4-8BF5,U+8BF8,U+8C01,U+8C06,U+8C08,U+8C0A,U+8C10,U+8C13,U+8C1A,U+8C22-8C23,U+8C2D,U+8C4C,U+8C61,U+8C6B,U+8D1E,U+8D23-8D24,U+8D26,U+8D28,U+8D2A,U+8D2E,U+8D34,U+8D3C,U+8D43-8D44,U+8D4E,U+8D58,U+8D5A,U+8D5E,U+8D60,U+8D62,U+8D70,U+8D75,U+8D8A,U+8D9F,U+8DB3,U+8DBE,U+8DC3,U+8DF3,U+8E0A,U+8E0F,U+8E22,U+8E2A,U+8E44,U+8E4B,U+8E81,U+8EBA,U+8F67,U+8F69,U+8F6C,U+8F74,U+8F7D,U+8F93,U+8F95-8F97,U+8F99,U+8F9B,U+8FC2,U+8FC5,U+8FCE,U+8FD0,U+8FD9,U+8FDC-8FDD,U+8FE2,U+8FF0,U+8FFD,U+9000-9001,U+9003,U+9009-900A,U+900F-9010,U+9014,U+901A,U+901F-9020,U+9038,U+903E,U+9042,U+9047,U+9057,U+9065,U+906D-906E,U+9075,U+9080,U+9091,U+90A2,U+90AA,U+90AE,U+90B9,U+90C1,U+90D1,U+90E7,U+9149,U+914C,U+9157,U+915D-915E,U+9165,U+916E,U+9178,U+9189,U+9192,U+91C9,U+91CD-91CE,U+9488,U+949F,U+94A5,U+94A8,U+94BB,U+94C0-94C1,U+94DC,U+94E1,U+94E3,U+94F1,U+94F6,U+94F8,U+9500-9501,U+9508,U+950C,U+9511,U+9517,U+9521,U+9525,U+9528,U+9547,U+9576,U+95EE,U+95F2,U+95F8,U+95FB,U+9605,U+9609,U+960E,U+9633-9635,U+963B,U+9640,U+9650,U+9662,U+9668-9669,U+9676-9677,U+9685,U+968B,U+968F-9690,U+9699,U+969C,U+96A7,U+96C1,U+96C4-96C5,U+96CD,U+96E8,U+96EA,U+96FE,U+9700,U+9704,U+9707,U+971C,U+971E,U+9774,U+978B,U+97E6,U+97F3,U+97F5,U+9875,U+9879-987B,U+987D,U+9882,U+9884,U+9890,U+9893,U+9896,U+9898,U+989C,U+996E,U+9972,U+9985,U+9999,U+9A6D-9A6F,U+9A7B-9A7C,U+9A8C,U+9AA4,U+9AD3,U+9B03,U+9B4F,U+9C7C,U+9C9C,U+9E26,U+9E2D,U+9E2F,U+9E33,U+9E35,U+9E70,U+9ECD,U+9F20"
|
|
723
|
+
}),
|
|
724
|
+
Object.freeze({
|
|
725
|
+
family: "Aha Hand",
|
|
726
|
+
file: "wenkai-gb-4-375dc3b3.woff2",
|
|
727
|
+
bytes: 257596,
|
|
728
|
+
unicodeRange: "U+4E0C,U+4E10,U+4E15,U+4E1E,U+4E28,U+4E36,U+4E3F,U+4E47,U+4E5C,U+4E69,U+4E8D,U+4E93,U+4E98,U+4E9F-4EA0,U+4EB3,U+4EB5,U+4EBB,U+4EC2-4EC4,U+4EC9,U+4EDD-4EDE,U+4EE1,U+4EE8,U+4EEB,U+4EF3,U+4EF5,U+4F09,U+4F1B,U+4F22,U+4F25,U+4F27,U+4F2B,U+4F32,U+4F3D,U+4F57-4F58,U+4F5A,U+4F5D-4F5F,U+4F64-4F65,U+4F67,U+4F74,U+4F76,U+4F7B-4F7C,U+4F7E,U+4F83,U+4F89,U+4F8F,U+4F91,U+4F94,U+4FAA,U+4FAC,U+4FC5,U+4FCE,U+4FD1,U+4FDA,U+4FDC,U+4FDF,U+4FE3,U+4FE6,U+4FE8,U+4FEA,U+4FF3,U+4FF8,U+4FFE,U+500C,U+500F,U+501C,U+5025,U+5028-5029,U+502C-502E,U+5043,U+5048,U+504C,U+504E,U+5055,U+506C,U+507B,U+507E,U+50A5,U+50A7,U+50A9,U+50BA,U+50D6,U+50E6,U+50EC-50EE,U+5106-5107,U+510B,U+5140,U+5155-5156,U+516E,U+5181-5182,U+5196,U+51A2,U+51A5,U+51AB,U+51B1,U+51BC-51BD,U+51C7,U+51EB,U+51F5,U+51FC,U+5202,U+5208,U+520D-520E,U+522D,U+5233,U+523F-5240,U+524C,U+525C,U+525E,U+5261,U+527D,U+5281-5282,U+5290,U+5293,U+52A2,U+52AC-52AD,U+52BE,U+52D0,U+52D6,U+52F0,U+52F9,U+530D,U+530F-5310,U+5315,U+531A,U+5326,U+532E,U+533E,U+5345,U+535F,U+5363,U+5366,U+5369,U+536E,U+537A,U+538D,U+539D,U+53A3,U+53A5,U+53AE,U+53B6,U+53DF,U+53E8-53E9,U+53F1,U+53F5,U+53FB,U+53FD,U+5406,U+5412,U+5416,U+5421,U+5423,U+5432,U+5443,U+544B,U+5452-5454,U+5456-5457,U+5459,U+5464,U+5466,U+5471-5472,U+5476-5477,U+5482,U+5484,U+5494,U+549A-549B,U+549D,U+54A3-54A4,U+54A6-54A7,U+54A9-54AA,U+54AD,U+54B4,U+54BB,U+54BF,U+54C2,U+54CC,U+54CF-54D0,U+54D2-54D5,U+54D9-54DA,U+54DC-54DE,U+54E7,U+54F3,U+54FD,U+54FF,U+550F,U+5511,U+5514,U+551B,U+5520,U+5522-5523,U+5527,U+552A,U+5530,U+5533,U+5537,U+553C,U+553F,U+5541,U+5549,U+5550,U+5555-5556,U+555C,U+5567,U+556C-556D,U+5575-5577,U+557B,U+557E,U+5581,U+5583,U+5588,U+558B,U+558F,U+5591,U+5594,U+5599,U+559F,U+55B1,U+55B5,U+55B9,U+55BD-55BE,U+55C4,U+55C9,U+55CC-55CD,U+55D1-55D2,U+55D4,U+55D6,U+55DD,U+55DF,U+55E4-55E6,U+55E8,U+55EA-55EC,U+55EF,U+55F2-55F3,U+55F5,U+55F7,U+55FE,U+5600-5601,U+5608,U+560C,U+560F,U+561E-561F,U+5623-5624,U+5627,U+562C-562D,U+5639,U+564C-564D,U+5654,U+5657-5659,U+565C,U+5662,U+5664,U+5669,U+566B,U+5671,U+567B-567C,U+5685-5686,U+5693,U+56AF,U+56D4,U+56D7,U+56DD,U+56DF,U+56E1,U+56EB,U+56F5,U+56F9,U+56FF,U+5704,U+5709-570A,U+571C,U+5729-572A,U+572C,U+572E-572F,U+5733,U+5739,U+573B,U+5742,U+574C,U+575C,U+5768-5769,U+576B,U+576D,U+5773,U+5776,U+577B-577C,U+5785-5786,U+578C,U+5793,U+57A0-57A1,U+57A4,U+57A7,U+57A9,U+57AD,U+57B2,U+57B4,U+57B8,U+57CF,U+57D2,U+57D5,U+57D8-57DA,U+57DD,U+57E4,U+57ED,U+57EF,U+57F4,U+57F8,U+57FD,U+5800,U+5807,U+580B,U+580D,U+5819,U+581E,U+5820,U+5844,U+5865,U+586C,U+587E,U+5880-5881,U+5889,U+589A,U+58BC,U+58C5,U+58D1,U+5902,U+5914,U+5919,U+5924-5925,U+592D,U+593C,U+5941-5942,U+5955,U+5958,U+595A,U+5B34,U+5B5B,U+5B6C,U+5C22,U+5C25,U+5C2C,U+5C34,U+5C7A,U+5C88,U+5C8C-5C8D,U+5C90-5C91,U+5C96,U+5C98-5C9A,U+5C9C,U+5CA2-5CA3,U+5CAB-5CAC,U+5CB1,U+5CB5,U+5CB7,U+5CBD,U+5CC1,U+5CC4,U+5CCB,U+5CD2,U+5CE4-5CE5,U+5D02-5D03,U+5D06,U+5D1B,U+5D1E,U+5D24,U+5D26-5D27,U+5D2E,U+5D34,U+5D3D-5D3E,U+5D4A-5D4B,U+5D58,U+5D5B,U+5D5D,U+5D69,U+5D6B-5D6C,U+5D6F,U+5D74,U+5D82,U+5D99,U+5D9D,U+5DB7,U+5DC5,U+5DEF,U+5DFD,U+5E0F,U+5E11,U+5E14,U+5E19,U+5E31,U+5E37,U+5E3B-5E3C,U+5E44,U+5E54,U+5E5B,U+5E5E,U+5E61,U+5E80,U+5E8B,U+5E91,U+5E96,U+5EA0,U+5EA5,U+5EB3,U+5EB5,U+5EB9,U+5EBE,U+5ED1-5ED2,U+5EDB,U+5EE8,U+5EEA,U+5EF4,U+5EFE-5EFF,U+5F01,U+5F08,U+5F0B,U+5F11,U+5F61,U+5F73,U+5F77,U+5F82,U+5F87,U+5F89,U+5F8C,U+5F95,U+5F99,U+5F9C,U+5FA8,U+5FAD,U+5FB5,U+5FBC,U+5FD2,U+61FF,U+624C,U+626A,U+629F,U+62BB,U+62CA,U+62D7,U+62DA,U+62EE,U+62F6,U+6322,U+6339,U+6343,U+634B,U+6369,U+636D,U+6371,U+637A,U+638A,U+638E,U+63AC-63AE,U+63B4,U+63BC,U+63BE,U+63C4,U+63C6,U+63CE,U+63DE,U+63E0,U+63F2,U+63F6,U+63F8,U+63FF,U+640B-640C,U+641B,U+6420-6421,U+6426,U+6441,U+6445,U+6452,U+645E,U+646D,U+647A,U+6484,U+6496,U+6499,U+64B7-64B8,U+64BA,U+64C0,U+64D0,U+64D7,U+64E2,U+64E4,U+6509,U+6525,U+652E,U+6538,U+6BD3,U+6C10,U+6C3D,U+6C46,U+71EE,U+723B,U+72AD,U+72B0,U+72B4,U+72B7-72B8,U+72C1,U+72C3,U+72CD-72CE,U+72D2,U+72E8-72E9,U+72EF,U+72F2-72F4,U+72F7,U+72FA-72FB,U+7301,U+7303,U+730A,U+7313,U+7315,U+7317,U+731D-731E,U+7321-7322,U+7325,U+732C,U+7331,U+7338-7339,U+734D,U+7350,U+7357,U+7360,U+736C,U+736F,U+737E,U+750D,U+7519,U+755A,U+777E,U+77A2,U+77CD,U+7980,U+79BA,U+7C74,U+7F54,U+7FB8,U+8037,U+80E4,U+8114,U+81BA,U+821B,U+8279,U+827D,U+827F,U+8284,U+8288,U+828A,U+828E-828F,U+8291,U+8297-8299,U+829F,U+82A1,U+82A4,U+82A8-82AB,U+82AE,U+82B0,U+82B4,U+82B7-82B8,U+82BE,U+82C1,U+82C4,U+82C8,U+82CA-82CC,U+82CE,U+82D2-82D3,U+82D5,U+82D8,U+82DC,U+82E0-82E1,U+82E3-82E4,U+82F4,U+82F7,U+82FB,U+8306-8309,U+830C,U+830F,U+8311,U+8314-8315,U+8317,U+831A-831C,U+832D,U+832F,U+8331,U+8333-8334,U+833A,U+833C,U+8340,U+8343,U+8347,U+834F,U+8351,U+835B-835C,U+835E-8360,U+8365-8366,U+8368-836A,U+836C-836E,U+8378,U+837B-837D,U+8385,U+8392-8393,U+8398,U+839B-839C,U+839E,U+83A0,U+83A8-83AA,U+83B0,U+83B3-83B4,U+83B6,U+83B8,U+83BA,U+83BC,U+83C0-83C1,U+83C5,U+83D4,U+83D6,U+83D8,U+83DD,U+83DF,U+83E1,U+83E5,U+83EA,U+83F0,U+83F8-83F9,U+83FD,U+8401,U+8403,U+8406,U+840B,U+840F,U+8411,U+8418,U+841C,U+8426,U+8431,U+8438,U+843C,U+8446,U+8451,U+8459-845A,U+845C,U+8469,U+846D,U+8473,U+8476,U+8478,U+847A,U+8487-8489,U+848C,U+848E,U+8497,U+84A1,U+84AF,U+84B4,U+84B9-84BA,U+84BD,U+84BF,U+84C1,U+84CA,U+84CD,U+84D0,U+84D3,U+84E0,U+84E3,U+84E5-84E6,U+84F0,U+84FC,U+84FF,U+850C,U+851F,U+8538-853B,U+8543,U+8548,U+8556,U+8559,U+855E,U+8564,U+8568,U+8572,U+8579-857B,U+8585,U+8587,U+858F,U+859C,U+85A4,U+85A8,U+85AE,U+85B0,U+85B7,U+85B9,U+85C1,U+85D3,U+85DC,U+85FF,U+8605,U+8616,U+8627,U+8629,U+863C,U+8803,U+8862,U+886E,U+88A4,U+88D2,U+8A07,U+8BA0,U+8BA6-8BA7,U+8BAA,U+8BB4-8BB5,U+8BB7,U+8BC2-8BC3,U+8BCB,U+8BCE-8BCF,U+8BD2-8BD4,U+8BD6,U+8BD8-8BD9,U+8BDC,U+8BDF-8BE0,U+8BE4,U+8BE8-8BE9,U+8BEE,U+8BF0,U+8BF3,U+8BF6,U+8BF9,U+8BFC,U+8BFF-8C00,U+8C02,U+8C04,U+8C07,U+8C0C,U+8C0F,U+8C11-8C12,U+8C14-8C16,U+8C18-8C19,U+8C1B,U+8C1D,U+8C1F-8C21,U+8C25,U+8C27,U+8C2A-8C2B,U+8C2E-8C2F,U+8C32-8C33,U+8C35-8C36,U+8C73,U+8D53,U+8D5C-8D5D,U+8F94,U+9097,U+9099,U+909B,U+909D,U+90A1,U+90AC,U+90B0,U+90B3-90B4,U+90B6,U+90B8,U+90BA,U+90BE,U+90C4-90C5,U+90C7,U+90CF-90D0,U+90D3,U+90D7,U+90DB-90DC,U+90E2,U+90E6,U+90EB,U+90EF,U+90FE,U+9104,U+911E,U+9122-9123,U+912F,U+9131,U+9139,U+9143,U+9146,U+961D,U+9621-9622,U+962A,U+9631,U+963C-963D,U+9642,U+9649,U+9654,U+965F,U+9667,U+966C,U+9672,U+9674,U+9688,U+968D,U+9697,U+96B0,U+9765,U+98E7,U+9963,U+9967-996C,U+9974,U+9977,U+997D,U+9980,U+9984,U+9987,U+998A,U+998D,U+9990-9991,U+9993-9995,U+9997-9998,U+99A8,U+9B2F,U+9B32,U+9EC9,U+9F10,U+9F17,U+9F19,U+9FA0"
|
|
729
|
+
}),
|
|
730
|
+
Object.freeze({
|
|
731
|
+
family: "Aha Hand",
|
|
732
|
+
file: "wenkai-gb-5-d0359bbc.woff2",
|
|
733
|
+
bytes: 278908,
|
|
734
|
+
unicodeRange: "U+4E2C,U+5216,U+54AB,U+584D,U+5981,U+5983,U+598D,U+5997,U+599E,U+59A3-59A4,U+59A9-59AB,U+59AF,U+59B2,U+59BE,U+59CA,U+59D2,U+59D7-59D8,U+59DD,U+59E3,U+59F9,U+5A05-5A06,U+5A08-5A09,U+5A0C,U+5A11,U+5A13,U+5A23,U+5A32,U+5A34,U+5A3C,U+5A40,U+5A4A,U+5A55,U+5A62,U+5A67,U+5A75,U+5A77,U+5A7A,U+5A9B,U+5AAA,U+5AB2,U+5AB5,U+5AB8,U+5ABE,U+5AD2,U+5AD4,U+5AD6,U+5AD8,U+5ADC,U+5AE0,U+5AE3,U+5AE6,U+5AEB,U+5AF1,U+5B09,U+5B16-5B17,U+5B32,U+5B37,U+5B40,U+5B51,U+5B53,U+5B5A,U+5B62,U+5B65,U+5B71,U+5B73,U+5B80,U+5B84,U+5B93,U+5B95,U+5BA5,U+5BB8,U+5BE4,U+5BEE,U+5BF0,U+5C15,U+5C1C,U+5C3B,U+5C50,U+5C59,U+5C63,U+5C66,U+5C6E,U+5DDB,U+5E7A,U+5F29-5F2A,U+5F2D,U+5F3C,U+5F40,U+5F50,U+5F56-5F58,U+5FC4,U+5FC9,U+5FCF-5FD1,U+5FD6,U+5FDD,U+5FE1,U+5FE4,U+5FEA,U+5FED-5FEE,U+5FF8,U+5FFE,U+6003-6006,U+600A,U+600D,U+600F,U+6019,U+601B,U+6021,U+6026,U+6029,U+602B,U+6035,U+603C,U+603F,U+6041-6042,U+6059-605A,U+605D,U+6063,U+6067,U+606A,U+6078-607B,U+607D,U+6083,U+608C,U+6092,U+6096,U+609A-609B,U+609D,U+60AB,U+60AD,U+60B1,U+60B4,U+60BB,U+60C6,U+60D8,U+60DA,U+60DD,U+60EC,U+60F4,U+6100,U+6106,U+610D-610E,U+6115,U+6120,U+6123,U+6126,U+612B,U+614A,U+615D,U+6175,U+6194,U+619D,U+61A7,U+61A9,U+61AC,U+61B7,U+61CB,U+61D1,U+61D4,U+61F5,U+6206,U+620B,U+6215,U+6217,U+621B,U+621F,U+6221-6222,U+6224-6225,U+622C,U+623D-623E,U+6243,U+6248-6249,U+6308,U+6332,U+63B0,U+6434,U+643F,U+64D8,U+6534-6535,U+6555,U+656B,U+6590,U+6593,U+65AB,U+65BC,U+65C3-65C4,U+65C6,U+65CC,U+65CE,U+65D2,U+65D6,U+65EE-65F0,U+6600,U+6603,U+660A,U+6615,U+6619,U+661D,U+6631,U+6634-6636,U+6641,U+664F,U+6654,U+6656-6657,U+665F,U+6661,U+6677,U+6684,U+668C,U+669D,U+66A7,U+66B9,U+66BE,U+66DB-66DC,U+66E6,U+66E9,U+66F7,U+670A,U+6710,U+6715,U+6726,U+6748,U+674C,U+6753,U+675E,U+6769-676A,U+6772-6773,U+6775,U+6777,U+677C,U+6787,U+678B,U+6798,U+679E,U+67A5,U+67A7-67A8,U+67AD,U+67B0,U+67B3,U+67B5,U+67B8,U+67C1,U+67C3,U+67D8-67DA,U+67DD,U+67E2,U+67E9,U+67F0,U+67FD,U+6800,U+6809-680A,U+680C,U+680E,U+681D,U+6829,U+6832-6833,U+683E,U+6840-6841,U+6844,U+6849-684A,U+684E,U+6855,U+6860-6862,U+6864,U+6866-6867,U+686B,U+6874,U+6877,U+6883,U+688F,U+6893,U+68B5,U+68C2,U+68E3,U+68F0,U+68F9,U+68FC,U+6901,U+690B,U+6910,U+691F-6920,U+6924,U+6934,U+6939,U+6942,U+6957,U+695D,U+6960,U+6963,U+6966,U+696B,U+696E,U+6971,U+6978-6979,U+6980,U+6984,U+6987-6989,U+698D,U+6995,U+6998,U+699B,U+69A7,U+69AB,U+69AD,U+69B1,U+69BB,U+69C1,U+69CA,U+69CC,U+69CE,U+69D4,U+69DF-69E0,U+69ED,U+69F2,U+69FF,U+6A17-6A18,U+6A28,U+6A2F,U+6A35,U+6A3D-6A3E,U+6A44,U+6A50,U+6A58,U+6A5B,U+6A65,U+6A79,U+6A7C,U+6A8E,U+6A90-6A91,U+6A97,U+6AA0,U+6AA9,U+6AAB,U+6B24,U+6B37,U+6B39,U+6B43,U+6B46,U+6B59,U+6B81-6B82,U+6B84,U+6B87,U+6B8D,U+6B92-6B93,U+6B9A-6B9B,U+6BA1,U+6BAA,U+6BB3,U+6BC2,U+6BEA,U+6BF3,U+6BF5,U+6BF9,U+6BFD,U+6C05-6C07,U+6C0D,U+6C15,U+6C18-6C1A,U+6C21,U+6C24,U+6C29-6C2A,U+6C32,U+6C35,U+6C4A,U+6C54,U+6C5C,U+6C68-6C69,U+6C74,U+6C76,U+6C85-6C86,U+6C8C,U+6C90,U+6C93-6C94,U+6CA3,U+6CA9,U+6CAD,U+6CB1-6CB2,U+6CD0,U+6CD3-6CD4,U+6CD6-6CD7,U+6CE0,U+6CEB,U+6CEE-6CEF,U+6CF1,U+6CF6-6CF8,U+6CFA,U+6CFE,U+6D04,U+6D07,U+6D0C,U+6D0E,U+6D19-6D1A,U+6D27,U+6D2B,U+6D2E,U+6D33,U+6D35,U+6D39,U+6D43,U+6D48,U+6D4D,U+6D4F,U+6D52,U+6D54,U+6D5C,U+6D5E,U+6D60,U+6D63,U+6D6F,U+6D7C,U+6D91,U+6D93-6D94,U+6D9E,U+6DA0,U+6DAB,U+6DAE,U+6DBF,U+6DC5,U+6DC7,U+6DD9,U+6DDD-6DDE,U+6DE0,U+6DE6,U+6DFC,U+6E0C,U+6E0E,U+6E11,U+6E16,U+6E1A,U+6E25,U+6E2B,U+6E32,U+6E44,U+6E4E,U+6E53-6E54,U+6E5F,U+6E6B,U+6E6E,U+6E86,U+6E8F,U+6E98,U+6E9F,U+6EA5,U+6EA7,U+6EB1-6EB2,U+6EB4,U+6EB7,U+6EBB,U+6EBD,U+6EC2,U+6ECF,U+6ED5,U+6ED7,U+6EDF-6EE0,U+6EE2,U+6EF9,U+6F09,U+6F15,U+6F24,U+6F29-6F2A,U+6F2D,U+6F2F,U+6F36,U+6F46-6F47,U+6F4B,U+6F62,U+6F72,U+6F74,U+6F78,U+6F7A,U+6F7C,U+6F89,U+6F8C-6F8D,U+6FA7,U+6FB6,U+6FB9,U+6FC2,U+6FC9,U+6FD1,U+6FDE,U+6FE0-6FE1,U+6FEE-6FEF,U+701A-701B,U+7023,U+7035,U+7039,U+704F,U+705E,U+706C,U+7080,U+7085,U+7096,U+709C-709D,U+70AB,U+70B1,U+70B7,U+70BB,U+70C0,U+70CA,U+70E8,U+7110,U+7113,U+7116,U+7118,U+712F,U+7131,U+7145,U+714A,U+715C,U+7166,U+7168,U+7172-7173,U+7178,U+717A,U+7198,U+71A0,U+71A8,U+71B3,U+71B5,U+71B9,U+71D4,U+71E0,U+71E7,U+71F9,U+721D,U+7228,U+7230,U+723F,U+724D,U+7252,U+7256,U+725D,U+7266,U+726E-726F,U+727E-727F,U+7284,U+728B,U+728D,U+728F,U+7292,U+729F,U+7337,U+7352,U+738E,U+7391,U+739F,U+73A2,U+73AE,U+73B3,U+73B7,U+73BA,U+73C0,U+73C2,U+73C8-73C9,U+73CF,U+73D1,U+73D9,U+73DE,U+73E5,U+73E7,U+73E9,U+73F2,U+740A,U+740F,U+741A-741B,U+7425-7426,U+7428,U+742A,U+742C,U+742E,U+7430,U+7441,U+7455,U+7457,U+7459,U+745B-745C,U+746D,U+7477,U+747E,U+7480-7481,U+7487,U+748B,U+748E,U+7490,U+749C,U+749E,U+74A7-74A9,U+74BA,U+74D2,U+74EF,U+74F4,U+74FF,U+750F,U+7511,U+7513,U+752F,U+753E,U+757F,U+77F6,U+77F8,U+7800,U+7809,U+7811,U+7817-7818,U+781C-781D,U+782D,U+793B,U+7940,U+7946,U+7949,U+7953,U+7957,U+795A-795C,U+7960,U+7962,U+7967,U+796F,U+797A,U+7985,U+798A,U+799A,U+79A7,U+79B3,U+7E9F,U+7EA1,U+7EA3,U+7EA5,U+7EA8-7EA9,U+7EAD,U+7EB0,U+7EBE,U+7EC0-7EC2,U+7EC9,U+7ECB-7ECC,U+7ED0,U+7ED4,U+7ED7,U+7EDB,U+7EE0-7EE1,U+7EE8,U+7EEB,U+7EEE-7EEF,U+7EF1-7EF2,U+7EF6,U+7EFA-7EFB,U+7EFE,U+7F01-7F03,U+7F07-7F08,U+7F0B-7F0D,U+7F0F,U+7F11-7F12,U+7F17,U+7F19,U+7F1B-7F1C,U+7F1F,U+7F21-7F27,U+7F2A-7F2D,U+7F2F-7F33,U+7F35,U+7FBC,U+8004,U+8006,U+807F-8080,U+8093,U+809C,U+809F,U+80AB,U+80AD,U+80B1,U+80B4,U+80B7,U+80BC-80BD,U+80C2,U+80C4,U+80CD,U+80D7,U+80D9,U+80DB,U+80DD,U+80E7-80ED,U+80F1-80F2,U+80F4,U+80FC,U+810D-810E,U+8112,U+8118,U+811E,U+812C,U+8132,U+8136,U+8148,U+814C,U+8153,U+8159-815A,U+8160,U+8167,U+8169,U+816D,U+8171,U+8174,U+817C-817D,U+8182,U+8188,U+8191,U+81A3,U+81A6,U+81AA,U+81BB,U+81C1,U+81CA,U+81CC,U+81E7,U+8274,U+8662,U+8930,U+89C7,U+89CA-89CC,U+89CE-89D1,U+89F3,U+8B07,U+8C5A,U+8D32-8D33,U+8D36,U+8D3B,U+8D3D,U+8D40,U+8D45-8D49,U+8D4D,U+8D55,U+8D59,U+8E47,U+8ECE,U+8F6B,U+8F6D,U+8F71-8F73,U+8F75-8F7A,U+8F7C,U+8F7E,U+8F81-8F82,U+8F84,U+8F87,U+8F8B,U+8F8D-8F8F,U+8F98,U+8F9A,U+8FB6,U+8FD3,U+8FD5,U+8FE4-8FE6,U+8FE8-8FE9,U+8FEE,U+8FF3,U+9004-9005,U+900B,U+900D,U+9011,U+9016,U+9021,U+9026,U+902D,U+902F,U+9035-9036,U+9044,U+9050-9052,U+9058,U+905B,U+9062,U+9068,U+9074,U+907D,U+9082-9083,U+9088,U+908B,U+9095,U+95E9,U+95EB,U+95F1,U+95F3,U+95F5-95F6,U+95FC,U+95FE,U+9603-9604,U+9606,U+9608,U+960A-960D,U+960F,U+9612,U+9615-9617,U+9619-961A,U+96B3,U+97EA-97EC,U+987C,U+98D1-98D3,U+98D5,U+98D9-98DA,U+9A75,U+9A77-9A78,U+9A7A,U+9A7D,U+9A7F-9A81,U+9A85,U+9A88,U+9A8A,U+9A90,U+9A92-9A93,U+9A96,U+9A98,U+9A9B-9AA0,U+9AA2-9AA3,U+9AA5,U+9AA7,U+9B3B,U+9F51"
|
|
735
|
+
}),
|
|
736
|
+
Object.freeze({
|
|
737
|
+
family: "Aha Hand",
|
|
738
|
+
file: "wenkai-gb-6-a238b41c.woff2",
|
|
739
|
+
bytes: 307604,
|
|
740
|
+
unicodeRange: "U+5D47,U+6549,U+659B,U+66A8,U+74DE,U+74E0,U+752C,U+753A,U+7540,U+7548,U+754B,U+754E,U+755B,U+7572,U+7579,U+7583,U+758B,U+7592,U+7594,U+7596,U+759D,U+75A0,U+75A3,U+75AC,U+75B0-75B1,U+75B3-75B4,U+75B8,U+75C2-75C4,U+75CD,U+75D6,U+75E3-75E4,U+75E6-75E8,U+75EB,U+75F1,U+75FC,U+75FF-7600,U+7603,U+7605,U+760A,U+760C,U+7610,U+7615,U+7617-7619,U+761B,U+7620,U+7622,U+7625,U+762D,U+7630,U+7633,U+7635,U+763C,U+763E-7640,U+7643,U+764D,U+7654,U+7656,U+765C,U+765E,U+766B,U+766F,U+7688,U+768E,U+7693,U+7699,U+76A4,U+76B2,U+76B4,U+76CD,U+76E5,U+76F1,U+76F9,U+7704,U+7707-7708,U+770D,U+7719-771A,U+7722,U+7726,U+772D,U+7735,U+7738,U+7743,U+7747,U+7750-7751,U+775A,U+7762,U+7765,U+7768,U+777D,U+777F-7780,U+778C-778D,U+7791,U+779F-77A0,U+77B0,U+77B5,U+77BD,U+77BF,U+77DC,U+77E7,U+77EC,U+781F,U+7823,U+7825-7826,U+7829,U+782C,U+7839-783C,U+7847,U+784C,U+784E,U+7850,U+7856-7857,U+786A,U+786D,U+7887,U+7893,U+789A-789C,U+78A1,U+78A3,U+78A5,U+78B2,U+78B9,U+78C9,U+78D4,U+78D9,U+78EC,U+78F2,U+78F4,U+7905,U+7913,U+791E,U+7924,U+7934,U+79D5,U+79E3,U+79EB,U+79ED,U+7A02-7A03,U+7A06,U+7A14,U+7A1E,U+7A23,U+7A37,U+7A39,U+7A51,U+7A70,U+7A78-7A79,U+7A80,U+7A86,U+7A88,U+7A95,U+7AA0,U+7AA6,U+7AA8,U+7AAC-7AAD,U+7AB3,U+7AE6,U+7AFA,U+7AFD,U+7B03-7B04,U+7B08,U+7B0A,U+7B0F,U+7B15,U+7B19,U+7B1E,U+7B20,U+7B24-7B25,U+7B2A-7B2B,U+7B2E,U+7B31,U+7B33,U+7B38,U+7B3E,U+7B45,U+7B47,U+7B4C,U+7B58,U+7B5A,U+7B5D,U+7B60,U+7B62,U+7B6E,U+7B71-7B72,U+7B75,U+7B7B,U+7B85,U+7B90,U+7B9C-7B9D,U+7BA2,U+7BA6-7BA8,U+7BAA-7BAC,U+7BB4,U+7BB8,U+7BC1,U+7BCC,U+7BD1,U+7BDA,U+7BDD,U+7BE5-7BE6,U+7BEA,U+7BFC,U+7BFE,U+7C0B-7C0C,U+7C0F,U+7C16,U+7C1F,U+7C26,U+7C2A,U+7C38,U+7C40-7C41,U+7C7C,U+7C91,U+7C9C-7C9E,U+7CA2,U+7CB2,U+7CBC-7CBD,U+7CC1,U+7CC5,U+7CC7-7CC8,U+7CCC-7CCD,U+7CD7,U+7CE8,U+7CF8,U+7D77,U+7DA6,U+7DAE,U+7E3B,U+7E47,U+7E9B,U+7F36,U+7F42,U+7F44-7F45,U+7F58,U+7F5F,U+7F61,U+7F68,U+7F71,U+7F74,U+7F79,U+7F7E,U+7F81,U+7F9D,U+7F9F,U+7FA7,U+7FAF-7FB0,U+7FB2,U+7FBF,U+7FCA,U+7FCE,U+7FD5,U+7FE1,U+7FE5-7FE6,U+7FE9,U+7FEE,U+7FF3,U+800B,U+8012,U+8014,U+8016,U+801C,U+8020,U+8022,U+8025-8029,U+8031,U+8035,U+8043,U+8046,U+804D,U+8052,U+8069,U+8071,U+80E5,U+81EC,U+81FE,U+8201-8202,U+8204,U+8210,U+8221-8223,U+8228,U+822B,U+822D,U+822F,U+8233-8234,U+8238,U+823B,U+823E,U+8244,U+8249,U+824B,U+824F,U+825A,U+825F,U+8268,U+826E,U+864D,U+8654,U+866C,U+866E,U+867A-867C,U+867F,U+868B,U+868D,U+8693,U+869D,U+86A3,U+86A7-86AA,U+86AC,U+86AF-86B1,U+86B4-86B6,U+86BA,U+86C4,U+86C9,U+86CE-86D1,U+86D8,U+86DE-86DF,U+86E9,U+86ED,U+86F1-86F4,U+86F8,U+8703,U+8707-870A,U+870D,U+8713,U+871A,U+871E,U+8722-8723,U+8725,U+8729,U+872E,U+8731,U+8734,U+8737,U+873B,U+873E-873F,U+8748,U+874C,U+8753,U+8759,U+8760,U+8763-8765,U+876E,U+8770,U+877B-877E,U+8782-8783,U+8785,U+8788,U+878B,U+8793,U+8797,U+87A8,U+87AB-87AD,U+87AF,U+87B3,U+87B5,U+87BD,U+87C0,U+87C6,U+87CA-87CB,U+87D1-87D3,U+87DB,U+87E0,U+87E5,U+87EA,U+87EE,U+87FE,U+880A,U+8813,U+8816,U+881B,U+8821,U+8832,U+8839,U+883C,U+8844,U+8864,U+8869,U+8872,U+887D-887F,U+8882,U+8885,U+8888,U+88A2,U+88B7,U+88BC,U+88C6,U+88C9,U+88CE,U+88D8,U+88DF,U+88E2-88E3,U+88E5,U+88E8,U+88F0-88F1,U+88FC,U+88FE,U+890A,U+8913,U+8919-891B,U+8921,U+892B,U+8934,U+8936,U+8941,U+895E,U+8966,U+897B,U+8983,U+89D6,U+89DA,U+89DC,U+89DE,U+89E5,U+89EB,U+89EF,U+8A3E,U+8A48,U+8B26,U+8C47,U+8C49,U+8C55,U+8C78,U+8C82,U+8C85,U+8C8A,U+8C94,U+8C98,U+8D67,U+8D6D,U+8D73,U+8D84,U+8D91,U+8D94,U+8DB1,U+8DB5,U+8DB8,U+8DBA,U+8DBC,U+8DBF,U+8DC4,U+8DC6,U+8DCE-8DCF,U+8DD6-8DD7,U+8DDA-8DDB,U+8DDE,U+8DE3-8DE4,U+8DEB-8DEC,U+8DF7-8DF9,U+8DFB,U+8DFD,U+8E05,U+8E09,U+8E14,U+8E1D,U+8E1F,U+8E23,U+8E2C,U+8E2E-8E2F,U+8E31,U+8E35,U+8E39-8E3A,U+8E3D,U+8E40-8E42,U+8E49-8E4A,U+8E51-8E52,U+8E59,U+8E69,U+8E6F-8E70,U+8E74,U+8E76,U+8E7C,U+8E85,U+8E8F-8E90,U+8E94,U+8E9C,U+8E9E,U+914A,U+914E-9150,U+9161-9162,U+9164,U+9169,U+916F-9170,U+9172,U+9174,U+9179,U+917D-917E,U+9185,U+918C-918D,U+9190-9191,U+91A2-91A3,U+91AA,U+91AD-91AF,U+91B4-91B5,U+91BA,U+928E,U+92AE,U+92C8,U+933E,U+936A,U+938F,U+93CA,U+93D6,U+943E,U+946B,U+9485-9487,U+948A-948D,U+948F-9490,U+9494-9495,U+9497,U+949A-949C,U+94A3-94A4,U+94AA-94AD,U+94AF-94B0,U+94B2,U+94B4,U+94B6-94BA,U+94BC-94BD,U+94BF,U+94C4,U+94C8-94CE,U+94D0-94D2,U+94D5-94D9,U+94DB,U+94DE-94E0,U+94E2,U+94E4-94E5,U+94E7-94EB,U+94EE-94EF,U+94F3-94F5,U+94F7,U+94F9,U+94FC-94FD,U+94FF,U+9502-9503,U+9506-9507,U+9509-950A,U+950D-950F,U+9512-9516,U+9518,U+951B,U+951D-951F,U+9522,U+9529-952C,U+9531-9532,U+9534-9538,U+953A,U+953C,U+953E-953F,U+9542,U+9544-9546,U+9549,U+954C,U+954E-954F,U+9552-9554,U+9556-9559,U+955B,U+955D-955F,U+9561-9562,U+9564-956C,U+956F,U+9571-9573,U+96B9,U+96BC-96BD,U+96C9,U+96CE,U+96D2,U+96E0,U+96E9,U+96EF,U+96F3,U+9701,U+9706,U+9708,U+970E-970F,U+972A,U+972D,U+9730,U+973E,U+9753,U+977C,U+9785,U+9791-9792,U+9794,U+97A3,U+97AB,U+97AF,U+97B2,U+97B4,U+9878,U+9880,U+9883,U+9889,U+988C-988D,U+988F,U+9894,U+989A-989B,U+989E-989F,U+98A1-98A2,U+98A5-98A6,U+98E8,U+990D,U+992E,U+9954-9955,U+99A5,U+9AB0-9AB1,U+9AB6-9AB7,U+9ABA,U+9ABC,U+9AC0-9AC2,U+9AC5,U+9ACB-9ACC,U+9AD1,U+9ADF,U+9AE1,U+9AE6,U+9AEB,U+9AED,U+9AEF,U+9AF9,U+9AFB,U+9B08,U+9B0F,U+9B13,U+9B1F,U+9B23,U+9B43,U+9B45,U+9B47-9B49,U+9B4D,U+9B51,U+9C7F,U+9C82,U+9C85-9C88,U+9C8B,U+9C8E,U+9C90-9C92,U+9C94-9C95,U+9C9A-9C9B,U+9C9E-9CA3,U+9CA5-9CA9,U+9CAB,U+9CAD-9CAE,U+9CB0-9CB7,U+9CBA-9CBD,U+9CC4-9CC7,U+9CCA-9CD0,U+9CD3-9CD5,U+9CD7-9CD9,U+9CDC-9CDD,U+9CDF,U+9CE2,U+9E20,U+9E22,U+9E28-9E2C,U+9E31-9E32,U+9E36-9E3A,U+9E3E,U+9E41-9E42,U+9E44,U+9E46-9E49,U+9E4B-9E4C,U+9E4E,U+9E51,U+9E55,U+9E57-9E58,U+9E5A-9E5C,U+9E5E,U+9E63,U+9E66-9E6D,U+9E71,U+9E73,U+9E7E,U+9E82,U+9E87-9E88,U+9E8B,U+9E92,U+9E9D,U+9E9F,U+9EB4,U+9EB8,U+9EBD-9EBE,U+9ECF,U+9EDB-9EDD,U+9EDF-9EE0,U+9EE2,U+9EE5,U+9EE7,U+9EE9-9EEA,U+9EEF,U+9EF9,U+9EFB-9EFC,U+9EFE,U+9F0B,U+9F0D,U+9F22,U+9F2C,U+9F2F,U+9F37,U+9F39,U+9F3D-9F3E,U+9F44,U+9F80,U+9F83,U+9F85-9F8A,U+9F8C,U+9F9B"
|
|
741
|
+
})
|
|
742
|
+
]);
|
|
743
|
+
//#endregion
|
|
744
|
+
//#region src/host/web-fetch.js
|
|
745
|
+
const LOCAL_ADDRESS_MESSAGE = "Local network addresses are not supported";
|
|
746
|
+
var AddressError = class extends Error {
|
|
747
|
+
constructor(message = LOCAL_ADDRESS_MESSAGE) {
|
|
748
|
+
super(message);
|
|
749
|
+
this.name = "AddressError";
|
|
750
|
+
this.code = "bad-url";
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
const V4_BLOCKED = [
|
|
754
|
+
["0.0.0.0", 8],
|
|
755
|
+
["10.0.0.0", 8],
|
|
756
|
+
["100.64.0.0", 10],
|
|
757
|
+
["127.0.0.0", 8],
|
|
758
|
+
["169.254.0.0", 16],
|
|
759
|
+
["172.16.0.0", 12],
|
|
760
|
+
["192.0.0.0", 24],
|
|
761
|
+
["192.0.2.0", 24],
|
|
762
|
+
["192.88.99.0", 24],
|
|
763
|
+
["192.168.0.0", 16],
|
|
764
|
+
["198.18.0.0", 15],
|
|
765
|
+
["198.51.100.0", 24],
|
|
766
|
+
["203.0.113.0", 24],
|
|
767
|
+
["224.0.0.0", 4],
|
|
768
|
+
["240.0.0.0", 4]
|
|
769
|
+
].map(([base, bits]) => [v4Number(base), bits]);
|
|
770
|
+
const V6_BLOCKED = [
|
|
771
|
+
["fc00::", 7],
|
|
772
|
+
["fe80::", 10],
|
|
773
|
+
["fec0::", 10],
|
|
774
|
+
["ff00::", 8],
|
|
775
|
+
["100::", 64],
|
|
776
|
+
["64:ff9b:1::", 48],
|
|
777
|
+
["2001::", 32],
|
|
778
|
+
["2001:2::", 48],
|
|
779
|
+
["2001:10::", 28],
|
|
780
|
+
["2001:20::", 28],
|
|
781
|
+
["2001:db8::", 32]
|
|
782
|
+
].map(([base, bits]) => [v6Bytes(base), bits]);
|
|
783
|
+
function v4Number(address) {
|
|
784
|
+
const parts = address.split(".").map(Number);
|
|
785
|
+
return (parts[0] << 24 >>> 0) + (parts[1] << 16) + (parts[2] << 8) + parts[3] >>> 0;
|
|
786
|
+
}
|
|
787
|
+
function v4Public(address) {
|
|
788
|
+
const value = v4Number(address);
|
|
789
|
+
return !V4_BLOCKED.some(([base, bits]) => bits === 0 ? true : value >>> 32 - bits === base >>> 32 - bits);
|
|
790
|
+
}
|
|
791
|
+
function v6Bytes(address) {
|
|
792
|
+
let text = String(address).toLowerCase();
|
|
793
|
+
const zone = text.indexOf("%");
|
|
794
|
+
if (zone >= 0) text = text.slice(0, zone);
|
|
795
|
+
const groups = [];
|
|
796
|
+
const dotted = text.match(/(\d+\.\d+\.\d+\.\d+)$/u);
|
|
797
|
+
if (dotted) {
|
|
798
|
+
const value = v4Number(dotted[1]);
|
|
799
|
+
text = `${text.slice(0, -dotted[1].length)}${(value >>> 16).toString(16)}:${(value & 65535).toString(16)}`;
|
|
800
|
+
}
|
|
801
|
+
const [head, tail] = text.includes("::") ? text.split("::") : [text, null];
|
|
802
|
+
const left = head ? head.split(":") : [];
|
|
803
|
+
const right = tail ? tail.split(":") : [];
|
|
804
|
+
const fill = tail === null ? 0 : 8 - left.length - right.length;
|
|
805
|
+
for (const group of [
|
|
806
|
+
...left,
|
|
807
|
+
...Array(Math.max(0, fill)).fill("0"),
|
|
808
|
+
...right
|
|
809
|
+
]) groups.push(Number.parseInt(group || "0", 16));
|
|
810
|
+
const bytes = /* @__PURE__ */ new Uint8Array(16);
|
|
811
|
+
groups.slice(0, 8).forEach((group, index) => {
|
|
812
|
+
bytes[index * 2] = group >> 8 & 255;
|
|
813
|
+
bytes[index * 2 + 1] = group & 255;
|
|
814
|
+
});
|
|
815
|
+
return bytes;
|
|
816
|
+
}
|
|
817
|
+
function prefixMatches(bytes, base, bits) {
|
|
818
|
+
for (let bit = 0; bit < bits; bit += 8) {
|
|
819
|
+
const mask = 255 << 8 - Math.min(8, bits - bit) & 255;
|
|
820
|
+
if ((bytes[bit / 8] & mask) !== (base[bit / 8] & mask)) return false;
|
|
821
|
+
}
|
|
822
|
+
return true;
|
|
823
|
+
}
|
|
824
|
+
const embeddedV4 = (bytes, at) => `${bytes[at]}.${bytes[at + 1]}.${bytes[at + 2]}.${bytes[at + 3]}`;
|
|
825
|
+
function v6Public(address) {
|
|
826
|
+
const bytes = v6Bytes(address);
|
|
827
|
+
const zeros = (count) => bytes.subarray(0, count).every((byte) => byte === 0);
|
|
828
|
+
if (zeros(12) || zeros(10) && bytes[10] === 255 && bytes[11] === 255) return v4Public(embeddedV4(bytes, 12));
|
|
829
|
+
if (prefixMatches(bytes, v6Bytes("64:ff9b::"), 96)) return v4Public(embeddedV4(bytes, 12));
|
|
830
|
+
if (bytes[0] === 32 && bytes[1] === 2) return v4Public(embeddedV4(bytes, 2));
|
|
831
|
+
return !V6_BLOCKED.some(([base, bits]) => prefixMatches(bytes, base, bits));
|
|
832
|
+
}
|
|
833
|
+
function isPublicAddress(address) {
|
|
834
|
+
const value = String(address ?? "").replace(/^\[|\]$/gu, "");
|
|
835
|
+
const family = isIP(value.split("%")[0]);
|
|
836
|
+
if (family === 4) return v4Public(value);
|
|
837
|
+
if (family === 6) return v6Public(value);
|
|
838
|
+
return false;
|
|
839
|
+
}
|
|
840
|
+
const LOCAL_NAME = /(^|\.)(localhost|local|internal|home\.arpa)$/u;
|
|
841
|
+
function assertPublicHostname(hostname) {
|
|
842
|
+
const host = String(hostname ?? "").replace(/^\[|\]$/gu, "").replace(/\.+$/u, "").toLowerCase();
|
|
843
|
+
if (!host) throw new AddressError("This is not a valid web address");
|
|
844
|
+
if (isIP(host)) {
|
|
845
|
+
if (!isPublicAddress(host)) throw new AddressError();
|
|
846
|
+
return true;
|
|
847
|
+
}
|
|
848
|
+
if (LOCAL_NAME.test(host) || !host.includes(".")) throw new AddressError();
|
|
849
|
+
return false;
|
|
850
|
+
}
|
|
851
|
+
function createGuardedLookup({ resolve = lookup, allowed = isPublicAddress } = {}) {
|
|
852
|
+
return function guardedLookup(hostname, options, callback) {
|
|
853
|
+
const done = typeof options === "function" ? options : callback;
|
|
854
|
+
const wanted = typeof options === "object" && options ? options : {};
|
|
855
|
+
resolve(hostname, { all: true }, (error, addresses) => {
|
|
856
|
+
if (error) return done(error);
|
|
857
|
+
const list = (Array.isArray(addresses) ? addresses : []).map((entry) => typeof entry === "string" ? {
|
|
858
|
+
address: entry,
|
|
859
|
+
family: isIP(entry)
|
|
860
|
+
} : entry).filter((entry) => entry?.address);
|
|
861
|
+
if (!list.length) return done(Object.assign(/* @__PURE__ */ new Error(`No address for ${hostname}`), { code: "ENOTFOUND" }));
|
|
862
|
+
if (list.some((entry) => !allowed(entry.address))) return done(new AddressError());
|
|
863
|
+
const family = wanted.family === 4 || wanted.family === 6 ? wanted.family : 0;
|
|
864
|
+
const usable = family ? list.filter((entry) => entry.family === family) : list;
|
|
865
|
+
const chosen = usable.length ? usable : list;
|
|
866
|
+
if (wanted.all) return done(null, chosen.map((entry) => ({
|
|
867
|
+
address: entry.address,
|
|
868
|
+
family: entry.family
|
|
869
|
+
})));
|
|
870
|
+
return done(null, chosen[0].address, chosen[0].family);
|
|
871
|
+
});
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
const EMPTY_BODY_STATUS = /* @__PURE__ */ new Set([
|
|
875
|
+
101,
|
|
876
|
+
204,
|
|
877
|
+
205,
|
|
878
|
+
304
|
|
879
|
+
]);
|
|
880
|
+
function decoded(response) {
|
|
881
|
+
const encoding = String(response.headers["content-encoding"] ?? "").trim().toLowerCase();
|
|
882
|
+
const decoder = encoding === "gzip" || encoding === "x-gzip" ? zlib.createGunzip() : encoding === "deflate" ? zlib.createInflate() : encoding === "br" ? zlib.createBrotliDecompress() : null;
|
|
883
|
+
if (!decoder) return response;
|
|
884
|
+
return pipeline(response, decoder, () => void 0);
|
|
885
|
+
}
|
|
886
|
+
function toHeaders(raw) {
|
|
887
|
+
const headers = new Headers();
|
|
888
|
+
for (const [name, value] of Object.entries(raw ?? {})) {
|
|
889
|
+
if (name === "content-encoding" || name === "content-length" || value === void 0) continue;
|
|
890
|
+
for (const entry of Array.isArray(value) ? value : [value]) try {
|
|
891
|
+
headers.append(name, String(entry));
|
|
892
|
+
} catch {}
|
|
893
|
+
}
|
|
894
|
+
return headers;
|
|
895
|
+
}
|
|
896
|
+
function createGuardedFetch({ resolve, allowed = isPublicAddress, maxBytes = 64 * 1024 * 1024 } = {}) {
|
|
897
|
+
const lookup = createGuardedLookup({
|
|
898
|
+
resolve,
|
|
899
|
+
allowed
|
|
900
|
+
});
|
|
901
|
+
return function guardedFetch(input, { headers = {}, signal } = {}) {
|
|
902
|
+
return new Promise((fulfil, reject) => {
|
|
903
|
+
let target;
|
|
904
|
+
try {
|
|
905
|
+
target = input instanceof URL ? input : new URL(String(input));
|
|
906
|
+
if (target.protocol !== "http:" && target.protocol !== "https:") throw new AddressError("Only http and https addresses are supported");
|
|
907
|
+
const literal = target.hostname.replace(/^\[|\]$/gu, "");
|
|
908
|
+
if (isIP(literal) && !allowed(literal)) throw new AddressError();
|
|
909
|
+
} catch (error) {
|
|
910
|
+
reject(error);
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
const transport = target.protocol === "https:" ? https : http;
|
|
914
|
+
let settled = false;
|
|
915
|
+
const fail = (error) => {
|
|
916
|
+
if (settled) return;
|
|
917
|
+
settled = true;
|
|
918
|
+
reject(error);
|
|
919
|
+
};
|
|
920
|
+
const request = transport.request(target, {
|
|
921
|
+
method: "GET",
|
|
922
|
+
agent: false,
|
|
923
|
+
lookup,
|
|
924
|
+
signal,
|
|
925
|
+
headers: {
|
|
926
|
+
...headers,
|
|
927
|
+
"accept-encoding": "gzip, deflate, br"
|
|
928
|
+
}
|
|
929
|
+
}, (response) => {
|
|
930
|
+
const status = response.statusCode ?? 0;
|
|
931
|
+
if (status < 200 || status > 599) {
|
|
932
|
+
response.resume();
|
|
933
|
+
fail(Object.assign(/* @__PURE__ */ new Error(`Unexpected status ${status}`), { code: "EBADSTATUS" }));
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
if (status >= 300 && status < 400 || EMPTY_BODY_STATUS.has(status)) {
|
|
937
|
+
response.resume();
|
|
938
|
+
settled = true;
|
|
939
|
+
fulfil(new Response(null, {
|
|
940
|
+
status,
|
|
941
|
+
headers: toHeaders(response.headers)
|
|
942
|
+
}));
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
const body = decoded(response);
|
|
946
|
+
const parts = [];
|
|
947
|
+
let size = 0;
|
|
948
|
+
body.on("data", (chunk) => {
|
|
949
|
+
if (settled) return;
|
|
950
|
+
size += chunk.length;
|
|
951
|
+
if (size > maxBytes) {
|
|
952
|
+
request.destroy();
|
|
953
|
+
body.destroy?.();
|
|
954
|
+
fail(Object.assign(/* @__PURE__ */ new Error("Response too large"), { code: "ETOOLARGE" }));
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
parts.push(chunk);
|
|
958
|
+
});
|
|
959
|
+
body.on("error", fail);
|
|
960
|
+
body.on("end", () => {
|
|
961
|
+
if (settled) return;
|
|
962
|
+
settled = true;
|
|
963
|
+
fulfil(new Response(Buffer.concat(parts), {
|
|
964
|
+
status,
|
|
965
|
+
headers: toHeaders(response.headers)
|
|
966
|
+
}));
|
|
967
|
+
});
|
|
968
|
+
});
|
|
969
|
+
request.on("error", fail);
|
|
970
|
+
request.end();
|
|
971
|
+
});
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
createGuardedFetch();
|
|
975
|
+
//#endregion
|
|
666
976
|
//#region src/host/materials.js
|
|
667
977
|
const MAX_UPLOAD_BYTES = 60 * 1024 * 1024;
|
|
668
978
|
const MAX_TEXT_CHARS = 2e6;
|
|
669
979
|
const CHUNK_CHARS = 1600;
|
|
670
980
|
const FETCH_TIMEOUT_MS = 2e4;
|
|
671
981
|
const MAX_PAGE_BYTES = 6 * 1024 * 1024;
|
|
982
|
+
const pageFetch = createGuardedFetch({ maxBytes: MAX_UPLOAD_BYTES });
|
|
672
983
|
var MaterialError = class extends Error {
|
|
673
984
|
constructor(code, message) {
|
|
674
985
|
super(message);
|
|
@@ -984,7 +1295,6 @@ async function ingestFile({ name, bytes, signal }) {
|
|
|
984
1295
|
const result = extractPlain(bytes, kind);
|
|
985
1296
|
return finish(kind, result.title || baseTitle, result.chunks);
|
|
986
1297
|
}
|
|
987
|
-
const PRIVATE_HOST = /^(localhost|.*\.local|127\.\d+\.\d+\.\d+|10\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|172\.(1[6-9]|2\d|3[01])\.\d+\.\d+|169\.254\.\d+\.\d+|0\.0\.0\.0|\[?::1\]?|\[?f[cd][0-9a-f]{2}:.*)$/iu;
|
|
988
1298
|
function checkPublicUrl(value) {
|
|
989
1299
|
let url;
|
|
990
1300
|
try {
|
|
@@ -994,10 +1304,14 @@ function checkPublicUrl(value) {
|
|
|
994
1304
|
}
|
|
995
1305
|
if (url.protocol !== "https:" && url.protocol !== "http:") throw new MaterialError("bad-url", "Only http and https addresses are supported");
|
|
996
1306
|
if (url.username || url.password) throw new MaterialError("bad-url", "Addresses with credentials are not supported");
|
|
997
|
-
|
|
1307
|
+
try {
|
|
1308
|
+
assertPublicHostname(url.hostname);
|
|
1309
|
+
} catch (error) {
|
|
1310
|
+
throw new MaterialError("bad-url", error.message);
|
|
1311
|
+
}
|
|
998
1312
|
return url;
|
|
999
1313
|
}
|
|
1000
|
-
async function ingestUrl(address, { fetchImpl =
|
|
1314
|
+
async function ingestUrl(address, { fetchImpl = pageFetch, signal } = {}) {
|
|
1001
1315
|
let url = checkPublicUrl(address);
|
|
1002
1316
|
let response;
|
|
1003
1317
|
for (let hop = 0; hop < 6; hop += 1) {
|
|
@@ -1013,6 +1327,8 @@ async function ingestUrl(address, { fetchImpl = globalThis.fetch, signal } = {})
|
|
|
1013
1327
|
});
|
|
1014
1328
|
} catch (error) {
|
|
1015
1329
|
if (signal?.aborted) throw signal.reason ?? error;
|
|
1330
|
+
if (error?.name === "AddressError") throw new MaterialError("bad-url", error.message);
|
|
1331
|
+
if (error?.code === "ETOOLARGE") throw new MaterialError("too-large", "The page is too large");
|
|
1016
1332
|
throw new MaterialError("network", timeout.aborted ? "The page took too long to load" : "The page could not be loaded");
|
|
1017
1333
|
}
|
|
1018
1334
|
if (response.status >= 300 && response.status < 400 && response.headers.get("location")) {
|
|
@@ -1057,6 +1373,7 @@ async function ingestUrl(address, { fetchImpl = globalThis.fetch, signal } = {})
|
|
|
1057
1373
|
//#region src/host/http.js
|
|
1058
1374
|
const UPLOAD_PATH = "/api/aha-tutor/upload";
|
|
1059
1375
|
const TTS_PATH = "/api/aha-tutor/tts";
|
|
1376
|
+
const FONT_PATH = "/api/aha-tutor/font";
|
|
1060
1377
|
async function readCapped(stream, max, signal) {
|
|
1061
1378
|
const parts = [];
|
|
1062
1379
|
let size = 0;
|
|
@@ -1140,6 +1457,34 @@ function ttsRoute({ speak }) {
|
|
|
1140
1457
|
}
|
|
1141
1458
|
};
|
|
1142
1459
|
}
|
|
1460
|
+
function fontsDir() {
|
|
1461
|
+
return join(dirname(createRequire(import.meta.url).resolve("dsh-aha-tutor/package.json")), "assets", "fonts");
|
|
1462
|
+
}
|
|
1463
|
+
const FONT_FILES = new Set(BOARD_FONT_FILES.map((entry) => entry.file));
|
|
1464
|
+
function fontRoute({ dir = fontsDir() } = {}) {
|
|
1465
|
+
const loaded = /* @__PURE__ */ new Map();
|
|
1466
|
+
return {
|
|
1467
|
+
path: FONT_PATH,
|
|
1468
|
+
methods: ["GET"],
|
|
1469
|
+
requestBody: "buffered",
|
|
1470
|
+
fetch: async (request) => {
|
|
1471
|
+
const name = new URL(request.url).searchParams.get("f") ?? "";
|
|
1472
|
+
if (!FONT_FILES.has(name)) return new Response("Not found", { status: 404 });
|
|
1473
|
+
try {
|
|
1474
|
+
if (!loaded.has(name)) loaded.set(name, await readFile(join(dir, name)));
|
|
1475
|
+
} catch {
|
|
1476
|
+
return new Response("Not found", { status: 404 });
|
|
1477
|
+
}
|
|
1478
|
+
return new Response(loaded.get(name), {
|
|
1479
|
+
status: 200,
|
|
1480
|
+
headers: {
|
|
1481
|
+
"content-type": "font/woff2",
|
|
1482
|
+
"cache-control": "public, max-age=31536000, immutable"
|
|
1483
|
+
}
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1143
1488
|
//#endregion
|
|
1144
1489
|
//#region src/host/jobs.js
|
|
1145
1490
|
const KEEP_FINISHED_MS = 10 * 6e4;
|
|
@@ -1162,7 +1507,7 @@ function createJobs({ logger, now = Date.now } = {}) {
|
|
|
1162
1507
|
sweep();
|
|
1163
1508
|
if (key && byKey.has(key)) {
|
|
1164
1509
|
const existing = jobs.get(byKey.get(key));
|
|
1165
|
-
if (existing && !existing.finishedAt) return snapshot(existing);
|
|
1510
|
+
if (existing && !existing.finishedAt && !existing.controller.signal.aborted) return snapshot(existing);
|
|
1166
1511
|
}
|
|
1167
1512
|
const controller = new AbortController();
|
|
1168
1513
|
const job = {
|
|
@@ -1206,7 +1551,10 @@ function createJobs({ logger, now = Date.now } = {}) {
|
|
|
1206
1551
|
job.result = result;
|
|
1207
1552
|
}).catch((error) => {
|
|
1208
1553
|
job.status = controller.signal.aborted ? "cancelled" : "failed";
|
|
1209
|
-
job.error = {
|
|
1554
|
+
job.error = controller.signal.aborted ? {
|
|
1555
|
+
code: "cancelled",
|
|
1556
|
+
message: "Cancelled"
|
|
1557
|
+
} : {
|
|
1210
1558
|
code: error?.code ?? "failed",
|
|
1211
1559
|
message: publicMessage(error)
|
|
1212
1560
|
};
|
|
@@ -1241,7 +1589,11 @@ function createJobs({ logger, now = Date.now } = {}) {
|
|
|
1241
1589
|
function running(key) {
|
|
1242
1590
|
const id = byKey.get(key);
|
|
1243
1591
|
const job = id ? jobs.get(id) : void 0;
|
|
1244
|
-
return job && !job.finishedAt ? snapshot(job) : null;
|
|
1592
|
+
return job && !job.finishedAt && !job.controller.signal.aborted ? snapshot(job) : null;
|
|
1593
|
+
}
|
|
1594
|
+
function cancelKey(key) {
|
|
1595
|
+
const job = running(key);
|
|
1596
|
+
return job ? cancel(job.id) : null;
|
|
1245
1597
|
}
|
|
1246
1598
|
function dispose() {
|
|
1247
1599
|
for (const job of jobs.values()) if (!job.finishedAt) job.controller.abort(/* @__PURE__ */ new Error("plugin stopped"));
|
|
@@ -1252,6 +1604,7 @@ function createJobs({ logger, now = Date.now } = {}) {
|
|
|
1252
1604
|
start,
|
|
1253
1605
|
get,
|
|
1254
1606
|
cancel,
|
|
1607
|
+
cancelKey,
|
|
1255
1608
|
running,
|
|
1256
1609
|
dispose
|
|
1257
1610
|
});
|
|
@@ -1768,6 +2121,7 @@ function round2(value) {
|
|
|
1768
2121
|
//#endregion
|
|
1769
2122
|
//#region src/host/lessons.js
|
|
1770
2123
|
const EVENTS_KEPT = 200;
|
|
2124
|
+
const STEP_ID = /^s\d{1,4}$/u;
|
|
1771
2125
|
function createLessons({ store, llm, jobs, courses, learner, now = () => /* @__PURE__ */ new Date() }) {
|
|
1772
2126
|
const stamp = () => now().toISOString();
|
|
1773
2127
|
async function context(courseId, lessonId) {
|
|
@@ -1781,10 +2135,11 @@ function createLessons({ store, llm, jobs, courses, learner, now = () => /* @__P
|
|
|
1781
2135
|
}
|
|
1782
2136
|
async function get({ courseId, lessonId }) {
|
|
1783
2137
|
const { course, row } = await context(courseId, lessonId);
|
|
1784
|
-
const [board, practice, progress] = await Promise.all([
|
|
2138
|
+
const [board, practice, progress, asides] = await Promise.all([
|
|
1785
2139
|
store.readJson(store.paths.board(courseId, lessonId), null),
|
|
1786
2140
|
store.readJson(store.paths.practice(courseId, lessonId), null),
|
|
1787
|
-
readProgress(store, courseId)
|
|
2141
|
+
readProgress(store, courseId),
|
|
2142
|
+
store.readJson(store.paths.asides(courseId, lessonId), null)
|
|
1788
2143
|
]);
|
|
1789
2144
|
return {
|
|
1790
2145
|
courseId,
|
|
@@ -1800,6 +2155,7 @@ function createLessons({ store, llm, jobs, courses, learner, now = () => /* @__P
|
|
|
1800
2155
|
lesson: row.lesson,
|
|
1801
2156
|
board,
|
|
1802
2157
|
practice,
|
|
2158
|
+
asides: Array.isArray(asides?.items) ? asides.items : [],
|
|
1803
2159
|
state: progress.lessons?.[lessonId] ?? {
|
|
1804
2160
|
status: "new",
|
|
1805
2161
|
stepIndex: 0
|
|
@@ -1845,6 +2201,11 @@ function createLessons({ store, llm, jobs, courses, learner, now = () => /* @__P
|
|
|
1845
2201
|
}
|
|
1846
2202
|
async function prepare({ courseId, lessonId, force = false, style }) {
|
|
1847
2203
|
const { course, row } = await context(courseId, lessonId);
|
|
2204
|
+
ensurePractice(course, row);
|
|
2205
|
+
if (force) {
|
|
2206
|
+
jobs.cancelKey(`board:${courseId}:${lessonId}`);
|
|
2207
|
+
await store.writeJson(store.paths.asides(courseId, lessonId), { items: [] });
|
|
2208
|
+
}
|
|
1848
2209
|
if (!force) {
|
|
1849
2210
|
const existing = await store.readJson(store.paths.board(courseId, lessonId), null);
|
|
1850
2211
|
if (existing) {
|
|
@@ -1939,7 +2300,18 @@ function createLessons({ store, llm, jobs, courses, learner, now = () => /* @__P
|
|
|
1939
2300
|
}
|
|
1940
2301
|
throw new TutorError("invalid", "Unknown board");
|
|
1941
2302
|
}
|
|
1942
|
-
function
|
|
2303
|
+
async function keepAside(scope, aside) {
|
|
2304
|
+
if (scope?.kind !== "lesson") return null;
|
|
2305
|
+
const saved = {
|
|
2306
|
+
id: newId("asd"),
|
|
2307
|
+
...aside,
|
|
2308
|
+
at: stamp()
|
|
2309
|
+
};
|
|
2310
|
+
await store.updateJson(store.paths.asides(scope.courseId, scope.lessonId), null, (value) => ({ items: [...Array.isArray(value?.items) ? value.items : [], saved].slice(-30) }));
|
|
2311
|
+
return saved;
|
|
2312
|
+
}
|
|
2313
|
+
const anchorFor = (board, stepIndex, anchorStepId) => STEP_ID.test(String(anchorStepId)) ? anchorStepId : board?.steps?.[Math.max(0, Number(stepIndex) || 0)]?.id ?? "s1";
|
|
2314
|
+
function ask({ scope, stepIndex = 0, question, anchorStepId }) {
|
|
1943
2315
|
const request = text(question, 1500);
|
|
1944
2316
|
if (!request) throw new TutorError("invalid", "Type your question");
|
|
1945
2317
|
return jobs.start("lesson/ask", async (api) => {
|
|
@@ -1963,15 +2335,24 @@ function createLessons({ store, llm, jobs, courses, learner, now = () => /* @__P
|
|
|
1963
2335
|
conceptIds: lesson?.concepts?.map((concept) => concept.id) ?? [],
|
|
1964
2336
|
onStep: (step) => api.push(step)
|
|
1965
2337
|
});
|
|
2338
|
+
const aside = await keepAside(scope, {
|
|
2339
|
+
kind: "question",
|
|
2340
|
+
question: request,
|
|
2341
|
+
anchorStepId: anchorFor(board, stepIndex, anchorStepId),
|
|
2342
|
+
steps: answer.steps
|
|
2343
|
+
});
|
|
1966
2344
|
if (scope.kind === "lesson") await logEvent(scope.courseId, {
|
|
1967
2345
|
type: "question",
|
|
1968
2346
|
lessonId: scope.lessonId,
|
|
1969
2347
|
text: request.slice(0, 200)
|
|
1970
2348
|
});
|
|
1971
|
-
return {
|
|
2349
|
+
return {
|
|
2350
|
+
steps: answer.steps,
|
|
2351
|
+
aside
|
|
2352
|
+
};
|
|
1972
2353
|
});
|
|
1973
2354
|
}
|
|
1974
|
-
function reexplain({ scope, stepIndex = 0, style = "example" }) {
|
|
2355
|
+
function reexplain({ scope, stepIndex = 0, style = "example", anchorStepId }) {
|
|
1975
2356
|
return jobs.start("lesson/reexplain", async (api) => {
|
|
1976
2357
|
const { course, lesson, board, language } = await scopeBoard(scope);
|
|
1977
2358
|
if (!board?.steps?.length) throw new TutorError("invalid", "Nothing to re-explain yet");
|
|
@@ -1993,6 +2374,12 @@ function createLessons({ store, llm, jobs, courses, learner, now = () => /* @__P
|
|
|
1993
2374
|
conceptIds: lesson?.concepts?.map((concept) => concept.id) ?? [],
|
|
1994
2375
|
onStep: (next) => api.push(next)
|
|
1995
2376
|
});
|
|
2377
|
+
const aside = await keepAside(scope, {
|
|
2378
|
+
kind: "reexplain",
|
|
2379
|
+
style,
|
|
2380
|
+
anchorStepId: anchorFor(board, index, anchorStepId),
|
|
2381
|
+
steps: answer.steps
|
|
2382
|
+
});
|
|
1996
2383
|
if (scope.kind === "lesson" && course) {
|
|
1997
2384
|
const conceptIds = lesson.concepts.map((concept) => concept.id);
|
|
1998
2385
|
await record({
|
|
@@ -2002,7 +2389,10 @@ function createLessons({ store, llm, jobs, courses, learner, now = () => /* @__P
|
|
|
2002
2389
|
evidence: { kind: "reexplain" }
|
|
2003
2390
|
});
|
|
2004
2391
|
}
|
|
2005
|
-
return {
|
|
2392
|
+
return {
|
|
2393
|
+
steps: answer.steps,
|
|
2394
|
+
aside
|
|
2395
|
+
};
|
|
2006
2396
|
});
|
|
2007
2397
|
}
|
|
2008
2398
|
async function record({ courseId, lessonId, conceptIds = [], evidence = {} }) {
|
|
@@ -2169,37 +2559,34 @@ function createLessons({ store, llm, jobs, courses, learner, now = () => /* @__P
|
|
|
2169
2559
|
const { course, row } = await context(courseId, lessonId);
|
|
2170
2560
|
const existing = await store.readJson(store.paths.practice(courseId, lessonId), null);
|
|
2171
2561
|
if (existing) return { practice: existing };
|
|
2172
|
-
return { job:
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
if (!set.items.length) throw new TutorError("bad-output", "No practice items came back. Try again.");
|
|
2189
|
-
const saved = {
|
|
2190
|
-
lessonId,
|
|
2191
|
-
...set,
|
|
2192
|
-
createdAt: stamp()
|
|
2193
|
-
};
|
|
2194
|
-
await store.writeJson(store.paths.practice(courseId, lessonId), saved);
|
|
2195
|
-
return { practice: saved };
|
|
2562
|
+
return { job: lecturePractice(course, row) };
|
|
2563
|
+
}
|
|
2564
|
+
function lecturePractice(course, row) {
|
|
2565
|
+
return jobs.start("lesson/practice", async (api) => {
|
|
2566
|
+
const missing = [];
|
|
2567
|
+
for (const lesson of row.lecture.lessons) if (!await store.exists(store.paths.practice(course.id, lesson.id))) missing.push(lesson);
|
|
2568
|
+
const written = missing.length ? await courses.writeLecturePractice({
|
|
2569
|
+
course,
|
|
2570
|
+
lecture: row.lecture,
|
|
2571
|
+
lessons: missing,
|
|
2572
|
+
signal: api.signal
|
|
2573
|
+
}) : {};
|
|
2574
|
+
const sets = {};
|
|
2575
|
+
for (const lesson of row.lecture.lessons) sets[lesson.id] = written[lesson.id] ?? await store.readJson(store.paths.practice(course.id, lesson.id), null);
|
|
2576
|
+
if (!Object.values(sets).some(Boolean)) throw new TutorError("bad-output", "No practice items came back. Try again.");
|
|
2577
|
+
return { sets };
|
|
2196
2578
|
}, {
|
|
2197
|
-
key: `practice:${
|
|
2579
|
+
key: `practice:${course.id}:${row.lecture.id}`,
|
|
2198
2580
|
meta: {
|
|
2199
|
-
courseId,
|
|
2200
|
-
|
|
2581
|
+
courseId: course.id,
|
|
2582
|
+
lectureId: row.lecture.id
|
|
2201
2583
|
}
|
|
2202
|
-
})
|
|
2584
|
+
});
|
|
2585
|
+
}
|
|
2586
|
+
function ensurePractice(course, row) {
|
|
2587
|
+
store.exists(store.paths.practice(course.id, row.lesson.id)).then((exists) => {
|
|
2588
|
+
if (!exists && !jobs.running(`practice:${course.id}:${row.lecture.id}`)) lecturePractice(course, row);
|
|
2589
|
+
}).catch(() => void 0);
|
|
2203
2590
|
}
|
|
2204
2591
|
async function unitSheet({ courseId, unitId, force = false }) {
|
|
2205
2592
|
const course = await courses.readCourse(courseId);
|
|
@@ -2648,6 +3035,7 @@ function createStore({ root }) {
|
|
|
2648
3035
|
sheetsDir: (id) => join(paths.courseDir(id), "sheets"),
|
|
2649
3036
|
board: (id, lessonId) => join(paths.courseDir(id), "boards", `${assertId(lessonId, "les")}.json`),
|
|
2650
3037
|
practice: (id, lessonId) => join(paths.courseDir(id), "practice", `${assertId(lessonId, "les")}.json`),
|
|
3038
|
+
asides: (id, lessonId) => join(paths.courseDir(id), "asides", `${assertId(lessonId, "les")}.json`),
|
|
2651
3039
|
sheet: (id, unitId) => join(paths.courseDir(id), "sheets", `${assertId(unitId, "unt")}.json`),
|
|
2652
3040
|
unitQuiz: (id, unitId) => join(paths.courseDir(id), "quizzes", `${assertId(unitId, "unt")}.json`),
|
|
2653
3041
|
materials: () => join(root, "materials"),
|
|
@@ -3401,12 +3789,14 @@ function createRoutes({ courses, lessons, learner, studio, projects, jobs, setti
|
|
|
3401
3789
|
"lesson/ask": (payload) => ({ job: lessons.ask({
|
|
3402
3790
|
scope: scopeOf(payload),
|
|
3403
3791
|
stepIndex: payload.stepIndex,
|
|
3404
|
-
question: payload.question
|
|
3792
|
+
question: payload.question,
|
|
3793
|
+
anchorStepId: payload.anchorStepId
|
|
3405
3794
|
}) }),
|
|
3406
3795
|
"lesson/reexplain": (payload) => ({ job: lessons.reexplain({
|
|
3407
3796
|
scope: scopeOf(payload),
|
|
3408
3797
|
stepIndex: payload.stepIndex,
|
|
3409
|
-
style: STYLES.includes(payload.style) ? payload.style : "example"
|
|
3798
|
+
style: STYLES.includes(payload.style) ? payload.style : "example",
|
|
3799
|
+
anchorStepId: payload.anchorStepId
|
|
3410
3800
|
}) }),
|
|
3411
3801
|
"lesson/record": (payload) => lessons.record({
|
|
3412
3802
|
courseId: need(payload, "courseId", "crs"),
|
|
@@ -4083,6 +4473,7 @@ const PREF_DEFAULTS = Object.freeze({
|
|
|
4083
4473
|
voiceEngine: "browser",
|
|
4084
4474
|
voiceRate: 1,
|
|
4085
4475
|
boardTheme: "auto",
|
|
4476
|
+
boardFont: "hand",
|
|
4086
4477
|
ttsProvider: "openai",
|
|
4087
4478
|
tts: Object.fromEntries(TTS_PROVIDERS.map((provider) => [provider, providerDefaults(provider)]))
|
|
4088
4479
|
});
|
|
@@ -4112,6 +4503,7 @@ function cleanPrefs(input = {}, base = PREF_DEFAULTS) {
|
|
|
4112
4503
|
"light",
|
|
4113
4504
|
"dark"
|
|
4114
4505
|
].includes(input.boardTheme)) next.boardTheme = input.boardTheme;
|
|
4506
|
+
if (["hand", "standard"].includes(input.boardFont)) next.boardFont = input.boardFont;
|
|
4115
4507
|
if (TTS_PROVIDERS.includes(input.ttsProvider)) next.ttsProvider = input.ttsProvider;
|
|
4116
4508
|
for (const provider of TTS_PROVIDERS) {
|
|
4117
4509
|
const patch = input.tts?.[provider];
|
|
@@ -4221,6 +4613,8 @@ const ASSIST_MODES = [
|
|
|
4221
4613
|
"solve",
|
|
4222
4614
|
"visualize"
|
|
4223
4615
|
];
|
|
4616
|
+
const DIGEST_SINGLE_CHARS = 24e3;
|
|
4617
|
+
const DIGEST_NOTES_CHARS = 48e3;
|
|
4224
4618
|
function createStudio({ store, llm, jobs, now = () => /* @__PURE__ */ new Date(), uiLanguage = () => "zh-CN" }) {
|
|
4225
4619
|
const stamp = () => now().toISOString();
|
|
4226
4620
|
async function saveMaterial(result, { bytes, signal, extra = {} }) {
|
|
@@ -4246,7 +4640,7 @@ function createStudio({ store, llm, jobs, now = () => /* @__PURE__ */ new Date()
|
|
|
4246
4640
|
purpose: "quick",
|
|
4247
4641
|
prompt: materialBriefPrompt({
|
|
4248
4642
|
title: meta.title,
|
|
4249
|
-
passages: result.chunks
|
|
4643
|
+
passages: formatPassages(spreadPassages(result.chunks, { maxChars: 12e3 }), ""),
|
|
4250
4644
|
language: detectLanguage(result.chunks[0].text, uiLanguage())
|
|
4251
4645
|
}),
|
|
4252
4646
|
maxTokens: 1500,
|
|
@@ -4328,36 +4722,77 @@ function createStudio({ store, llm, jobs, now = () => /* @__PURE__ */ new Date()
|
|
|
4328
4722
|
return jobs.start("material/digest", async (api) => {
|
|
4329
4723
|
const [material] = await readMaterials(store, [assertId(id, "mat")]);
|
|
4330
4724
|
if (!material?.chunks.length) throw new TutorError("invalid", "This material has no text to digest");
|
|
4725
|
+
const title = material.meta.title;
|
|
4331
4726
|
const language = detectLanguage(material.chunks[0].text, uiLanguage());
|
|
4727
|
+
const size = material.chunks.reduce((sum, chunk) => sum + chunk.text.length, 0);
|
|
4728
|
+
let prompt;
|
|
4729
|
+
let missing = [];
|
|
4730
|
+
if (size <= DIGEST_SINGLE_CHARS) {
|
|
4731
|
+
api.progress(0, 1, "writing");
|
|
4732
|
+
prompt = digestPrompt({
|
|
4733
|
+
title,
|
|
4734
|
+
passages: formatPassages(material.chunks, ""),
|
|
4735
|
+
language
|
|
4736
|
+
});
|
|
4737
|
+
} else {
|
|
4738
|
+
const parts = documentParts(material.chunks);
|
|
4739
|
+
const notes = new Array(parts.length).fill(null);
|
|
4740
|
+
const readPart = async (index) => {
|
|
4741
|
+
try {
|
|
4742
|
+
notes[index] = await generateJson(llm, {
|
|
4743
|
+
purpose: "teach",
|
|
4744
|
+
prompt: digestPartPrompt({
|
|
4745
|
+
title,
|
|
4746
|
+
part: index + 1,
|
|
4747
|
+
parts: parts.length,
|
|
4748
|
+
range: passageRange(parts[index]),
|
|
4749
|
+
passages: formatPassages(parts[index], ""),
|
|
4750
|
+
language
|
|
4751
|
+
}),
|
|
4752
|
+
maxTokens: 6e3,
|
|
4753
|
+
signal: api.signal,
|
|
4754
|
+
normalize: normalizeDigestPart
|
|
4755
|
+
});
|
|
4756
|
+
} catch (error) {
|
|
4757
|
+
if (api.signal.aborted) throw error;
|
|
4758
|
+
}
|
|
4759
|
+
};
|
|
4760
|
+
const queue = parts.map((part, index) => index);
|
|
4761
|
+
let done = 0;
|
|
4762
|
+
api.progress(0, parts.length + 1, "reading");
|
|
4763
|
+
const worker = async () => {
|
|
4764
|
+
while (queue.length) {
|
|
4765
|
+
api.signal.throwIfAborted();
|
|
4766
|
+
await readPart(queue.shift());
|
|
4767
|
+
done += 1;
|
|
4768
|
+
api.progress(done, parts.length + 1, "reading");
|
|
4769
|
+
}
|
|
4770
|
+
};
|
|
4771
|
+
await Promise.all([worker(), worker()]);
|
|
4772
|
+
for (const [index, note] of notes.entries()) if (!note) await readPart(index);
|
|
4773
|
+
const read = notes.map((note, index) => note ? {
|
|
4774
|
+
part: index + 1,
|
|
4775
|
+
of: parts.length,
|
|
4776
|
+
range: passageRange(parts[index]),
|
|
4777
|
+
...note
|
|
4778
|
+
} : null).filter(Boolean);
|
|
4779
|
+
if (read.length < Math.ceil(parts.length / 2)) throw new TutorError("bad-output", "The model could not read enough of this document. Try again or pick a stronger model in settings.");
|
|
4780
|
+
missing = parts.map((part, index) => notes[index] ? null : passageRange(part) || `${index + 1}/${parts.length}`).filter(Boolean);
|
|
4781
|
+
api.progress(parts.length, parts.length + 1, "writing");
|
|
4782
|
+
prompt = digestPrompt({
|
|
4783
|
+
title,
|
|
4784
|
+
notes: digestNotesText(read, DIGEST_NOTES_CHARS),
|
|
4785
|
+
language
|
|
4786
|
+
});
|
|
4787
|
+
}
|
|
4332
4788
|
const result = await generateJson(llm, {
|
|
4333
4789
|
purpose: "teach",
|
|
4334
|
-
prompt
|
|
4335
|
-
title: material.meta.title,
|
|
4336
|
-
passages: passagesFor([material], "", 24e3),
|
|
4337
|
-
language
|
|
4338
|
-
}),
|
|
4790
|
+
prompt,
|
|
4339
4791
|
maxTokens: 9e3,
|
|
4340
4792
|
signal: api.signal,
|
|
4341
|
-
normalize:
|
|
4342
|
-
overview: text(raw?.overview, 2e3),
|
|
4343
|
-
structure: (Array.isArray(raw?.structure) ? raw.structure : []).slice(0, 30).map((item) => ({
|
|
4344
|
-
heading: text(item?.heading, 160),
|
|
4345
|
-
points: (item?.points ?? []).map((point) => text(point, 400)).filter(Boolean).slice(0, 10),
|
|
4346
|
-
pages: text(item?.pages, 30)
|
|
4347
|
-
})).filter((item) => item.heading),
|
|
4348
|
-
keyIdeas: (raw?.keyIdeas ?? []).map((item) => text(item, 400)).filter(Boolean).slice(0, 15),
|
|
4349
|
-
arguments: (raw?.arguments ?? []).slice(0, 15).map((item) => ({
|
|
4350
|
-
claim: text(item?.claim, 400),
|
|
4351
|
-
support: text(item?.support, 600),
|
|
4352
|
-
page: text(item?.page, 20)
|
|
4353
|
-
})).filter((item) => item.claim),
|
|
4354
|
-
glossary: (raw?.glossary ?? []).slice(0, 30).map((item) => ({
|
|
4355
|
-
term: text(item?.term, 80),
|
|
4356
|
-
meaning: text(item?.meaning, 400)
|
|
4357
|
-
})).filter((item) => item.term),
|
|
4358
|
-
questions: (raw?.questions ?? []).map((item) => text(item, 300)).filter(Boolean).slice(0, 8)
|
|
4359
|
-
})
|
|
4793
|
+
normalize: normalizeDigest
|
|
4360
4794
|
});
|
|
4795
|
+
if (missing.length) result.missing = missing;
|
|
4361
4796
|
return { material: await store.updateJson(store.paths.material(id), null, (value) => ({
|
|
4362
4797
|
...value,
|
|
4363
4798
|
digest: {
|
|
@@ -4618,21 +5053,24 @@ function createStudio({ store, llm, jobs, now = () => /* @__PURE__ */ new Date()
|
|
|
4618
5053
|
board,
|
|
4619
5054
|
at: stamp()
|
|
4620
5055
|
};
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
5056
|
+
const id = thread?.id ?? (/^thd_[a-z0-9]{6,40}$/u.test(String(newThreadId)) ? newThreadId : newId("thd"));
|
|
5057
|
+
const saved = await store.updateJson(store.paths.item("assist", id), null, (current) => {
|
|
5058
|
+
const next = current ?? {
|
|
5059
|
+
id,
|
|
5060
|
+
title: board.title || ask.slice(0, 60),
|
|
5061
|
+
language,
|
|
5062
|
+
materialIds: [],
|
|
5063
|
+
turns: [],
|
|
5064
|
+
createdAt: stamp()
|
|
5065
|
+
};
|
|
5066
|
+
next.turns = [...next.turns ?? [], turn].slice(-30);
|
|
5067
|
+
next.materialIds = [.../* @__PURE__ */ new Set([...next.materialIds ?? [], ...ids])].slice(0, 8);
|
|
5068
|
+
next.updatedAt = stamp();
|
|
5069
|
+
return next;
|
|
5070
|
+
});
|
|
4633
5071
|
return {
|
|
4634
|
-
threadId:
|
|
4635
|
-
turn:
|
|
5072
|
+
threadId: saved.id,
|
|
5073
|
+
turn: saved.turns.length - 1,
|
|
4636
5074
|
board
|
|
4637
5075
|
};
|
|
4638
5076
|
}, { meta: { threadId: threadId ?? null } });
|
|
@@ -4702,6 +5140,60 @@ function createStudio({ store, llm, jobs, now = () => /* @__PURE__ */ new Date()
|
|
|
4702
5140
|
makeShort
|
|
4703
5141
|
});
|
|
4704
5142
|
}
|
|
5143
|
+
function normalizeDigest(raw) {
|
|
5144
|
+
return {
|
|
5145
|
+
overview: text(raw?.overview, 2e3),
|
|
5146
|
+
structure: (Array.isArray(raw?.structure) ? raw.structure : []).slice(0, 30).map((item) => ({
|
|
5147
|
+
heading: text(item?.heading, 160),
|
|
5148
|
+
points: (item?.points ?? []).map((point) => text(point, 400)).filter(Boolean).slice(0, 10),
|
|
5149
|
+
pages: text(item?.pages, 30)
|
|
5150
|
+
})).filter((item) => item.heading),
|
|
5151
|
+
keyIdeas: (raw?.keyIdeas ?? []).map((item) => text(item, 400)).filter(Boolean).slice(0, 15),
|
|
5152
|
+
arguments: (raw?.arguments ?? []).slice(0, 15).map((item) => ({
|
|
5153
|
+
claim: text(item?.claim, 400),
|
|
5154
|
+
support: text(item?.support, 600),
|
|
5155
|
+
page: text(item?.page, 20)
|
|
5156
|
+
})).filter((item) => item.claim),
|
|
5157
|
+
glossary: (raw?.glossary ?? []).slice(0, 30).map((item) => ({
|
|
5158
|
+
term: text(item?.term, 80),
|
|
5159
|
+
meaning: text(item?.meaning, 400)
|
|
5160
|
+
})).filter((item) => item.term),
|
|
5161
|
+
questions: (raw?.questions ?? []).map((item) => text(item, 300)).filter(Boolean).slice(0, 8)
|
|
5162
|
+
};
|
|
5163
|
+
}
|
|
5164
|
+
function normalizeDigestPart(raw) {
|
|
5165
|
+
const value = {
|
|
5166
|
+
sections: (Array.isArray(raw?.sections) ? raw.sections : []).slice(0, 12).map((item) => ({
|
|
5167
|
+
heading: text(item?.heading, 160),
|
|
5168
|
+
pages: text(item?.pages, 30),
|
|
5169
|
+
points: (Array.isArray(item?.points) ? item.points : []).map((point) => text(point, 300)).filter(Boolean).slice(0, 6)
|
|
5170
|
+
})).filter((item) => item.heading),
|
|
5171
|
+
keyIdeas: (Array.isArray(raw?.keyIdeas) ? raw.keyIdeas : []).map((item) => text(item, 300)).filter(Boolean).slice(0, 8),
|
|
5172
|
+
arguments: (Array.isArray(raw?.arguments) ? raw.arguments : []).slice(0, 8).map((item) => ({
|
|
5173
|
+
claim: text(item?.claim, 300),
|
|
5174
|
+
support: text(item?.support, 400),
|
|
5175
|
+
page: text(item?.page, 20)
|
|
5176
|
+
})).filter((item) => item.claim),
|
|
5177
|
+
glossary: (Array.isArray(raw?.glossary) ? raw.glossary : []).slice(0, 12).map((item) => ({
|
|
5178
|
+
term: text(item?.term, 80),
|
|
5179
|
+
meaning: text(item?.meaning, 300)
|
|
5180
|
+
})).filter((item) => item.term)
|
|
5181
|
+
};
|
|
5182
|
+
if (!value.sections.length && !value.keyIdeas.length) throw new Error("no notes for this part");
|
|
5183
|
+
return value;
|
|
5184
|
+
}
|
|
5185
|
+
function digestNotesText(notes, maxChars) {
|
|
5186
|
+
const share = Math.max(600, Math.floor(maxChars / Math.max(1, notes.length)));
|
|
5187
|
+
return notes.map((note) => {
|
|
5188
|
+
const lines = [`[Part ${note.part}/${note.of}${note.range ? ` · ${note.range}` : ""}]`];
|
|
5189
|
+
for (const section of note.sections) lines.push(`- ${section.heading}${section.pages ? ` (p.${section.pages})` : ""}: ${section.points.join("; ")}`);
|
|
5190
|
+
if (note.keyIdeas.length) lines.push(`Key ideas: ${note.keyIdeas.join("; ")}`);
|
|
5191
|
+
for (const argument of note.arguments) lines.push(`Claim: ${argument.claim}${argument.page ? ` (p.${argument.page})` : ""} — ${argument.support}`);
|
|
5192
|
+
if (note.glossary.length) lines.push(`Terms: ${note.glossary.map((entry) => `${entry.term}: ${entry.meaning}`).join("; ")}`);
|
|
5193
|
+
const block = lines.join("\n");
|
|
5194
|
+
return block.length > share ? `${block.slice(0, share)}…` : block;
|
|
5195
|
+
}).join("\n\n");
|
|
5196
|
+
}
|
|
4705
5197
|
//#endregion
|
|
4706
5198
|
//#region src/index.js
|
|
4707
5199
|
const name = "aha-tutor";
|
|
@@ -4822,6 +5314,7 @@ function apply(ctx) {
|
|
|
4822
5314
|
if (typeof fetchRoutes?.register !== "function") return;
|
|
4823
5315
|
connectionCtx.effect(() => fetchRoutes.register(uploadRoute({ studio })), "aha-tutor: upload route");
|
|
4824
5316
|
connectionCtx.effect(() => fetchRoutes.register(ttsRoute({ speak })), "aha-tutor: tts route");
|
|
5317
|
+
connectionCtx.effect(() => fetchRoutes.register(fontRoute()), "aha-tutor: font route");
|
|
4825
5318
|
});
|
|
4826
5319
|
ctx.effect(() => publishRuntime({
|
|
4827
5320
|
store,
|