@falkenslab/moodle-driver 0.4.1 → 0.5.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/README.md +3 -2
- package/dist/areas/activities/build.d.ts +47 -10
- package/dist/areas/activities/build.js +157 -24
- package/dist/areas/activities/build.js.map +1 -1
- package/dist/areas/activities/conditions.d.ts +77 -0
- package/dist/areas/activities/conditions.js +216 -0
- package/dist/areas/activities/conditions.js.map +1 -0
- package/dist/areas/activities/content.d.ts +3 -0
- package/dist/areas/activities/content.js +1 -0
- package/dist/areas/activities/content.js.map +1 -1
- package/dist/areas/assignments/grader.d.ts +32 -0
- package/dist/areas/assignments/grader.js +66 -2
- package/dist/areas/assignments/grader.js.map +1 -1
- package/dist/areas/assignments/grading.d.ts +69 -6
- package/dist/areas/assignments/grading.js +173 -13
- package/dist/areas/assignments/grading.js.map +1 -1
- package/dist/areas/assignments/student.d.ts +14 -0
- package/dist/areas/assignments/student.js +43 -2
- package/dist/areas/assignments/student.js.map +1 -1
- package/dist/areas/backup/backup.d.ts +86 -0
- package/dist/areas/backup/backup.js +368 -0
- package/dist/areas/backup/backup.js.map +1 -0
- package/dist/areas/calendar/calendar.d.ts +27 -0
- package/dist/areas/calendar/calendar.js +115 -9
- package/dist/areas/calendar/calendar.js.map +1 -1
- package/dist/areas/completion/completion.d.ts +3 -0
- package/dist/areas/completion/completion.js.map +1 -1
- package/dist/areas/courses/list.d.ts +2 -0
- package/dist/areas/courses/list.js.map +1 -1
- package/dist/areas/courses/reset.d.ts +51 -0
- package/dist/areas/courses/reset.js +123 -0
- package/dist/areas/courses/reset.js.map +1 -0
- package/dist/areas/courses/state.d.ts +17 -0
- package/dist/areas/courses/state.js +37 -6
- package/dist/areas/courses/state.js.map +1 -1
- package/dist/areas/courses/structure.d.ts +14 -2
- package/dist/areas/courses/structure.js +11 -5
- package/dist/areas/courses/structure.js.map +1 -1
- package/dist/areas/forums/discussions.d.ts +8 -0
- package/dist/areas/forums/discussions.js +10 -0
- package/dist/areas/forums/discussions.js.map +1 -1
- package/dist/areas/forums/grading.d.ts +49 -0
- package/dist/areas/forums/grading.js +125 -0
- package/dist/areas/forums/grading.js.map +1 -0
- package/dist/areas/forums/posts.d.ts +37 -0
- package/dist/areas/forums/posts.js +141 -6
- package/dist/areas/forums/posts.js.map +1 -1
- package/dist/areas/grades/export.d.ts +38 -0
- package/dist/areas/grades/export.js +88 -0
- package/dist/areas/grades/export.js.map +1 -0
- package/dist/areas/grades/gradebook.d.ts +50 -0
- package/dist/areas/grades/gradebook.js +120 -0
- package/dist/areas/grades/gradebook.js.map +1 -1
- package/dist/areas/grades/singleview.d.ts +39 -0
- package/dist/areas/grades/singleview.js +186 -0
- package/dist/areas/grades/singleview.js.map +1 -0
- package/dist/areas/h5p/h5p.d.ts +2 -0
- package/dist/areas/h5p/h5p.js +12 -7
- package/dist/areas/h5p/h5p.js.map +1 -1
- package/dist/areas/lessons/lessons.d.ts +1 -0
- package/dist/areas/lessons/lessons.js.map +1 -1
- package/dist/areas/messages/messages.d.ts +32 -0
- package/dist/areas/messages/messages.js +44 -2
- package/dist/areas/messages/messages.js.map +1 -1
- package/dist/areas/participants/enrolments.d.ts +60 -0
- package/dist/areas/participants/enrolments.js +218 -0
- package/dist/areas/participants/enrolments.js.map +1 -0
- package/dist/areas/participants/groups.d.ts +75 -0
- package/dist/areas/participants/groups.js +201 -0
- package/dist/areas/participants/groups.js.map +1 -0
- package/dist/areas/participants/methods.d.ts +56 -0
- package/dist/areas/participants/methods.js +154 -0
- package/dist/areas/participants/methods.js.map +1 -0
- package/dist/areas/participants/participants.d.ts +11 -0
- package/dist/areas/participants/participants.js +24 -19
- package/dist/areas/participants/participants.js.map +1 -1
- package/dist/areas/questions/banks.d.ts +36 -1
- package/dist/areas/questions/banks.js +140 -17
- package/dist/areas/questions/banks.js.map +1 -1
- package/dist/areas/quizzes/attempts.d.ts +2 -0
- package/dist/areas/quizzes/attempts.js +9 -0
- package/dist/areas/quizzes/attempts.js.map +1 -1
- package/dist/areas/quizzes/grading.d.ts +50 -0
- package/dist/areas/quizzes/grading.js +131 -0
- package/dist/areas/quizzes/grading.js.map +1 -0
- package/dist/areas/quizzes/results.d.ts +3 -0
- package/dist/areas/quizzes/results.js +2 -1
- package/dist/areas/quizzes/results.js.map +1 -1
- package/dist/areas/quizzes/structure.d.ts +65 -9
- package/dist/areas/quizzes/structure.js +222 -23
- package/dist/areas/quizzes/structure.js.map +1 -1
- package/dist/areas/ratings/ratings.d.ts +26 -0
- package/dist/areas/ratings/ratings.js +108 -0
- package/dist/areas/ratings/ratings.js.map +1 -0
- package/dist/areas/reports/dates.d.ts +18 -0
- package/dist/areas/reports/dates.js +134 -0
- package/dist/areas/reports/dates.js.map +1 -0
- package/dist/areas/reports/reports.d.ts +143 -0
- package/dist/areas/reports/reports.js +267 -0
- package/dist/areas/reports/reports.js.map +1 -0
- package/dist/areas/scorm/scorm.d.ts +1 -0
- package/dist/areas/scorm/scorm.js.map +1 -1
- package/dist/areas/site/users.d.ts +7 -1
- package/dist/areas/site/users.js +9 -2
- package/dist/areas/site/users.js.map +1 -1
- package/dist/areas/surveys/choice.d.ts +2 -0
- package/dist/areas/surveys/choice.js +6 -3
- package/dist/areas/surveys/choice.js.map +1 -1
- package/dist/areas/surveys/surveys.d.ts +3 -0
- package/dist/areas/surveys/surveys.js +1 -0
- package/dist/areas/surveys/surveys.js.map +1 -1
- package/dist/areas/workshops/workshops.d.ts +133 -0
- package/dist/areas/workshops/workshops.js +335 -0
- package/dist/areas/workshops/workshops.js.map +1 -0
- package/dist/browser/background.d.ts +43 -0
- package/dist/browser/background.js +164 -0
- package/dist/browser/background.js.map +1 -0
- package/dist/browser/host.d.ts +30 -0
- package/dist/browser/host.js +373 -0
- package/dist/browser/host.js.map +1 -0
- package/dist/browser/manager.d.ts +9 -0
- package/dist/browser/manager.js +8 -0
- package/dist/browser/manager.js.map +1 -1
- package/dist/categories.d.ts +1 -0
- package/dist/categories.js +67 -0
- package/dist/categories.js.map +1 -1
- package/dist/cli/args.d.ts +8 -0
- package/dist/cli/args.js +49 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/background.d.ts +23 -0
- package/dist/cli/background.js +128 -0
- package/dist/cli/background.js.map +1 -0
- package/dist/cli/command.d.ts +66 -0
- package/dist/cli/command.js +328 -0
- package/dist/cli/command.js.map +1 -0
- package/dist/cli/commands.generated.js +2635 -577
- package/dist/cli/commands.generated.js.map +1 -1
- package/dist/cli/config.d.ts +2 -0
- package/dist/cli/config.js +2 -0
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/main.js +30 -10
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/run.d.ts +3 -14
- package/dist/cli/run.js +9 -185
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/shell.d.ts +9 -0
- package/dist/cli/shell.js +233 -0
- package/dist/cli/shell.js.map +1 -0
- package/dist/client.d.ts +71 -8
- package/dist/client.js +75 -8
- package/dist/client.js.map +1 -1
- package/dist/core/errors.d.ts +1 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/core/files.d.ts +5 -0
- package/dist/core/files.js +7 -3
- package/dist/core/files.js.map +1 -1
- package/dist/core/forms.d.ts +33 -3
- package/dist/core/forms.js +105 -8
- package/dist/core/forms.js.map +1 -1
- package/dist/core/http.d.ts +7 -0
- package/dist/core/http.js +28 -7
- package/dist/core/http.js.map +1 -1
- package/dist/core/login.d.ts +3 -0
- package/dist/core/login.js +2 -0
- package/dist/core/login.js.map +1 -1
- package/dist/core/session.d.ts +12 -1
- package/dist/core/session.js +12 -1
- package/dist/core/session.js.map +1 -1
- package/dist/index.d.ts +35 -11
- package/dist/index.js +32 -12
- package/dist/index.js.map +1 -1
- package/dist/internals.d.ts +9 -1
- package/dist/internals.js +9 -4
- package/dist/internals.js.map +1 -1
- package/dist/options.d.ts +2 -0
- package/dist/options.js.map +1 -1
- package/dist/testing/fakeMoodle.d.ts +9 -2
- package/dist/testing/fakeMoodle.js +5 -3
- package/dist/testing/fakeMoodle.js.map +1 -1
- package/dist/testing/index.d.ts +7 -0
- package/dist/testing/index.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
// One command line of `moodle` (ADR-012), run on a session that may outlive it: `run` makes one for a
|
|
2
|
+
// single line, `moodle shell` keeps one for every line typed. Its surroundings come as arguments, so
|
|
3
|
+
// tests run it against the fake Moodle.
|
|
4
|
+
import { mkdirSync, rmSync } from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { backgroundBrowser, closeBackgroundBrowser, connectBrowserManager } from "../browser/background.js";
|
|
7
|
+
import { ALL_DATA_CATEGORIES, DATA_CATEGORIES } from "../categories.js";
|
|
8
|
+
import { MoodleError } from "../core/errors.js";
|
|
9
|
+
import { NotLoggedInError } from "../core/session.js";
|
|
10
|
+
import { parseSiteUrl } from "../options.js";
|
|
11
|
+
import { UsageError, commandName, findCommand, kebab, methodArguments, splitLine } from "./args.js";
|
|
12
|
+
import { COMMANDS } from "./commands.generated.js";
|
|
13
|
+
import { lockBackground } from "./background.js";
|
|
14
|
+
import { forgetSite, listSites, loadConfig, loadSite, nameProfile, pendingProfile, profileFor, saveConfig, saveSite } from "./config.js";
|
|
15
|
+
import { render } from "./output.js";
|
|
16
|
+
const firstSentence = (text) => (/^.*?\.(\s|$)/.exec(text)?.[0] ?? text).trim().replace(/\.$/, "");
|
|
17
|
+
export function overview() {
|
|
18
|
+
const width = Math.max(...COMMANDS.map((c) => kebab(c.name).length));
|
|
19
|
+
return [
|
|
20
|
+
"moodle: every operation of moodle-driver, from a terminal.",
|
|
21
|
+
"",
|
|
22
|
+
"Usage: moodle <command> [arguments] [--options]",
|
|
23
|
+
"",
|
|
24
|
+
"Start with: moodle login --site https://campus.example.org/",
|
|
25
|
+
"Then: moodle list-courses, moodle my-grades 3, moodle help <command>",
|
|
26
|
+
"",
|
|
27
|
+
"Global options:",
|
|
28
|
+
" --site <url> The Moodle site (remembered after login; or MOODLE_SITE)",
|
|
29
|
+
" --as <name> The profile on the site, by name (or MOODLE_AS; the site's default unless told)",
|
|
30
|
+
" --profile <dir> A browser profile folder of your own (or MOODLE_PROFILE)",
|
|
31
|
+
" --json Print JSON (the default when the output isn't a terminal)",
|
|
32
|
+
" --show Show the browser while the command works",
|
|
33
|
+
" --allow <list> Refuse commands that touch other data categories (own,course-content,…)",
|
|
34
|
+
" --help, --version",
|
|
35
|
+
"",
|
|
36
|
+
"The command's own:",
|
|
37
|
+
` ${"shell".padEnd(width)} Types commands one after another on one browser, kept open (with --show, watch each act)`,
|
|
38
|
+
` ${"open".padEnd(width)} Leaves a browser open in the background (--show: a window) that every command connects to`,
|
|
39
|
+
` ${"close".padEnd(width)} Closes the background browser, saving the session`,
|
|
40
|
+
` ${"sites".padEnd(width)} The sites and profiles logged in to, which is the default, and whether each has a session`,
|
|
41
|
+
` ${"forget".padEnd(width)} Deletes a site and its sessions (forget <site>), or one account's profile (--as <name>)`,
|
|
42
|
+
"",
|
|
43
|
+
"Commands:",
|
|
44
|
+
...COMMANDS.map((c) => ` ${kebab(c.name).padEnd(width)} ${firstSentence(c.description).slice(0, 90)}`),
|
|
45
|
+
].join("\n");
|
|
46
|
+
}
|
|
47
|
+
function commandHelp(command) {
|
|
48
|
+
const usage = [`moodle ${kebab(command.name)}`, ...command.params.map((p) => (p.optional ? `[${p.name}]` : `<${p.name}>`)), ...(command.options ? ["[--options]"] : [])].join(" ");
|
|
49
|
+
const lines = [`Usage: ${usage}`, "", command.description];
|
|
50
|
+
if (command.params.length > 0) {
|
|
51
|
+
lines.push("", "Arguments:");
|
|
52
|
+
for (const p of command.params)
|
|
53
|
+
lines.push(` ${p.name}${p.optional ? " (optional)" : ""} ${p.type}${p.description ? ` ${p.description}` : ""}`);
|
|
54
|
+
}
|
|
55
|
+
if (command.options) {
|
|
56
|
+
lines.push("", `Options (--json '{…}' gives ${command.options.name} whole):`);
|
|
57
|
+
for (const f of command.options.fields)
|
|
58
|
+
lines.push(` --${kebab(f.name)}${f.optional ? "" : " (required)"} ${f.type}${f.description ? ` ${f.description}` : ""}`);
|
|
59
|
+
if (command.options.open)
|
|
60
|
+
lines.push(` --<name> <value> any other field of ${command.options.name}`);
|
|
61
|
+
}
|
|
62
|
+
const categories = categoriesOf(command.name);
|
|
63
|
+
if (categories)
|
|
64
|
+
lines.push("", `Data: ${categories.join(", ")}`);
|
|
65
|
+
return lines.join("\n");
|
|
66
|
+
}
|
|
67
|
+
const categoriesOf = (name) => DATA_CATEGORIES[name] ?? DATA_CATEGORIES[`Moodle.${name}`];
|
|
68
|
+
/** The data categories of `--allow`, checked: a `UsageError` names the unknown ones. */
|
|
69
|
+
export function allowedCategories(allow) {
|
|
70
|
+
const allowed = allow.split(",").map((c) => c.trim());
|
|
71
|
+
const unknown = allowed.filter((c) => !ALL_DATA_CATEGORIES.includes(c));
|
|
72
|
+
if (unknown.length > 0)
|
|
73
|
+
throw new UsageError(`Unknown data categories in --allow: ${unknown.join(", ")}. They are ${ALL_DATA_CATEGORIES.join(", ")}.`);
|
|
74
|
+
return allowed;
|
|
75
|
+
}
|
|
76
|
+
/** The site a line works on: `--site`, the session's, `MOODLE_SITE`, the last one logged in to. */
|
|
77
|
+
function siteOf(deps, session, global) {
|
|
78
|
+
const raw = global.site ?? session.defaults.site ?? deps.env.MOODLE_SITE ?? loadConfig(deps.home).site;
|
|
79
|
+
return raw ? parseSiteUrl(raw) : undefined;
|
|
80
|
+
}
|
|
81
|
+
/** The site and profile a line works on, as far as they're known: `undefined` before the first login. */
|
|
82
|
+
export function targetOf(deps, session, global = { json: false, show: false, help: false, version: false }) {
|
|
83
|
+
const site = siteOf(deps, session, global);
|
|
84
|
+
if (!site)
|
|
85
|
+
return undefined;
|
|
86
|
+
const ownProfile = global.profile ?? session.defaults.profile ?? deps.env.MOODLE_PROFILE;
|
|
87
|
+
const chosen = profileFor(deps.home, site, { profile: ownProfile, as: global.as ?? session.defaults.as ?? deps.env.MOODLE_AS });
|
|
88
|
+
return chosen && { site, profileDir: chosen.profileDir, name: chosen.name, ownProfile };
|
|
89
|
+
}
|
|
90
|
+
/** Why a site has no profile to work with, and what to do. */
|
|
91
|
+
function noProfile(deps, site) {
|
|
92
|
+
const names = listSites(deps.home).filter((p) => p.site === site).map((p) => p.profile);
|
|
93
|
+
if (names.length > 0)
|
|
94
|
+
return new UsageError(`${site} has no default profile: pick one with --as (${names.join(", ")}), or make one the default with \`moodle login --as <name>\`.`);
|
|
95
|
+
return new UsageError(`No profile for ${site} yet: log in with \`moodle login --site ${site}\`.`);
|
|
96
|
+
}
|
|
97
|
+
/** The session's Moodle object for a site and profile: the open one when it's theirs, else a new one (the old one closed). */
|
|
98
|
+
async function moodleFor(deps, session, site, profileDir) {
|
|
99
|
+
const open = session.open;
|
|
100
|
+
if (open && open.site === site && open.profileDir === profileDir)
|
|
101
|
+
return open.moodle;
|
|
102
|
+
await closeSession(session);
|
|
103
|
+
const progress = deps.interactive ? (elapsed, total) => deps.stderr(` reading… ${Math.round(elapsed)}${total ? `/${Math.round(total)}` : ""} s`) : undefined;
|
|
104
|
+
const defaults = { downloadDir: deps.cwd, onProgress: progress };
|
|
105
|
+
// A browser `moodle open` left on the profile: connected to, one command at a time (ADR-014).
|
|
106
|
+
const background = await backgroundBrowser(profileDir);
|
|
107
|
+
if (background) {
|
|
108
|
+
const release = await lockBackground(profileDir, deps.lockWaitMs);
|
|
109
|
+
try {
|
|
110
|
+
const moodle = deps.createMoodle({ site, browser: connectBrowserManager({ ...background, profileDir }), ...defaults });
|
|
111
|
+
session.open = { moodle, site, profileDir, release };
|
|
112
|
+
return moodle;
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
release();
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const moodle = deps.createMoodle({ site, profileDir, headless: true, downloadBrowser: true, ...defaults });
|
|
120
|
+
session.open = { moodle, site, profileDir };
|
|
121
|
+
if (session.show)
|
|
122
|
+
await moodle.setVisible(true);
|
|
123
|
+
return moodle;
|
|
124
|
+
}
|
|
125
|
+
/** Closes the session's browser, saving the session (ADR-003); the next line opens it again. */
|
|
126
|
+
export async function closeSession(session) {
|
|
127
|
+
const open = session.open;
|
|
128
|
+
session.open = undefined;
|
|
129
|
+
await open?.moodle.close().catch(() => undefined);
|
|
130
|
+
open?.release?.();
|
|
131
|
+
}
|
|
132
|
+
/** Opens the session's browser now, for its site and profile (`--show` and `show` in the shell, `use`). */
|
|
133
|
+
export async function openSession(deps, session) {
|
|
134
|
+
const site = siteOf(deps, session, { json: false, show: false, help: false, version: false });
|
|
135
|
+
if (!site)
|
|
136
|
+
throw new UsageError("No site yet: log in first with `login --site https://campus.example.org/`.");
|
|
137
|
+
const target = targetOf(deps, session);
|
|
138
|
+
if (!target)
|
|
139
|
+
throw noProfile(deps, site);
|
|
140
|
+
const moodle = await moodleFor(deps, session, target.site, target.profileDir);
|
|
141
|
+
if (session.show && !moodle.visible())
|
|
142
|
+
await moodle.setVisible(true);
|
|
143
|
+
return target;
|
|
144
|
+
}
|
|
145
|
+
/** Prints an error as the command does, and says its exit status (2 a command line that doesn't fit, else 1). */
|
|
146
|
+
export function report(deps, error) {
|
|
147
|
+
if (error instanceof UsageError) {
|
|
148
|
+
deps.stderr(`${error.message}\n${error.message.includes("moodle help") ? "" : "`moodle help` lists the commands; `moodle help <command>` explains one."}`.trimEnd());
|
|
149
|
+
return 2;
|
|
150
|
+
}
|
|
151
|
+
if (error instanceof NotLoggedInError) {
|
|
152
|
+
deps.stderr(`${error.code}: ${error.message}\nLog in again with \`moodle login\`.`);
|
|
153
|
+
return 1;
|
|
154
|
+
}
|
|
155
|
+
if (error instanceof MoodleError) {
|
|
156
|
+
deps.stderr(`${error.code}: ${error.message}`);
|
|
157
|
+
return 1;
|
|
158
|
+
}
|
|
159
|
+
deps.stderr(error instanceof Error ? error.message : String(error));
|
|
160
|
+
return 1;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Runs one command line on the session, leaving its browser open for the next line; returns the exit
|
|
164
|
+
* status (0 done, 1 failed, 2 a command line that doesn't fit).
|
|
165
|
+
*/
|
|
166
|
+
export async function runLine(argv, deps, session) {
|
|
167
|
+
// A first login's provisional profile, removed if the login doesn't get to name it.
|
|
168
|
+
let pending;
|
|
169
|
+
try {
|
|
170
|
+
const typed = commandName(argv);
|
|
171
|
+
const own = typed === "sites" || typed === "forget" || typed === "open" || typed === "close";
|
|
172
|
+
const command = typed && typed !== "help" && !own ? findCommand(COMMANDS, typed) : undefined;
|
|
173
|
+
const { global, positionals, flags } = splitLine(argv, command);
|
|
174
|
+
const json = global.json || Boolean(session.defaults.json) || !deps.interactive;
|
|
175
|
+
if (global.version) {
|
|
176
|
+
deps.stdout(deps.version);
|
|
177
|
+
return 0;
|
|
178
|
+
}
|
|
179
|
+
if (typed === "help") {
|
|
180
|
+
const about = positionals[0] ? findCommand(COMMANDS, positionals[0]) : undefined;
|
|
181
|
+
if (positionals[0] && !about)
|
|
182
|
+
throw new UsageError(`There's no command "${positionals[0]}".`);
|
|
183
|
+
deps.stdout(about ? commandHelp(about) : overview());
|
|
184
|
+
return 0;
|
|
185
|
+
}
|
|
186
|
+
if (!typed) {
|
|
187
|
+
deps.stdout(overview());
|
|
188
|
+
return global.help ? 0 : 2;
|
|
189
|
+
}
|
|
190
|
+
if (typed === "sites") {
|
|
191
|
+
const text = render(listSites(deps.home), json);
|
|
192
|
+
deps.stdout(text === "(none)" ? "No sites yet: `moodle login --site https://campus.example.org/`." : text);
|
|
193
|
+
return 0;
|
|
194
|
+
}
|
|
195
|
+
if (typed === "forget") {
|
|
196
|
+
const target = positionals[0];
|
|
197
|
+
if (!target)
|
|
198
|
+
throw new UsageError("forget needs <site>: `moodle sites` lists them.");
|
|
199
|
+
// The browser may be on the profile going away, or a background one.
|
|
200
|
+
await closeSession(session);
|
|
201
|
+
const site = parseSiteUrl(target);
|
|
202
|
+
for (const row of listSites(deps.home))
|
|
203
|
+
if (row.site === site && (global.as === undefined || row.profile === global.as))
|
|
204
|
+
await closeBackgroundBrowser(row.path).catch(() => undefined);
|
|
205
|
+
const gone = forgetSite(deps.home, site, global.as);
|
|
206
|
+
if (gone.length === 0) {
|
|
207
|
+
deps.stderr(`not-found: ${target}${global.as ? ` has no profile ${global.as}` : " isn't a site logged in to"}; \`moodle sites\` lists them.`);
|
|
208
|
+
return 1;
|
|
209
|
+
}
|
|
210
|
+
deps.stdout(`✔ Deleted ${gone.join(", ")}`);
|
|
211
|
+
return 0;
|
|
212
|
+
}
|
|
213
|
+
if (typed === "open" || typed === "close")
|
|
214
|
+
return await background(typed, deps, session, global, positionals);
|
|
215
|
+
if (!command)
|
|
216
|
+
throw new UsageError(`There's no command "${typed}". \`moodle help\` lists them.`);
|
|
217
|
+
if (global.help) {
|
|
218
|
+
deps.stdout(commandHelp(command));
|
|
219
|
+
return 0;
|
|
220
|
+
}
|
|
221
|
+
const site = siteOf(deps, session, global);
|
|
222
|
+
if (!site)
|
|
223
|
+
throw new UsageError("No site yet: log in first with `moodle login --site https://campus.example.org/`, or give --site.");
|
|
224
|
+
const loggingIn = command.name === "logIn";
|
|
225
|
+
const chosen = targetOf(deps, session, global);
|
|
226
|
+
// A first login with no name for its profile: a provisional folder, named after the person's username once in.
|
|
227
|
+
pending = !chosen && loggingIn ? pendingProfile(deps.home, site) : undefined;
|
|
228
|
+
// What anyone can ask without logging in needs no browser, so no profile either.
|
|
229
|
+
const browserless = command.name === "publicSiteInfo";
|
|
230
|
+
if (!chosen && !pending && !browserless)
|
|
231
|
+
throw noProfile(deps, site);
|
|
232
|
+
// A browserless command never opens this folder: the object launches no browser until it needs one.
|
|
233
|
+
const profileDir = chosen?.profileDir ?? pending ?? path.join(deps.home, "sites", ".none");
|
|
234
|
+
// A profile logged in to for the first time has its folder from now on, browser or not.
|
|
235
|
+
if (loggingIn)
|
|
236
|
+
mkdirSync(profileDir, { recursive: true });
|
|
237
|
+
const allow = global.allow ?? session.defaults.allow;
|
|
238
|
+
if (allow) {
|
|
239
|
+
const allowed = allowedCategories(allow);
|
|
240
|
+
const outside = (categoriesOf(command.name) ?? ["any"]).filter((c) => !allowed.includes(c));
|
|
241
|
+
if (outside.length > 0) {
|
|
242
|
+
deps.stderr(`refused: ${kebab(command.name)} touches ${outside.join(", ")}, outside --allow ${allowed.join(",")}.`);
|
|
243
|
+
return 1;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const args = methodArguments(command, positionals, flags, deps.cwd);
|
|
247
|
+
const moodle = await moodleFor(deps, session, site, profileDir);
|
|
248
|
+
if (global.show && !moodle.visible())
|
|
249
|
+
await moodle.setVisible(true);
|
|
250
|
+
const method = moodle[command.name];
|
|
251
|
+
const result = await method.apply(moodle, args);
|
|
252
|
+
if (loggingIn) {
|
|
253
|
+
// The site becomes the default, and the profile logged in with becomes the site's.
|
|
254
|
+
let name = chosen?.name;
|
|
255
|
+
if (pending) {
|
|
256
|
+
const userId = result.userId;
|
|
257
|
+
const username = await moodle.whoAmI().then((me) => me.username).catch(() => undefined);
|
|
258
|
+
// The folder is renamed: the browser on it closes, and the next line opens it on the named one.
|
|
259
|
+
await closeSession(session);
|
|
260
|
+
name = nameProfile(deps.home, site, pending, username ?? `user-${userId}`);
|
|
261
|
+
pending = undefined;
|
|
262
|
+
}
|
|
263
|
+
else if (!session.show && session.open) {
|
|
264
|
+
// A window opened only to log in closes; the next line runs headless.
|
|
265
|
+
await session.open.moodle.setVisible(false).catch(() => undefined);
|
|
266
|
+
}
|
|
267
|
+
const record = loadSite(deps.home, site);
|
|
268
|
+
saveSite(deps.home, { url: site, default: chosen?.ownProfile ? undefined : name, profileDir: chosen?.ownProfile ?? record?.profileDir });
|
|
269
|
+
saveConfig(deps.home, { ...loadConfig(deps.home), site });
|
|
270
|
+
// The session goes on with the site and profile logged in to.
|
|
271
|
+
session.defaults.site = site;
|
|
272
|
+
if (name)
|
|
273
|
+
session.defaults.as = name;
|
|
274
|
+
if (name && deps.interactive)
|
|
275
|
+
deps.stderr(`Profile "${name}" is the default for ${site}.`);
|
|
276
|
+
}
|
|
277
|
+
const text = render(result, json);
|
|
278
|
+
if (text)
|
|
279
|
+
deps.stdout(text);
|
|
280
|
+
return 0;
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
return report(deps, error);
|
|
284
|
+
}
|
|
285
|
+
finally {
|
|
286
|
+
if (pending) {
|
|
287
|
+
if (session.open?.profileDir === pending)
|
|
288
|
+
await closeSession(session);
|
|
289
|
+
rmSync(pending, { recursive: true, force: true });
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/** `moodle open [--show]` and `moodle close`: the profile's background browser (ADR-014). */
|
|
294
|
+
async function background(typed, deps, session, global, positionals) {
|
|
295
|
+
if (positionals.length > 0)
|
|
296
|
+
throw new UsageError(`${typed} takes no arguments, only the global options (--site, --as, --profile${typed === "open" ? ", --show" : ""}).`);
|
|
297
|
+
const site = siteOf(deps, session, global);
|
|
298
|
+
if (!site)
|
|
299
|
+
throw new UsageError("No site yet: log in first with `moodle login --site https://campus.example.org/`, or give --site.");
|
|
300
|
+
const target = targetOf(deps, session, global);
|
|
301
|
+
if (!target)
|
|
302
|
+
throw noProfile(deps, site);
|
|
303
|
+
const profile = target.name ? `profile "${target.name}"` : target.profileDir;
|
|
304
|
+
const json = global.json || Boolean(session.defaults.json) || !deps.interactive;
|
|
305
|
+
// A browser this session opened on the profile would hold it: closed first.
|
|
306
|
+
if (session.open?.profileDir === target.profileDir)
|
|
307
|
+
await closeSession(session);
|
|
308
|
+
if (typed === "close") {
|
|
309
|
+
if (!(await closeBackgroundBrowser(target.profileDir))) {
|
|
310
|
+
deps.stderr(`not-found: there's no background browser on ${profile} of ${site}.`);
|
|
311
|
+
return 1;
|
|
312
|
+
}
|
|
313
|
+
deps.stdout(render({ changed: `Closed the background browser on ${profile} of ${site}, its session saved.` }, json));
|
|
314
|
+
return 0;
|
|
315
|
+
}
|
|
316
|
+
const running = await backgroundBrowser(target.profileDir);
|
|
317
|
+
if (running) {
|
|
318
|
+
deps.stdout(render({ changed: `Nothing: a background browser is already open on ${profile} of ${site}${running.headed ? ", with a window" : ""}.`, headed: running.headed }, json));
|
|
319
|
+
return 0;
|
|
320
|
+
}
|
|
321
|
+
if (!deps.startBackground)
|
|
322
|
+
throw new MoodleError("This program can't start a background browser.", "not-available");
|
|
323
|
+
await deps.startBackground(target.profileDir, global.show || session.show);
|
|
324
|
+
const started = await backgroundBrowser(target.profileDir);
|
|
325
|
+
deps.stdout(render({ changed: `Opened a background browser on ${profile} of ${site}${started?.headed ? ", with a window" : ""}: commands on it work there until \`moodle close\`.`, headed: started?.headed ?? false }, json));
|
|
326
|
+
return 0;
|
|
327
|
+
}
|
|
328
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/cli/command.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,qGAAqG;AACrG,wCAAwC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC5G,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAqB,MAAM,kBAAkB,CAAC;AAE3F,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,EAAE,SAAS,EAAoB,MAAM,WAAW,CAAC;AACtH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACzI,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAmDrC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAE3G,MAAM,UAAU,QAAQ;IACtB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACrE,OAAO;QACL,4DAA4D;QAC5D,EAAE;QACF,iDAAiD;QACjD,EAAE;QACF,8DAA8D;QAC9D,6EAA6E;QAC7E,EAAE;QACF,iBAAiB;QACjB,+EAA+E;QAC/E,sGAAsG;QACtG,+EAA+E;QAC/E,gFAAgF;QAChF,+DAA+D;QAC/D,8FAA8F;QAC9F,qBAAqB;QACrB,EAAE;QACF,oBAAoB;QACpB,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4FAA4F;QACtH,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,6FAA6F;QACtH,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qDAAqD;QAC/E,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6FAA6F;QACvH,KAAK,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,2FAA2F;QACtH,EAAE;QACF,WAAW;QACX,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;KACzG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,OAAoB;IACvC,MAAM,KAAK,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnL,MAAM,KAAK,GAAG,CAAC,UAAU,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3D,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;QAC7B,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrJ,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,+BAA+B,OAAO,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,CAAC;QAC9E,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpK,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,0CAA0C,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzG,CAAC;IACD,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,YAAY,GAAG,CAAC,IAAY,EAAuC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;AAEvI,wFAAwF;AACxF,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAmB,CAAC;IACxE,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,uCAAuC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvJ,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,mGAAmG;AACnG,SAAS,MAAM,CAAC,IAAa,EAAE,OAAmB,EAAE,MAAmB;IACrE,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;IACvG,OAAO,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7C,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,QAAQ,CAAC,IAAa,EAAE,OAAmB,EAAE,SAAsB,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;IAC1I,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC;IACzF,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;IAChI,OAAO,MAAM,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;AAC1F,CAAC;AAED,8DAA8D;AAC9D,SAAS,SAAS,CAAC,IAAa,EAAE,IAAY;IAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACxF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,UAAU,CAAC,GAAG,IAAI,gDAAgD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;IACpL,OAAO,IAAI,UAAU,CAAC,kBAAkB,IAAI,2CAA2C,IAAI,KAAK,CAAC,CAAC;AACpG,CAAC;AAED,8HAA8H;AAC9H,KAAK,UAAU,SAAS,CAAC,IAAa,EAAE,OAAmB,EAAE,IAAY,EAAE,UAAkB;IAC3F,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1B,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC;IACrF,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAe,EAAE,KAAc,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/K,MAAM,QAAQ,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;IACjE,8FAA8F;IAC9F,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACvD,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAClE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,qBAAqB,CAAC,EAAE,GAAG,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;YACvH,OAAO,CAAC,IAAI,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;YACrD,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,CAAC;YACV,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;IAC3G,OAAO,CAAC,IAAI,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAC5C,IAAI,OAAO,CAAC,IAAI;QAAE,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gGAAgG;AAChG,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAmB;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1B,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IACzB,MAAM,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAClD,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;AACpB,CAAC;AAED,2GAA2G;AAC3G,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAa,EAAE,OAAmB;IAClE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9F,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,UAAU,CAAC,4EAA4E,CAAC,CAAC;IAC9G,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM;QAAE,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC9E,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;QAAE,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,iHAAiH;AACjH,MAAM,UAAU,MAAM,CAAC,IAAa,EAAE,KAAc;IAClD,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,yEAAyE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QACrK,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,uCAAuC,CAAC,CAAC;QACpF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAc,EAAE,IAAa,EAAE,OAAmB;IAC9E,oFAAoF;IACpF,IAAI,OAA2B,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,GAAG,GAAG,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,CAAC;QAC7F,MAAM,OAAO,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7F,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAChE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;QAChF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1B,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACjF,IAAI,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,UAAU,CAAC,uBAAuB,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC9F,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;YACrD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACxB,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;YAChD,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,kEAAkE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC3G,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,UAAU,CAAC,iDAAiD,CAAC,CAAC;YACrF,qEAAqE;YACrE,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;YAC5B,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;YAClC,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,SAAS,IAAI,GAAG,CAAC,OAAO,KAAK,MAAM,CAAC,EAAE,CAAC;oBAAE,MAAM,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACvL,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YACpD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,MAAM,CAAC,cAAc,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,4BAA4B,gCAAgC,CAAC,CAAC;gBAC9I,OAAO,CAAC,CAAC;YACX,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5C,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO;YAAE,OAAO,MAAM,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QAC9G,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,UAAU,CAAC,uBAAuB,KAAK,gCAAgC,CAAC,CAAC;QACjG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;YAClC,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,UAAU,CAAC,mGAAmG,CAAC,CAAC;QACrI,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC;QAC3C,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC/C,+GAA+G;QAC/G,OAAO,GAAG,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7E,iFAAiF;QACjF,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,KAAK,gBAAgB,CAAC;QACtD,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,IAAI,CAAC,WAAW;YAAE,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACrE,oGAAoG;QACpG,MAAM,UAAU,GAAG,MAAM,EAAE,UAAU,IAAI,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3F,wFAAwF;QACxF,IAAI,SAAS;YAAE,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE1D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;QACrD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACzC,MAAM,OAAO,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5F,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,IAAI,CAAC,MAAM,CAAC,YAAY,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACpH,OAAO,CAAC,CAAC;YACX,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QAChE,IAAI,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;YAAE,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,MAAM,GAAI,MAA2E,CAAC,OAAO,CAAC,IAAI,CAAE,CAAC;QAC3G,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChD,IAAI,SAAS,EAAE,CAAC;YACd,mFAAmF;YACnF,IAAI,IAAI,GAAG,MAAM,EAAE,IAAI,CAAC;YACxB,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,MAAM,GAAI,MAA6B,CAAC,MAAM,CAAC;gBACrD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBACxF,gGAAgG;gBAChG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;gBAC5B,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,IAAI,QAAQ,MAAM,EAAE,CAAC,CAAC;gBAC3E,OAAO,GAAG,SAAS,CAAC;YACtB,CAAC;iBAAM,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACzC,sEAAsE;gBACtE,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACrE,CAAC;YACD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACzC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,IAAI,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YACzI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,8DAA8D;YAC9D,OAAO,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;YAC7B,IAAI,IAAI;gBAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,IAAI,CAAC;YACrC,IAAI,IAAI,IAAI,IAAI,CAAC,WAAW;gBAAE,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,wBAAwB,IAAI,GAAG,CAAC,CAAC;QAC7F,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,IAAI;YAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;YAAS,CAAC;QACT,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,OAAO,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO;gBAAE,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;YACtE,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;AACH,CAAC;AAED,6FAA6F;AAC7F,KAAK,UAAU,UAAU,CAAC,KAAuB,EAAE,IAAa,EAAE,OAAmB,EAAE,MAAmB,EAAE,WAAqB;IAC/H,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,GAAG,KAAK,wEAAwE,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACzK,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,UAAU,CAAC,mGAAmG,CAAC,CAAC;IACrI,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM;QAAE,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;IAC7E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;IAChF,4EAA4E;IAC5E,IAAI,OAAO,CAAC,IAAI,EAAE,UAAU,KAAK,MAAM,CAAC,UAAU;QAAE,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;IAChF,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,MAAM,sBAAsB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,MAAM,CAAC,+CAA+C,OAAO,OAAO,IAAI,GAAG,CAAC,CAAC;YAClF,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,oCAAoC,OAAO,OAAO,IAAI,sBAAsB,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACrH,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3D,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,oDAAoD,OAAO,OAAO,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACpL,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,eAAe;QAAE,MAAM,IAAI,WAAW,CAAC,gDAAgD,EAAE,eAAe,CAAC,CAAC;IACpH,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3D,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,kCAAkC,OAAO,OAAO,IAAI,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,qDAAqD,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/N,OAAO,CAAC,CAAC;AACX,CAAC"}
|