laneyard 0.4.1 → 0.6.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 +312 -282
- package/dist/src/cli/adopt.js +221 -0
- package/dist/src/cli/home.js +46 -0
- package/dist/src/cli/remove.js +195 -0
- package/dist/src/cli/reset.js +117 -0
- package/dist/src/cli/setup.js +123 -11
- package/dist/src/cli/uninstall.js +2 -24
- package/dist/src/config/accounts.js +103 -39
- package/dist/src/config/load.js +3 -27
- package/dist/src/config/resolve.js +36 -0
- package/dist/src/config/schema.js +25 -9
- package/dist/src/config/store.js +27 -3
- package/dist/src/data/remove-project.js +70 -0
- package/dist/src/db/runs.js +11 -0
- package/dist/src/fastfile/adoption.js +142 -0
- package/dist/src/fastfile/splice.js +38 -0
- package/dist/src/logs/store.js +9 -1
- package/dist/src/main.js +24 -16
- package/dist/src/secrets/vault.js +6 -5
- package/dist/src/server/app.js +17 -12
- package/dist/src/server/permissions.js +50 -0
- package/dist/src/server/routes/account.js +56 -1
- package/dist/src/server/routes/fastfile.js +7 -0
- package/dist/src/server/routes/projects.js +95 -86
- package/dist/src/server/routes/users.js +47 -4
- package/dist/src/sidecar/bridge.js +5 -4
- package/dist/src/sidecar/fastlane-dir.js +8 -8
- package/dist/src/sidecar/prism-ruby.js +42 -0
- package/dist/src/sidecar/scan.js +44 -0
- package/dist/web/assets/{Editor-9nLYwtg7.js → Editor-CMa4-4N3.js} +1 -1
- package/dist/web/assets/index-B8lAQPEM.js +62 -0
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
- package/ruby/scan.rb +176 -0
- package/dist/web/assets/index-pzPa9EZr.js +0 -62
|
@@ -1,40 +1,69 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { accountMayReach } from "../permissions.js";
|
|
2
|
+
import { removeProjectData } from "../../data/remove-project.js";
|
|
3
3
|
export async function registerProjectRoutes(app, ctx) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
// The listing every account is shown, filtered to what it may reach. This is
|
|
5
|
+
// the source of the invisibility the interface shows — the nav and the project
|
|
6
|
+
// list are driven by it, so a filtered response filters the UI with no change
|
|
7
|
+
// beyond what the data carries. The account is looked up fresh, the way the
|
|
8
|
+
// auth hook does, because config.yml is the truth on every request. An admin,
|
|
9
|
+
// and a builder with no `projects` field, are served every project.
|
|
10
|
+
app.get("/api/projects", async (req) => {
|
|
11
|
+
const account = ctx.config.server()?.users.find((u) => u.name === req.identity.name);
|
|
12
|
+
return ctx.config
|
|
13
|
+
.projects()
|
|
14
|
+
.filter((p) => account !== undefined && accountMayReach(account, p.slug))
|
|
15
|
+
.map((p) => {
|
|
16
|
+
const last = ctx.runs.listByProject(p.slug, 1)[0] ?? null;
|
|
17
|
+
return {
|
|
18
|
+
slug: p.slug,
|
|
19
|
+
name: p.name,
|
|
20
|
+
color: p.color,
|
|
21
|
+
lastRun: last && { id: last.id, status: last.status, lane: last.lane, finishedAt: last.finishedAt },
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
});
|
|
13
25
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
26
|
+
* Removes everything Laneyard holds for a project, in one confirmed act.
|
|
27
|
+
*
|
|
28
|
+
* It is the destructive route in the product, and it is destructive on
|
|
29
|
+
* purpose. The block leaves config.yml, through the YAML document so the rest
|
|
30
|
+
* of a hand-written file is untouched; the clone is deleted; every artifact
|
|
31
|
+
* folder goes; the run history — the rows and their logs — is deleted; and
|
|
32
|
+
* the project's own secrets and signing blocks are forgotten from the vault.
|
|
33
|
+
* The history is the one thing here that cannot be made again, which is why
|
|
34
|
+
* the whole act is behind a slug typed back rather than a click.
|
|
16
35
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* -
|
|
20
|
-
*
|
|
21
|
-
* - the
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
36
|
+
* What it still does not reach, and why each is out of scope:
|
|
37
|
+
*
|
|
38
|
+
* - the git remote. The repository is on GitHub and on the user's disk. It
|
|
39
|
+
* is theirs, not Laneyard's, and nothing here reads or writes it.
|
|
40
|
+
* - the credential originals. Laneyard removes its own encrypted copy of a
|
|
41
|
+
* `.p8` or a keystore; the file that went in is still in the password
|
|
42
|
+
* manager or the safe it came from. The answer says so, the way
|
|
43
|
+
* `uninstall` does, so nobody is left thinking their keystore is gone.
|
|
44
|
+
* - global secrets and global signing blocks. They are read by every project
|
|
45
|
+
* on the machine, not this one's to take — `vault.forget` touches only
|
|
46
|
+
* slug-scoped rows, and the answer counts the global ones it left alone.
|
|
47
|
+
*
|
|
48
|
+
* The confirmation is the project's own slug, sent back as `?confirm=`.
|
|
49
|
+
* Without a match nothing is removed: a bare DELETE is a refusal, not a
|
|
50
|
+
* deletion. This is the gate `laneyard uninstall` uses for the same reason —
|
|
51
|
+
* the one irreversible thing must not be reachable by a reflex.
|
|
32
52
|
*/
|
|
33
53
|
app.delete("/api/projects/:slug", async (req, reply) => {
|
|
34
54
|
const { slug } = req.params;
|
|
55
|
+
const { confirm } = req.query;
|
|
35
56
|
const entry = ctx.config.project(slug);
|
|
36
57
|
if (!entry)
|
|
37
58
|
return reply.code(404).send({ error: "Unknown project" });
|
|
59
|
+
// The slug typed back is the confirmation. This deletes the run history,
|
|
60
|
+
// which nothing can rebuild, so a request that does not carry the slug
|
|
61
|
+
// removes nothing and says why.
|
|
62
|
+
if (confirm !== slug) {
|
|
63
|
+
return reply.code(400).send({
|
|
64
|
+
error: `Removing "${slug}" deletes its runs, its clone, its artifacts and its stored secrets, and cannot be undone. Send the project's slug as confirmation to remove it. Nothing was removed.`,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
38
67
|
// A run that has begun is reading the workspace this project points at.
|
|
39
68
|
// Queued runs are not: the queue already fails a run whose project went
|
|
40
69
|
// away, so waiting on them would only mean refusing for longer.
|
|
@@ -43,69 +72,49 @@ export async function registerProjectRoutes(app, ctx) {
|
|
|
43
72
|
error: `"${slug}" has a run in flight. Wait for it to finish, or cancel it, then remove the project.`,
|
|
44
73
|
});
|
|
45
74
|
}
|
|
46
|
-
|
|
47
|
-
|
|
75
|
+
// The global counts are read now — the last moment anyone is looking — so
|
|
76
|
+
// the answer can say what it left alone. They are shared by every project
|
|
77
|
+
// and survive one of them going away, which is why the removal never takes
|
|
78
|
+
// them and the reply names them apart.
|
|
79
|
+
const globalSecrets = ctx.vault.listGlobal().length;
|
|
80
|
+
const globalSigningBlocks = ctx.vault.listGlobalCredentials().length;
|
|
81
|
+
// The removal itself lives in one place, shared with `laneyard remove`: the
|
|
82
|
+
// route confirms and shapes the reply, the core does the deleting.
|
|
83
|
+
const result = await removeProjectData({
|
|
84
|
+
configPath: ctx.config.configPath(),
|
|
85
|
+
// The file is watched, but on a debounce: reloading here is what makes
|
|
86
|
+
// the very next request — the listing this page is about to ask for —
|
|
87
|
+
// truthful.
|
|
88
|
+
reloadConfig: () => ctx.config.load(),
|
|
89
|
+
runs: ctx.runs,
|
|
90
|
+
logs: ctx.logs,
|
|
91
|
+
vault: ctx.vault,
|
|
92
|
+
workspacePath: ctx.workspacePath,
|
|
93
|
+
artifactsDir: ctx.artifactsDir,
|
|
94
|
+
}, slug);
|
|
95
|
+
if (!result.found)
|
|
48
96
|
return reply.code(404).send({ error: "Unknown project" });
|
|
49
|
-
// The
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
// behind, and a project with sixty runs must not be told about fifty of them.
|
|
54
|
-
const runs = ctx.runs.listByProject(slug, -1);
|
|
55
|
-
const leftOnDisk = [
|
|
56
|
-
ctx.workspacePath(slug),
|
|
57
|
-
...runs.map((run) => ctx.artifactsDir(run.id)),
|
|
58
|
-
].filter((path) => existsSync(path));
|
|
59
|
-
// Counted after the block is gone, and read from the vault rather than
|
|
60
|
-
// inferred: the two stores are the only thing that knows, and this is the
|
|
61
|
-
// last moment anyone is looking.
|
|
62
|
-
const owned = ctx.vault.ownedBy(slug);
|
|
97
|
+
// The slug is also stripped from every account's access grants, in the core
|
|
98
|
+
// beside the other "forget for this slug" steps: a grant pointing at a
|
|
99
|
+
// project that no longer exists is dead data, and a project re-created later
|
|
100
|
+
// under the same slug must not silently inherit an old grant.
|
|
63
101
|
return reply.send({
|
|
64
102
|
slug,
|
|
65
103
|
name: entry.name,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
104
|
+
removed: {
|
|
105
|
+
runs: result.runs,
|
|
106
|
+
artifacts: result.artifacts,
|
|
107
|
+
workspace: result.workspace,
|
|
108
|
+
secrets: result.secrets,
|
|
109
|
+
signingBlocks: result.signingBlocks,
|
|
110
|
+
},
|
|
111
|
+
// Named, not removed. The git remote and the credential originals are the
|
|
112
|
+
// user's and are never touched here; the global rows are shared by every
|
|
113
|
+
// project and survive one of them going away.
|
|
114
|
+
untouched: {
|
|
115
|
+
globalSecrets,
|
|
116
|
+
globalSigningBlocks,
|
|
76
117
|
},
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
/**
|
|
80
|
-
* Removes what the vault still holds under a removed project's name.
|
|
81
|
-
*
|
|
82
|
-
* Deliberately not part of removing the project. That route destroys nothing,
|
|
83
|
-
* and the reason is the one this route has to earn instead: a signing block
|
|
84
|
-
* cannot be read back out of Laneyard — the `.p8` and the keystore that went
|
|
85
|
-
* in are the only copies it ever had — so deleting one on the same click that
|
|
86
|
-
* hides a project from a list would be destroying something unrecoverable as
|
|
87
|
-
* a side effect of tidying up.
|
|
88
|
-
*
|
|
89
|
-
* Refused while the slug is still a project, so this can only ever be the
|
|
90
|
-
* clean-up after a removal. A live project's secrets and blocks are removed
|
|
91
|
-
* one at a time, from the tabs that show them, where the user can see what
|
|
92
|
-
* each one is.
|
|
93
|
-
*
|
|
94
|
-
* Only rows carrying this slug go. A global secret and a global signing block
|
|
95
|
-
* are shared by every project and survive it.
|
|
96
|
-
*/
|
|
97
|
-
app.delete("/api/projects/:slug/vault", async (req, reply) => {
|
|
98
|
-
const { slug } = req.params;
|
|
99
|
-
if (ctx.config.project(slug)) {
|
|
100
|
-
return reply.code(409).send({
|
|
101
|
-
error: `"${slug}" is still a project on this machine. Remove the project first, or remove its secrets and signing blocks one at a time from its own tabs.`,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
const removed = ctx.vault.forget(slug);
|
|
105
|
-
return reply.send({
|
|
106
|
-
slug,
|
|
107
|
-
secretsRemoved: removed.secrets,
|
|
108
|
-
signingBlocksRemoved: removed.credentials,
|
|
109
118
|
});
|
|
110
119
|
});
|
|
111
120
|
app.get("/api/projects/:slug/lanes", async (req, reply) => {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { MIN_PASSWORD_LENGTH, VALID_NAME, refusalFor, removeUserFromConfig, upsertUserInConfig, } from "../../config/accounts.js";
|
|
1
|
+
import { MIN_PASSWORD_LENGTH, VALID_NAME, refusalFor, removeUserFromConfig, setUserProjectsInConfig, upsertUserInConfig, } from "../../config/accounts.js";
|
|
2
|
+
/** The same slug rule the schema enforces, stated once for the grant route. */
|
|
3
|
+
const VALID_SLUG = /^[a-z0-9][a-z0-9-]*$/;
|
|
2
4
|
const ROLES = ["admin", "builder"];
|
|
3
5
|
/**
|
|
4
6
|
* The accounts, as the interface sees them.
|
|
@@ -9,9 +11,12 @@ const ROLES = ["admin", "builder"];
|
|
|
9
11
|
*/
|
|
10
12
|
export async function registerUserRoutes(app, ctx) {
|
|
11
13
|
const accounts = () => ctx.config.server()?.users ?? [];
|
|
12
|
-
// Name
|
|
13
|
-
//
|
|
14
|
-
|
|
14
|
+
// Name, role, and the project grants — never the hash, which is simply never
|
|
15
|
+
// put on the wire. `projects` is sent as it stands: an array when the account
|
|
16
|
+
// carries a grant list, `null` when it has no field at all (every project),
|
|
17
|
+
// the same three-way the storage keeps. The accounts screen ticks a checkbox
|
|
18
|
+
// from it; an admin's is `null` and its checklist is not drawn.
|
|
19
|
+
app.get("/api/users", async () => accounts().map((u) => ({ name: u.name, role: u.role, projects: u.projects ?? null })));
|
|
15
20
|
app.post("/api/users", async (req, reply) => {
|
|
16
21
|
const { name, role, password } = (req.body ?? {});
|
|
17
22
|
if (typeof name !== "string" || !VALID_NAME.test(name)) {
|
|
@@ -46,6 +51,44 @@ export async function registerUserRoutes(app, ctx) {
|
|
|
46
51
|
await ctx.config.load();
|
|
47
52
|
return reply.code(created ? 201 : 200).send({ name, role });
|
|
48
53
|
});
|
|
54
|
+
/**
|
|
55
|
+
* Sets which projects an account may reach.
|
|
56
|
+
*
|
|
57
|
+
* Admin-only, like every route in this file: it is covered by the
|
|
58
|
+
* `/api/users` prefix in `REQUIRES_ADMIN`, so nothing here checks a role. The
|
|
59
|
+
* list is written through the YAML document and takes effect on the next
|
|
60
|
+
* request, since the auth hook re-reads config.yml every time — no session is
|
|
61
|
+
* revoked, because the role has not changed, only what it reaches.
|
|
62
|
+
*
|
|
63
|
+
* An admin has no reach to restrict: the field is ignored for them, so writing
|
|
64
|
+
* one would be a lie the server does not tell. The request is refused rather
|
|
65
|
+
* than quietly written and forgotten.
|
|
66
|
+
*/
|
|
67
|
+
app.put("/api/users/:name/projects", async (req, reply) => {
|
|
68
|
+
const { name } = req.params;
|
|
69
|
+
const { projects } = (req.body ?? {});
|
|
70
|
+
if (!Array.isArray(projects) ||
|
|
71
|
+
!projects.every((p) => typeof p === "string" && VALID_SLUG.test(p))) {
|
|
72
|
+
return reply
|
|
73
|
+
.code(400)
|
|
74
|
+
.send({ error: "Projects is a list of slugs: lowercase letters, digits and hyphens." });
|
|
75
|
+
}
|
|
76
|
+
const account = accounts().find((u) => u.name === name);
|
|
77
|
+
if (!account)
|
|
78
|
+
return reply.code(404).send({ error: "Unknown account" });
|
|
79
|
+
if (account.role === "admin") {
|
|
80
|
+
return reply
|
|
81
|
+
.code(400)
|
|
82
|
+
.send({ error: "An admin reaches every project; there is no access list to set." });
|
|
83
|
+
}
|
|
84
|
+
const written = await setUserProjectsInConfig(ctx.config.configPath(), name, projects);
|
|
85
|
+
if (!written)
|
|
86
|
+
return reply.code(404).send({ error: "Unknown account" });
|
|
87
|
+
// The file is watched on a debounce; reloading here makes the very next
|
|
88
|
+
// request — and the reach check in the hook — see the grant at once.
|
|
89
|
+
await ctx.config.load();
|
|
90
|
+
return reply.code(200).send({ name, projects });
|
|
91
|
+
});
|
|
49
92
|
app.delete("/api/users/:name", async (req, reply) => {
|
|
50
93
|
const { name } = req.params;
|
|
51
94
|
if (!accounts().some((u) => u.name === name)) {
|
|
@@ -7,17 +7,18 @@ import { promisify } from "node:util";
|
|
|
7
7
|
import { FASTLANE_UNAVAILABLE, resolveRubyEnv } from "./ruby-env.js";
|
|
8
8
|
const exec = promisify(execFile);
|
|
9
9
|
/**
|
|
10
|
-
* Locates `
|
|
10
|
+
* Locates a ruby sidecar script (`introspect.rb` by default) from wherever
|
|
11
|
+
* this module happens to live.
|
|
11
12
|
*
|
|
12
13
|
* Two layouts, and only trying one of them is how listing lanes came to be
|
|
13
14
|
* broken in every installed copy while working perfectly from the sources:
|
|
14
15
|
* `src/sidecar/` sits two levels under the package root, `dist/src/sidecar/`
|
|
15
16
|
* sits three. The package ships `ruby/` at its root in both cases.
|
|
16
17
|
*/
|
|
17
|
-
export function resolveSidecarScript(moduleDir) {
|
|
18
|
+
export function resolveSidecarScript(moduleDir, file = "introspect.rb") {
|
|
18
19
|
const candidates = [
|
|
19
|
-
join(moduleDir, "..", "..", "ruby",
|
|
20
|
-
join(moduleDir, "..", "..", "..", "ruby",
|
|
20
|
+
join(moduleDir, "..", "..", "ruby", file),
|
|
21
|
+
join(moduleDir, "..", "..", "..", "ruby", file),
|
|
21
22
|
];
|
|
22
23
|
return candidates.find((candidate) => existsSync(candidate)) ?? candidates[0];
|
|
23
24
|
}
|
|
@@ -6,18 +6,18 @@ import { stat } from "node:fs/promises";
|
|
|
6
6
|
* '…/workspaces/popotheque-app/fastlane'` — technically accurate and no help at
|
|
7
7
|
* all, because the interesting part is *why* it was looking there.
|
|
8
8
|
*
|
|
9
|
-
* It is nearly always the same story
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* It is nearly always the same story: the configured fastlane folder is in the
|
|
10
|
+
* working copy setup ran against, but not in the clone Laneyard builds from. A
|
|
11
|
+
* folder only present locally — never committed, not yet pushed, or gitignored
|
|
12
|
+
* — does not reach the clone, and neither does a `laneyard.yml` that would
|
|
13
|
+
* point at it until it too is committed and pushed.
|
|
14
14
|
*/
|
|
15
15
|
export async function assertFastlaneDir(dir, configured) {
|
|
16
16
|
const found = await stat(dir).then((s) => s.isDirectory(), () => false);
|
|
17
17
|
if (found)
|
|
18
18
|
return;
|
|
19
19
|
throw new Error(`No ${configured}/ in the clone. Laneyard builds from a clone of the remote, ` +
|
|
20
|
-
"so
|
|
21
|
-
"
|
|
22
|
-
"on the project's block in config.yml.");
|
|
20
|
+
"so a fastlane folder that exists only in your working copy — uncommitted, " +
|
|
21
|
+
"unpushed, or gitignored — never reaches it. Commit and push it, or set " +
|
|
22
|
+
"`fastlane_dir` on the project's block in config.yml.");
|
|
23
23
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { resolveRubyEnv } from "./ruby-env.js";
|
|
4
|
+
const exec = promisify(execFile);
|
|
5
|
+
async function canRequirePrism(env) {
|
|
6
|
+
try {
|
|
7
|
+
await exec("ruby", ["-e", 'require "prism"'], { env, timeout: 30_000 });
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
let cached = null;
|
|
15
|
+
/**
|
|
16
|
+
* An environment in which `ruby` can load Prism, or null.
|
|
17
|
+
*
|
|
18
|
+
* Two candidates, cheapest first. `process.env` is right whenever the user's
|
|
19
|
+
* shell already points at a modern Ruby, and costs milliseconds. Only when
|
|
20
|
+
* that fails is `resolveRubyEnv` asked — it probes `require "fastlane"` and is
|
|
21
|
+
* slow, but it finds the Ruby the project actually builds with, which is the
|
|
22
|
+
* one that matters when `PATH` points somewhere else.
|
|
23
|
+
*
|
|
24
|
+
* Measured, and the reason this function exists rather than a bare `ruby`:
|
|
25
|
+
* macOS ships 2.6 at `/usr/bin/ruby`, and Prism is a default gem only from
|
|
26
|
+
* Ruby 3.3. A caller that assumed `ruby` would do would silently never find
|
|
27
|
+
* anything on a machine whose shell had not been set up.
|
|
28
|
+
*
|
|
29
|
+
* Returns null rather than throwing. Every caller treats an absent Ruby as
|
|
30
|
+
* "not analysed", never as a failure.
|
|
31
|
+
*/
|
|
32
|
+
export function resolvePrismRuby() {
|
|
33
|
+
cached ??= (async () => {
|
|
34
|
+
if (await canRequirePrism(process.env))
|
|
35
|
+
return process.env;
|
|
36
|
+
const fallback = await resolveRubyEnv();
|
|
37
|
+
if (fallback && (await canRequirePrism(fallback.env)))
|
|
38
|
+
return fallback.env;
|
|
39
|
+
return null;
|
|
40
|
+
})();
|
|
41
|
+
return cached;
|
|
42
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { resolveSidecarScript } from "./bridge.js";
|
|
6
|
+
import { resolvePrismRuby } from "./prism-ruby.js";
|
|
7
|
+
const exec = promisify(execFile);
|
|
8
|
+
const SCRIPT = resolveSidecarScript(dirname(fileURLToPath(import.meta.url)), "scan.rb");
|
|
9
|
+
/**
|
|
10
|
+
* What a Fastfile says, or null.
|
|
11
|
+
*
|
|
12
|
+
* **Null is an ordinary answer, never a failure.** No Ruby with Prism, no
|
|
13
|
+
* Fastfile, a Fastfile that does not parse — all of them mean the same thing to
|
|
14
|
+
* every caller: this file was not analysed, carry on. Setup must not fail
|
|
15
|
+
* because a scan could not run; it did its job before this feature existed.
|
|
16
|
+
*/
|
|
17
|
+
export async function scanFastfile(cwd, fastlaneDir) {
|
|
18
|
+
const env = await resolvePrismRuby();
|
|
19
|
+
if (env === null)
|
|
20
|
+
return null;
|
|
21
|
+
try {
|
|
22
|
+
const { stdout } = await exec("ruby", [SCRIPT, "--fastlane-dir", fastlaneDir], {
|
|
23
|
+
cwd,
|
|
24
|
+
env,
|
|
25
|
+
timeout: 30_000,
|
|
26
|
+
});
|
|
27
|
+
const res = JSON.parse(stdout);
|
|
28
|
+
if (!res.ok)
|
|
29
|
+
return null;
|
|
30
|
+
return res.literals.map((l) => ({
|
|
31
|
+
action: String(l["action"]),
|
|
32
|
+
arg: String(l["arg"]),
|
|
33
|
+
value: String(l["value"]),
|
|
34
|
+
valueStart: Number(l["value_start"]),
|
|
35
|
+
valueLength: Number(l["value_length"]),
|
|
36
|
+
pairStart: Number(l["pair_start"]),
|
|
37
|
+
pairLength: Number(l["pair_length"]),
|
|
38
|
+
line: Number(l["line"]),
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as Fn,j as Eh}from"./index-
|
|
1
|
+
import{r as Fn,j as Eh}from"./index-B8lAQPEM.js";let hs=[],tl=[];(()=>{let n="lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map(e=>e?parseInt(e,36):1);for(let e=0,t=0;e<n.length;e++)(e%2?tl:hs).push(t=t+n[e])})();function Rh(n){if(n<768)return!1;for(let e=0,t=hs.length;;){let i=e+t>>1;if(n<hs[i])t=i;else if(n>=tl[i])e=i+1;else return!0;if(e==t)return!1}}function Pr(n){return n>=127462&&n<=127487}const Ir=8205;function Ph(n,e,t=!0,i=!0){return(t?il:Ih)(n,e,i)}function il(n,e,t){if(e==n.length)return e;e&&nl(n.charCodeAt(e))&&sl(n.charCodeAt(e-1))&&e--;let i=Hn(n,e);for(e+=Nr(i);e<n.length;){let s=Hn(n,e);if(i==Ir||s==Ir||t&&Rh(s))e+=Nr(s),i=s;else if(Pr(s)){let r=0,o=e-2;for(;o>=0&&Pr(Hn(n,o));)r++,o-=2;if(r%2==0)break;e+=2}else break}return e}function Ih(n,e,t){for(;e>1;){let i=il(n,e-2,t);if(i<e)return i;e--}return 0}function Hn(n,e){let t=n.charCodeAt(e);if(!sl(t)||e+1==n.length)return t;let i=n.charCodeAt(e+1);return nl(i)?(t-55296<<10)+(i-56320)+65536:t}function nl(n){return n>=56320&&n<57344}function sl(n){return n>=55296&&n<56320}function Nr(n){return n<65536?1:2}class W{lineAt(e){if(e<0||e>this.length)throw new RangeError(`Invalid position ${e} in document of length ${this.length}`);return this.lineInner(e,!1,1,0)}line(e){if(e<1||e>this.lines)throw new RangeError(`Invalid line number ${e} in ${this.lines}-line document`);return this.lineInner(e,!0,1,0)}replace(e,t,i){[e,t]=Ht(this,e,t);let s=[];return this.decompose(0,e,s,2),i.length&&i.decompose(0,i.length,s,3),this.decompose(t,this.length,s,1),Ve.from(s,this.length-(t-e)+i.length)}append(e){return this.replace(this.length,this.length,e)}slice(e,t=this.length){[e,t]=Ht(this,e,t);let i=[];return this.decompose(e,t,i,0),Ve.from(i,t-e)}eq(e){if(e==this)return!0;if(e.length!=this.length||e.lines!=this.lines)return!1;let t=this.scanIdentical(e,1),i=this.length-this.scanIdentical(e,-1),s=new ri(this),r=new ri(e);for(let o=t,l=t;;){if(s.next(o),r.next(o),o=0,s.lineBreak!=r.lineBreak||s.done!=r.done||s.value!=r.value)return!1;if(l+=s.value.length,s.done||l>=i)return!0}}iter(e=1){return new ri(this,e)}iterRange(e,t=this.length){return new rl(this,e,t)}iterLines(e,t){let i;if(e==null)i=this.iter();else{t==null&&(t=this.lines+1);let s=this.line(e).from;i=this.iterRange(s,Math.max(s,t==this.lines+1?this.length:t<=1?0:this.line(t-1).to))}return new ol(i)}toString(){return this.sliceString(0)}toJSON(){let e=[];return this.flatten(e),e}constructor(){}static of(e){if(e.length==0)throw new RangeError("A document must have at least one line");return e.length==1&&!e[0]?W.empty:e.length<=32?new J(e):Ve.from(J.split(e,[]))}}class J extends W{constructor(e,t=Nh(e)){super(),this.text=e,this.length=t}get lines(){return this.text.length}get children(){return null}lineInner(e,t,i,s){for(let r=0;;r++){let o=this.text[r],l=s+o.length;if((t?i:l)>=e)return new Wh(s,l,i,o);s=l+1,i++}}decompose(e,t,i,s){let r=e<=0&&t>=this.length?this:new J(Wr(this.text,e,t),Math.min(t,this.length)-Math.max(0,e));if(s&1){let o=i.pop(),l=Yi(r.text,o.text.slice(),0,r.length);if(l.length<=32)i.push(new J(l,o.length+r.length));else{let a=l.length>>1;i.push(new J(l.slice(0,a)),new J(l.slice(a)))}}else i.push(r)}replace(e,t,i){if(!(i instanceof J))return super.replace(e,t,i);[e,t]=Ht(this,e,t);let s=Yi(this.text,Yi(i.text,Wr(this.text,0,e)),t),r=this.length+i.length-(t-e);return s.length<=32?new J(s,r):Ve.from(J.split(s,[]),r)}sliceString(e,t=this.length,i=`
|
|
2
2
|
`){[e,t]=Ht(this,e,t);let s="";for(let r=0,o=0;r<=t&&o<this.text.length;o++){let l=this.text[o],a=r+l.length;r>e&&o&&(s+=i),e<a&&t>r&&(s+=l.slice(Math.max(0,e-r),t-r)),r=a+1}return s}flatten(e){for(let t of this.text)e.push(t)}scanIdentical(){return 0}static split(e,t){let i=[],s=-1;for(let r of e)i.push(r),s+=r.length+1,i.length==32&&(t.push(new J(i,s)),i=[],s=-1);return s>-1&&t.push(new J(i,s)),t}}class Ve extends W{constructor(e,t){super(),this.children=e,this.length=t,this.lines=0;for(let i of e)this.lines+=i.lines}lineInner(e,t,i,s){for(let r=0;;r++){let o=this.children[r],l=s+o.length,a=i+o.lines-1;if((t?a:l)>=e)return o.lineInner(e,t,i,s);s=l+1,i=a+1}}decompose(e,t,i,s){for(let r=0,o=0;o<=t&&r<this.children.length;r++){let l=this.children[r],a=o+l.length;if(e<=a&&t>=o){let h=s&((o<=e?1:0)|(a>=t?2:0));o>=e&&a<=t&&!h?i.push(l):l.decompose(e-o,t-o,i,h)}o=a+1}}replace(e,t,i){if([e,t]=Ht(this,e,t),i.lines<this.lines)for(let s=0,r=0;s<this.children.length;s++){let o=this.children[s],l=r+o.length;if(e>=r&&t<=l){let a=o.replace(e-r,t-r,i),h=this.lines-o.lines+a.lines;if(a.lines<h>>4&&a.lines>h>>6){let c=this.children.slice();return c[s]=a,new Ve(c,this.length-(t-e)+i.length)}return super.replace(r,l,a)}r=l+1}return super.replace(e,t,i)}sliceString(e,t=this.length,i=`
|
|
3
3
|
`){[e,t]=Ht(this,e,t);let s="";for(let r=0,o=0;r<this.children.length&&o<=t;r++){let l=this.children[r],a=o+l.length;o>e&&r&&(s+=i),e<a&&t>o&&(s+=l.sliceString(e-o,t-o,i)),o=a+1}return s}flatten(e){for(let t of this.children)t.flatten(e)}scanIdentical(e,t){if(!(e instanceof Ve))return 0;let i=0,[s,r,o,l]=t>0?[0,0,this.children.length,e.children.length]:[this.children.length-1,e.children.length-1,-1,-1];for(;;s+=t,r+=t){if(s==o||r==l)return i;let a=this.children[s],h=e.children[r];if(a!=h)return i+a.scanIdentical(h,t);i+=a.length+1}}static from(e,t=e.reduce((i,s)=>i+s.length+1,-1)){let i=0;for(let d of e)i+=d.lines;if(i<32){let d=[];for(let p of e)p.flatten(d);return new J(d,t)}let s=Math.max(32,i>>5),r=s<<1,o=s>>1,l=[],a=0,h=-1,c=[];function f(d){let p;if(d.lines>r&&d instanceof Ve)for(let g of d.children)f(g);else d.lines>o&&(a>o||!a)?(u(),l.push(d)):d instanceof J&&a&&(p=c[c.length-1])instanceof J&&d.lines+p.lines<=32?(a+=d.lines,h+=d.length+1,c[c.length-1]=new J(p.text.concat(d.text),p.length+1+d.length)):(a+d.lines>s&&u(),a+=d.lines,h+=d.length+1,c.push(d))}function u(){a!=0&&(l.push(c.length==1?c[0]:Ve.from(c,h)),h=-1,a=c.length=0)}for(let d of e)f(d);return u(),l.length==1?l[0]:new Ve(l,t)}}W.empty=new J([""],0);function Nh(n){let e=-1;for(let t of n)e+=t.length+1;return e}function Yi(n,e,t=0,i=1e9){for(let s=0,r=0,o=!0;r<n.length&&s<=i;r++){let l=n[r],a=s+l.length;a>=t&&(a>i&&(l=l.slice(0,i-s)),s<t&&(l=l.slice(t-s)),o?(e[e.length-1]+=l,o=!1):e.push(l)),s=a+1}return e}function Wr(n,e,t){return Yi(n,[""],e,t)}class ri{constructor(e,t=1){this.dir=t,this.done=!1,this.lineBreak=!1,this.value="",this.nodes=[e],this.offsets=[t>0?1:(e instanceof J?e.text.length:e.children.length)<<1]}nextInner(e,t){for(this.done=this.lineBreak=!1;;){let i=this.nodes.length-1,s=this.nodes[i],r=this.offsets[i],o=r>>1,l=s instanceof J?s.text.length:s.children.length;if(o==(t>0?l:0)){if(i==0)return this.done=!0,this.value="",this;t>0&&this.offsets[i-1]++,this.nodes.pop(),this.offsets.pop()}else if((r&1)==(t>0?0:1)){if(this.offsets[i]+=t,e==0)return this.lineBreak=!0,this.value=`
|
|
4
4
|
`,this;e--}else if(s instanceof J){let a=s.text[o+(t<0?-1:0)];if(this.offsets[i]+=t,a.length>Math.max(0,e))return this.value=e==0?a:t>0?a.slice(e):a.slice(0,a.length-e),this;e-=a.length}else{let a=s.children[o+(t<0?-1:0)];e>a.length?(e-=a.length,this.offsets[i]+=t):(t<0&&this.offsets[i]--,this.nodes.push(a),this.offsets.push(t>0?1:(a instanceof J?a.text.length:a.children.length)<<1))}}}next(e=0){return e<0&&(this.nextInner(-e,-this.dir),e=this.value.length),this.nextInner(e,this.dir)}}class rl{constructor(e,t,i){this.value="",this.done=!1,this.cursor=new ri(e,t>i?-1:1),this.pos=t>i?e.length:0,this.from=Math.min(t,i),this.to=Math.max(t,i)}nextInner(e,t){if(t<0?this.pos<=this.from:this.pos>=this.to)return this.value="",this.done=!0,this;e+=Math.max(0,t<0?this.pos-this.to:this.from-this.pos);let i=t<0?this.pos-this.from:this.to-this.pos;e>i&&(e=i),i-=e;let{value:s}=this.cursor.next(e);return this.pos+=(s.length+e)*t,this.value=s.length<=i?s:t<0?s.slice(s.length-i):s.slice(0,i),this.done=!this.value,this}next(e=0){return e<0?e=Math.max(e,this.from-this.pos):e>0&&(e=Math.min(e,this.to-this.pos)),this.nextInner(e,this.cursor.dir)}get lineBreak(){return this.cursor.lineBreak&&this.value!=""}}class ol{constructor(e){this.inner=e,this.afterBreak=!0,this.value="",this.done=!1}next(e=0){let{done:t,lineBreak:i,value:s}=this.inner.next(e);return t&&this.afterBreak?(this.value="",this.afterBreak=!1):t?(this.done=!0,this.value=""):i?this.afterBreak?this.value="":(this.afterBreak=!0,this.next()):(this.value=s,this.afterBreak=!1),this}get lineBreak(){return!1}}typeof Symbol<"u"&&(W.prototype[Symbol.iterator]=function(){return this.iter()},ri.prototype[Symbol.iterator]=rl.prototype[Symbol.iterator]=ol.prototype[Symbol.iterator]=function(){return this});class Wh{constructor(e,t,i,s){this.from=e,this.to=t,this.number=i,this.text=s}get length(){return this.to-this.from}}function Ht(n,e,t){return e=Math.max(0,Math.min(n.length,e)),[e,Math.max(e,Math.min(n.length,t))]}function ee(n,e,t=!0,i=!0){return Ph(n,e,t,i)}function Fh(n){return n>=56320&&n<57344}function Hh(n){return n>=55296&&n<56320}function er(n,e){let t=n.charCodeAt(e);if(!Hh(t)||e+1==n.length)return t;let i=n.charCodeAt(e+1);return Fh(i)?(t-55296<<10)+(i-56320)+65536:t}function Vh(n){return n<=65535?String.fromCharCode(n):(n-=65536,String.fromCharCode((n>>10)+55296,(n&1023)+56320))}function ll(n){return n<65536?1:2}const cs=/\r\n?|\n/;var xe=function(n){return n[n.Simple=0]="Simple",n[n.TrackDel=1]="TrackDel",n[n.TrackBefore=2]="TrackBefore",n[n.TrackAfter=3]="TrackAfter",n}(xe||(xe={}));class Ue{constructor(e){this.sections=e}get length(){let e=0;for(let t=0;t<this.sections.length;t+=2)e+=this.sections[t];return e}get newLength(){let e=0;for(let t=0;t<this.sections.length;t+=2){let i=this.sections[t+1];e+=i<0?this.sections[t]:i}return e}get empty(){return this.sections.length==0||this.sections.length==2&&this.sections[1]<0}iterGaps(e){for(let t=0,i=0,s=0;t<this.sections.length;){let r=this.sections[t++],o=this.sections[t++];o<0?(e(i,s,r),s+=r):s+=o,i+=r}}iterChangedRanges(e,t=!1){fs(this,e,t)}get invertedDesc(){let e=[];for(let t=0;t<this.sections.length;){let i=this.sections[t++],s=this.sections[t++];s<0?e.push(i,s):e.push(s,i)}return new Ue(e)}composeDesc(e){return this.empty?e:e.empty?this:al(this,e)}mapDesc(e,t=!1){return e.empty?this:us(this,e,t)}mapPos(e,t=-1,i=xe.Simple){let s=0,r=0;for(let o=0;o<this.sections.length;){let l=this.sections[o++],a=this.sections[o++],h=s+l;if(a<0){if(h>e)return r+(e-s);r+=l}else{if(i!=xe.Simple&&h>=e&&(i==xe.TrackDel&&s<e&&h>e||i==xe.TrackBefore&&s<e||i==xe.TrackAfter&&h>e))return null;if(h>e||h==e&&t<0&&!l)return e==s||t<0?r:r+a;r+=a}s=h}if(e>s)throw new RangeError(`Position ${e} is out of range for changeset of length ${s}`);return r}touchesRange(e,t=e){for(let i=0,s=0;i<this.sections.length&&s<=t;){let r=this.sections[i++],o=this.sections[i++],l=s+r;if(o>=0&&s<=t&&l>=e)return s<e&&l>t?"cover":!0;s=l}return!1}toString(){let e="";for(let t=0;t<this.sections.length;){let i=this.sections[t++],s=this.sections[t++];e+=(e?" ":"")+i+(s>=0?":"+s:"")}return e}toJSON(){return this.sections}static fromJSON(e){if(!Array.isArray(e)||e.length%2||e.some(t=>typeof t!="number"))throw new RangeError("Invalid JSON representation of ChangeDesc");return new Ue(e)}static create(e){return new Ue(e)}}class X extends Ue{constructor(e,t){super(e),this.inserted=t}apply(e){if(this.length!=e.length)throw new RangeError("Applying change set to a document with the wrong length");return fs(this,(t,i,s,r,o)=>e=e.replace(s,s+(i-t),o),!1),e}mapDesc(e,t=!1){return us(this,e,t,!0)}invert(e){let t=this.sections.slice(),i=[];for(let s=0,r=0;s<t.length;s+=2){let o=t[s],l=t[s+1];if(l>=0){t[s]=l,t[s+1]=o;let a=s>>1;for(;i.length<a;)i.push(W.empty);i.push(o?e.slice(r,r+o):W.empty)}r+=o}return new X(t,i)}compose(e){return this.empty?e:e.empty?this:al(this,e,!0)}map(e,t=!1){return e.empty?this:us(this,e,t,!0)}iterChanges(e,t=!1){fs(this,e,t)}get desc(){return Ue.create(this.sections)}filter(e){let t=[],i=[],s=[],r=new fi(this);e:for(let o=0,l=0;;){let a=o==e.length?1e9:e[o++];for(;l<a||l==a&&r.len==0;){if(r.done)break e;let c=Math.min(r.len,a-l);oe(s,c,-1);let f=r.ins==-1?-1:r.off==0?r.ins:0;oe(t,c,f),f>0&&nt(i,t,r.text),r.forward(c),l+=c}let h=e[o++];for(;l<h;){if(r.done)break e;let c=Math.min(r.len,h-l);oe(t,c,-1),oe(s,c,r.ins==-1?-1:r.off==0?r.ins:0),r.forward(c),l+=c}}return{changes:new X(t,i),filtered:Ue.create(s)}}toJSON(){let e=[];for(let t=0;t<this.sections.length;t+=2){let i=this.sections[t],s=this.sections[t+1];s<0?e.push(i):s==0?e.push([i]):e.push([i].concat(this.inserted[t>>1].toJSON()))}return e}static of(e,t,i){let s=[],r=[],o=0,l=null;function a(c=!1){if(!c&&!s.length)return;o<t&&oe(s,t-o,-1);let f=new X(s,r);l=l?l.compose(f.map(l)):f,s=[],r=[],o=0}function h(c){if(Array.isArray(c))for(let f of c)h(f);else if(c instanceof X){if(c.length!=t)throw new RangeError(`Mismatched change set length (got ${c.length}, expected ${t})`);a(),l=l?l.compose(c.map(l)):c}else{let{from:f,to:u=f,insert:d}=c;if(f>u||f<0||u>t)throw new RangeError(`Invalid change range ${f} to ${u} (in doc of length ${t})`);let p=d?typeof d=="string"?W.of(d.split(i||cs)):d:W.empty,g=p.length;if(f==u&&g==0)return;f<o&&a(),f>o&&oe(s,f-o,-1),oe(s,u-f,g),nt(r,s,p),o=u}}return h(e),a(!l),l}static empty(e){return new X(e?[e,-1]:[],[])}static fromJSON(e){if(!Array.isArray(e))throw new RangeError("Invalid JSON representation of ChangeSet");let t=[],i=[];for(let s=0;s<e.length;s++){let r=e[s];if(typeof r=="number")t.push(r,-1);else{if(!Array.isArray(r)||typeof r[0]!="number"||r.some((o,l)=>l&&typeof o!="string"))throw new RangeError("Invalid JSON representation of ChangeSet");if(r.length==1)t.push(r[0],0);else{for(;i.length<s;)i.push(W.empty);i[s]=W.of(r.slice(1)),t.push(r[0],i[s].length)}}}return new X(t,i)}static createSet(e,t){return new X(e,t)}}function oe(n,e,t,i=!1){if(e==0&&t<=0)return;let s=n.length-2;s>=0&&t<=0&&t==n[s+1]?n[s]+=e:s>=0&&e==0&&n[s]==0?n[s+1]+=t:i?(n[s]+=e,n[s+1]+=t):n.push(e,t)}function nt(n,e,t){if(t.length==0)return;let i=e.length-2>>1;if(i<n.length)n[n.length-1]=n[n.length-1].append(t);else{for(;n.length<i;)n.push(W.empty);n.push(t)}}function fs(n,e,t){let i=n.inserted;for(let s=0,r=0,o=0;o<n.sections.length;){let l=n.sections[o++],a=n.sections[o++];if(a<0)s+=l,r+=l;else{let h=s,c=r,f=W.empty;for(;h+=l,c+=a,a&&i&&(f=f.append(i[o-2>>1])),!(t||o==n.sections.length||n.sections[o+1]<0);)l=n.sections[o++],a=n.sections[o++];e(s,h,r,c,f),s=h,r=c}}}function us(n,e,t,i=!1){let s=[],r=i?[]:null,o=new fi(n),l=new fi(e);for(let a=-1;;){if(o.done&&l.len||l.done&&o.len)throw new Error("Mismatched change set lengths");if(o.ins==-1&&l.ins==-1){let h=Math.min(o.len,l.len);oe(s,h,-1),o.forward(h),l.forward(h)}else if(l.ins>=0&&(o.ins<0||a==o.i||o.off==0&&(l.len<o.len||l.len==o.len&&!t))){let h=l.len;for(oe(s,l.ins,-1);h;){let c=Math.min(o.len,h);o.ins>=0&&a<o.i&&o.len<=c&&(oe(s,0,o.ins),r&&nt(r,s,o.text),a=o.i),o.forward(c),h-=c}l.next()}else if(o.ins>=0){let h=0,c=o.len;for(;c;)if(l.ins==-1){let f=Math.min(c,l.len);h+=f,c-=f,l.forward(f)}else if(l.ins==0&&l.len<c)c-=l.len,l.next();else break;oe(s,h,a<o.i?o.ins:0),r&&a<o.i&&nt(r,s,o.text),a=o.i,o.forward(o.len-c)}else{if(o.done&&l.done)return r?X.createSet(s,r):Ue.create(s);throw new Error("Mismatched change set lengths")}}}function al(n,e,t=!1){let i=[],s=t?[]:null,r=new fi(n),o=new fi(e);for(let l=!1;;){if(r.done&&o.done)return s?X.createSet(i,s):Ue.create(i);if(r.ins==0)oe(i,r.len,0,l),r.next();else if(o.len==0&&!o.done)oe(i,0,o.ins,l),s&&nt(s,i,o.text),o.next();else{if(r.done||o.done)throw new Error("Mismatched change set lengths");{let a=Math.min(r.len2,o.len),h=i.length;if(r.ins==-1){let c=o.ins==-1?-1:o.off?0:o.ins;oe(i,a,c,l),s&&c&&nt(s,i,o.text)}else o.ins==-1?(oe(i,r.off?0:r.len,a,l),s&&nt(s,i,r.textBit(a))):(oe(i,r.off?0:r.len,o.off?0:o.ins,l),s&&!o.off&&nt(s,i,o.text));l=(r.ins>a||o.ins>=0&&o.len>a)&&(l||i.length>h),r.forward2(a),o.forward(a)}}}}class fi{constructor(e){this.set=e,this.i=0,this.next()}next(){let{sections:e}=this.set;this.i<e.length?(this.len=e[this.i++],this.ins=e[this.i++]):(this.len=0,this.ins=-2),this.off=0}get done(){return this.ins==-2}get len2(){return this.ins<0?this.len:this.ins}get text(){let{inserted:e}=this.set,t=this.i-2>>1;return t>=e.length?W.empty:e[t]}textBit(e){let{inserted:t}=this.set,i=this.i-2>>1;return i>=t.length&&!e?W.empty:t[i].slice(this.off,e==null?void 0:this.off+e)}forward(e){e==this.len?this.next():(this.len-=e,this.off+=e)}forward2(e){this.ins==-1?this.forward(e):e==this.ins?this.next():(this.ins-=e,this.off+=e)}}class tt{constructor(e,t,i,s){this.from=e,this.to=t,this.flags=i,this.goalColumn=s}get anchor(){return this.flags&32?this.to:this.from}get head(){return this.flags&32?this.from:this.to}get empty(){return this.from==this.to}get assoc(){return this.flags&8?-1:this.flags&16?1:0}get undirectional(){return(this.flags&64)>0}get bidiLevel(){let e=this.flags&7;return e==7?null:e}map(e,t=-1){let i,s;return this.empty?i=s=e.mapPos(this.from,t):(i=e.mapPos(this.from,1),s=e.mapPos(this.to,-1)),i==this.from&&s==this.to?this:new tt(i,s,this.flags,this.goalColumn)}extend(e,t=e,i=0){if(e<=this.anchor&&t>=this.anchor)return b.range(e,t,void 0,void 0,i);let s=Math.abs(e-this.anchor)>Math.abs(t-this.anchor)?e:t;return b.range(this.anchor,s,void 0,void 0,i)}eq(e,t=!1){return this.anchor==e.anchor&&this.head==e.head&&this.goalColumn==e.goalColumn&&(!t||!this.empty||this.assoc==e.assoc)}toJSON(){return{anchor:this.anchor,head:this.head}}static fromJSON(e){if(!e||typeof e.anchor!="number"||typeof e.head!="number")throw new RangeError("Invalid JSON representation for SelectionRange");return b.range(e.anchor,e.head)}static create(e,t,i,s){return new tt(e,t,i,s)}}class b{constructor(e,t){this.ranges=e,this.mainIndex=t}map(e,t=-1){return e.empty?this:b.create(this.ranges.map(i=>i.map(e,t)),this.mainIndex)}eq(e,t=!1){if(this.ranges.length!=e.ranges.length||this.mainIndex!=e.mainIndex)return!1;for(let i=0;i<this.ranges.length;i++)if(!this.ranges[i].eq(e.ranges[i],t))return!1;return!0}get main(){return this.ranges[this.mainIndex]}asSingle(){return this.ranges.length==1?this:new b([this.main],0)}addRange(e,t=!0){return b.create([e].concat(this.ranges),t?0:this.mainIndex+1)}replaceRange(e,t=this.mainIndex){let i=this.ranges.slice();return i[t]=e,b.create(i,this.mainIndex)}toJSON(){return{ranges:this.ranges.map(e=>e.toJSON()),main:this.mainIndex}}static fromJSON(e){if(!e||!Array.isArray(e.ranges)||typeof e.main!="number"||e.main>=e.ranges.length)throw new RangeError("Invalid JSON representation for EditorSelection");return new b(e.ranges.map(t=>tt.fromJSON(t)),e.main)}static single(e,t=e){return new b([b.range(e,t)],0)}static create(e,t=0){if(e.length==0)throw new RangeError("A selection needs at least one range");for(let i=0,s=0;s<e.length;s++){let r=e[s];if(r.empty?r.from<=i:r.from<i)return b.normalized(e.slice(),t);i=r.to}return new b(e,t)}static cursor(e,t=0,i,s){return tt.create(e,e,(t==0?0:t<0?8:16)|(i==null?7:Math.min(6,i)),s)}static range(e,t,i,s,r){let o=s==null?7:Math.min(6,s);return!r&&e!=t&&(r=t<e?1:-1),r&&(o|=r<0?8:16),t<e?tt.create(t,e,o|32,i):tt.create(e,t,o,i)}static undirectionalRange(e,t){return tt.create(e,t,64,void 0)}static normalized(e,t=0){let i=e[t];e.sort((s,r)=>s.from-r.from),t=e.indexOf(i);for(let s=1;s<e.length;s++){let r=e[s],o=e[s-1];if(r.empty?r.from<=o.to:r.from<o.to){let l=o.from,a=Math.max(r.to,o.to);s<=t&&t--,e.splice(--s,2,r.anchor>r.head?b.range(a,l):b.range(l,a))}}return new b(e,t)}}function hl(n,e){for(let t of n.ranges)if(t.to>e)throw new RangeError("Selection points outside of document")}let tr=0;class A{constructor(e,t,i,s,r){this.combine=e,this.compareInput=t,this.compare=i,this.isStatic=s,this.id=tr++,this.default=e([]),this.extensions=typeof r=="function"?r(this):r}get reader(){return this}static define(e={}){return new A(e.combine||(t=>t),e.compareInput||((t,i)=>t===i),e.compare||(e.combine?(t,i)=>t===i:ir),!!e.static,e.enables)}of(e){return new Xi([],this,0,e)}compute(e,t){if(this.isStatic)throw new Error("Can't compute a static facet");return new Xi(e,this,1,t)}computeN(e,t){if(this.isStatic)throw new Error("Can't compute a static facet");return new Xi(e,this,2,t)}from(e,t){return t||(t=i=>i),this.compute([e],i=>t(i.field(e)))}}function ir(n,e){return n==e||n.length==e.length&&n.every((t,i)=>t===e[i])}class Xi{constructor(e,t,i,s){this.dependencies=e,this.facet=t,this.type=i,this.value=s,this.id=tr++}dynamicSlot(e){var t;let i=this.value,s=this.facet.compareInput,r=this.id,o=e[r]>>1,l=this.type==2,a=!1,h=!1,c=[];for(let f of this.dependencies)f=="doc"?a=!0:f=="selection"?h=!0:((t=e[f.id])!==null&&t!==void 0?t:1)&1||c.push(e[f.id]);return{create(f){return f.values[o]=i(f),1},update(f,u){if(a&&u.docChanged||h&&(u.docChanged||u.selection)||ds(f,c)){let d=i(f);if(l?!Fr(d,f.values[o],s):!s(d,f.values[o]))return f.values[o]=d,1}return 0},reconfigure:(f,u)=>{let d,p=u.config.address[r];if(p!=null){let g=ln(u,p);if(this.dependencies.every(m=>m instanceof A?u.facet(m)===f.facet(m):m instanceof Ge?u.field(m,!1)==f.field(m,!1):!0)||(l?Fr(d=i(f),g,s):s(d=i(f),g)))return f.values[o]=g,0}else d=i(f);return f.values[o]=d,1}}}get extension(){return this}}function Fr(n,e,t){if(n.length!=e.length)return!1;for(let i=0;i<n.length;i++)if(!t(n[i],e[i]))return!1;return!0}function ds(n,e){let t=!1;for(let i of e)oi(n,i)&1&&(t=!0);return t}function zh(n,e,t){let i=t.map(a=>n[a.id]),s=t.map(a=>a.type),r=i.filter(a=>!(a&1)),o=n[e.id]>>1;function l(a){let h=[];for(let c=0;c<i.length;c++){let f=ln(a,i[c]);if(s[c]==2)for(let u of f)h.push(u);else h.push(f)}return e.combine(h)}return{create(a){for(let h of i)oi(a,h);return a.values[o]=l(a),1},update(a,h){if(!ds(a,r))return 0;let c=l(a);return e.compare(c,a.values[o])?0:(a.values[o]=c,1)},reconfigure(a,h){let c=ds(a,i),f=h.config.facets[e.id],u=h.facet(e);if(f&&!c&&ir(t,f))return a.values[o]=u,0;let d=l(a);return e.compare(d,u)?(a.values[o]=u,0):(a.values[o]=d,1)}}}const Li=A.define({static:!0});class Ge{constructor(e,t,i,s,r){this.id=e,this.createF=t,this.updateF=i,this.compareF=s,this.spec=r,this.provides=void 0}static define(e){let t=new Ge(tr++,e.create,e.update,e.compare||((i,s)=>i===s),e);return e.provide&&(t.provides=e.provide(t)),t}create(e){let t=e.facet(Li).find(i=>i.field==this);return((t==null?void 0:t.create)||this.createF)(e)}slot(e){let t=e[this.id]>>1;return{create:i=>(i.values[t]=this.create(i),1),update:(i,s)=>{let r=i.values[t],o=this.updateF(r,s);return this.compareF(r,o)?0:(i.values[t]=o,1)},reconfigure:(i,s)=>{let r=i.facet(Li),o=s.facet(Li),l;return(l=r.find(a=>a.field==this))&&l!=o.find(a=>a.field==this)?(i.values[t]=l.create(i),1):s.config.address[this.id]!=null?(i.values[t]=s.field(this),0):(i.values[t]=this.create(i),1)}}}init(e){return[this,Li.of({field:this,create:e})]}get extension(){return this}}const mt={lowest:4,low:3,default:2,high:1,highest:0};function Xt(n){return e=>new cl(e,n)}const vi={highest:Xt(mt.highest),high:Xt(mt.high),default:Xt(mt.default),low:Xt(mt.low),lowest:Xt(mt.lowest)};class cl{constructor(e,t){this.inner=e,this.prec=t}get extension(){return this}}class Mn{of(e){return new ps(this,e)}reconfigure(e){return Mn.reconfigure.of({compartment:this,extension:e})}get(e){return e.config.compartments.get(this)}}class ps{constructor(e,t){this.compartment=e,this.inner=t}get extension(){return this}}class on{constructor(e,t,i,s,r,o){for(this.base=e,this.compartments=t,this.dynamicSlots=i,this.address=s,this.staticValues=r,this.facets=o,this.statusTemplate=[];this.statusTemplate.length<i.length;)this.statusTemplate.push(0)}staticFacet(e){let t=this.address[e.id];return t==null?e.default:this.staticValues[t>>1]}static resolve(e,t,i){let s=[],r=Object.create(null),o=new Map;for(let u of qh(e,t,o))u instanceof Ge?s.push(u):(r[u.facet.id]||(r[u.facet.id]=[])).push(u);let l=Object.create(null),a=[],h=[];for(let u of s)l[u.id]=h.length<<1,h.push(d=>u.slot(d));let c=i==null?void 0:i.config.facets;for(let u in r){let d=r[u],p=d[0].facet,g=c&&c[u]||[];if(d.every(m=>m.type==0))if(l[p.id]=a.length<<1|1,ir(g,d))a.push(i.facet(p));else{let m=p.combine(d.map(y=>y.value));a.push(i&&p.compare(m,i.facet(p))?i.facet(p):m)}else{for(let m of d)m.type==0?(l[m.id]=a.length<<1|1,a.push(m.value)):(l[m.id]=h.length<<1,h.push(y=>m.dynamicSlot(y)));l[p.id]=h.length<<1,h.push(m=>zh(m,p,d))}}let f=h.map(u=>u(l));return new on(e,o,f,l,a,r)}}function qh(n,e,t){let i=[[],[],[],[],[]],s=new Map;function r(o,l){let a=s.get(o);if(a!=null){if(a<=l)return;let h=i[a].indexOf(o);h>-1&&i[a].splice(h,1),o instanceof ps&&t.delete(o.compartment)}if(s.set(o,l),Array.isArray(o))for(let h of o)r(h,l);else if(o instanceof ps){if(t.has(o.compartment))throw new RangeError("Duplicate use of compartment in extensions");let h=e.get(o.compartment)||o.inner;t.set(o.compartment,h),r(h,l)}else if(o instanceof cl)r(o.inner,o.prec);else if(o instanceof Ge)i[l].push(o),o.provides&&r(o.provides,l);else if(o instanceof Xi)i[l].push(o),o.facet.extensions&&r(o.facet.extensions,mt.default);else{let h=o.extension;if(!h)throw new Error(`Unrecognized extension value in extension set (${o}).`);if(h==o)throw new Error(`Unrecognized extension value in extension set (${o}). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.`);r(h,l)}}return r(n,mt.default),i.reduce((o,l)=>o.concat(l))}function oi(n,e){if(e&1)return 2;let t=e>>1,i=n.status[t];if(i==4)throw new Error("Cyclic dependency between fields and/or facets");if(i&2)return i;n.status[t]=4;let s=n.computeSlot(n,n.config.dynamicSlots[t]);return n.status[t]=2|s}function ln(n,e){return e&1?n.config.staticValues[e>>1]:n.values[e>>1]}const fl=A.define(),gs=A.define({combine:n=>n.some(e=>e),static:!0}),ul=A.define({combine:n=>n.length?n[0]:void 0,static:!0}),dl=A.define(),pl=A.define(),gl=A.define(),ml=A.define({combine:n=>n.length?n[0]:!1});class ft{constructor(e,t){this.type=e,this.value=t}static define(){return new Kh}}class Kh{of(e){return new ft(this,e)}}class $h{constructor(e){this.map=e}of(e){return new K(this,e)}}class K{constructor(e,t){this.type=e,this.value=t}map(e){let t=this.type.map(this.value,e);return t===void 0?void 0:t==this.value?this:new K(this.type,t)}is(e){return this.type==e}static define(e={}){return new $h(e.map||(t=>t))}static mapEffects(e,t){if(!e.length)return e;let i=[];for(let s of e){let r=s.map(t);r&&i.push(r)}return i}}K.reconfigure=K.define();K.appendConfig=K.define();class Q{constructor(e,t,i,s,r,o){this.startState=e,this.changes=t,this.selection=i,this.effects=s,this.annotations=r,this.scrollIntoView=o,this._doc=null,this._state=null,i&&hl(i,t.newLength),r.some(l=>l.type==Q.time)||(this.annotations=r.concat(Q.time.of(Date.now())))}static create(e,t,i,s,r,o){return new Q(e,t,i,s,r,o)}get newDoc(){return this._doc||(this._doc=this.changes.apply(this.startState.doc))}get newSelection(){return this.selection||this.startState.selection.map(this.changes)}get state(){return this._state||this.startState.applyTransaction(this),this._state}annotation(e){for(let t of this.annotations)if(t.type==e)return t.value}get docChanged(){return!this.changes.empty}get reconfigured(){return this.startState.config!=this.state.config}isUserEvent(e){let t=this.annotation(Q.userEvent);return!!(t&&(t==e||t.length>e.length&&t.slice(0,e.length)==e&&t[e.length]=="."))}}Q.time=ft.define();Q.userEvent=ft.define();Q.addToHistory=ft.define();Q.remote=ft.define();function jh(n,e){let t=[];for(let i=0,s=0;;){let r,o;if(i<n.length&&(s==e.length||e[s]>=n[i]))r=n[i++],o=n[i++];else if(s<e.length)r=e[s++],o=e[s++];else return t;!t.length||t[t.length-1]<r?t.push(r,o):t[t.length-1]<o&&(t[t.length-1]=o)}}function yl(n,e,t){var i;let s,r,o;return t?(s=e.changes,r=X.empty(e.changes.length),o=n.changes.compose(e.changes)):(s=e.changes.map(n.changes),r=n.changes.mapDesc(e.changes,!0),o=n.changes.compose(s)),{changes:o,selection:e.selection?e.selection.map(r):(i=n.selection)===null||i===void 0?void 0:i.map(s),effects:K.mapEffects(n.effects,s).concat(K.mapEffects(e.effects,r)),annotations:n.annotations.length?n.annotations.concat(e.annotations):e.annotations,scrollIntoView:n.scrollIntoView||e.scrollIntoView}}function ms(n,e,t){let i=e.selection,s=Pt(e.annotations);return e.userEvent&&(s=s.concat(Q.userEvent.of(e.userEvent))),{changes:e.changes instanceof X?e.changes:X.of(e.changes||[],t,n.facet(ul)),selection:i&&(i instanceof b?i:b.single(i.anchor,i.head)),effects:Pt(e.effects),annotations:s,scrollIntoView:!!e.scrollIntoView}}function bl(n,e,t){let i=ms(n,e.length?e[0]:{},n.doc.length);e.length&&e[0].filter===!1&&(t=!1);for(let r=1;r<e.length;r++){e[r].filter===!1&&(t=!1);let o=!!e[r].sequential;i=yl(i,ms(n,e[r],o?i.changes.newLength:n.doc.length),o)}let s=Q.create(n,i.changes,i.selection,i.effects,i.annotations,i.scrollIntoView);return _h(t?Uh(s):s)}function Uh(n){let e=n.startState,t=!0;for(let s of e.facet(dl)){let r=s(n);if(r===!1){t=!1;break}Array.isArray(r)&&(t=t===!0?r:jh(t,r))}if(t!==!0){let s,r;if(t===!1)r=n.changes.invertedDesc,s=X.empty(e.doc.length);else{let o=n.changes.filter(t);s=o.changes,r=o.filtered.mapDesc(o.changes).invertedDesc}n=Q.create(e,s,n.selection&&n.selection.map(r),K.mapEffects(n.effects,r),n.annotations,n.scrollIntoView)}let i=e.facet(pl);for(let s=i.length-1;s>=0;s--){let r=i[s](n);r instanceof Q?n=r:Array.isArray(r)&&r.length==1&&r[0]instanceof Q?n=r[0]:n=bl(e,Pt(r),!1)}return n}function _h(n){let e=n.startState,t=e.facet(gl),i=n;for(let s=t.length-1;s>=0;s--){let r=t[s](n);r&&Object.keys(r).length&&(i=yl(i,ms(e,r,n.changes.newLength),!0))}return i==n?n:Q.create(e,n.changes,n.selection,i.effects,i.annotations,i.scrollIntoView)}const Gh=[];function Pt(n){return n==null?Gh:Array.isArray(n)?n:[n]}var se=function(n){return n[n.Word=0]="Word",n[n.Space=1]="Space",n[n.Other=2]="Other",n}(se||(se={}));const Jh=/[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;let ys;try{ys=new RegExp("[\\p{Alphabetic}\\p{Number}_]","u")}catch{}function Yh(n){if(ys)return ys.test(n);for(let e=0;e<n.length;e++){let t=n[e];if(/\w/.test(t)||t>""&&(t.toUpperCase()!=t.toLowerCase()||Jh.test(t)))return!0}return!1}function Xh(n){return e=>{if(!/\S/.test(e))return se.Space;if(Yh(e))return se.Word;for(let t=0;t<n.length;t++)if(e.indexOf(n[t])>-1)return se.Word;return se.Other}}class N{constructor(e,t,i,s,r,o){this.config=e,this.doc=t,this.selection=i,this.values=s,this.status=e.statusTemplate.slice(),this.computeSlot=r,o&&(o._state=this);for(let l=0;l<this.config.dynamicSlots.length;l++)oi(this,l<<1);this.computeSlot=null}field(e,t=!0){let i=this.config.address[e.id];if(i==null){if(t)throw new RangeError("Field is not present in this state");return}return oi(this,i),ln(this,i)}update(...e){return bl(this,e,!0)}applyTransaction(e){let t=this.config,{base:i,compartments:s}=t;for(let l of e.effects)l.is(Mn.reconfigure)?(t&&(s=new Map,t.compartments.forEach((a,h)=>s.set(h,a)),t=null),s.set(l.value.compartment,l.value.extension)):l.is(K.reconfigure)?(t=null,i=l.value):l.is(K.appendConfig)&&(t=null,i=Pt(i).concat(l.value));let r;t?r=e.startState.values.slice():(t=on.resolve(i,s,this),r=new N(t,this.doc,this.selection,t.dynamicSlots.map(()=>null),(a,h)=>h.reconfigure(a,this),null).values);let o=e.startState.facet(gs)?e.newSelection:e.newSelection.asSingle();new N(t,e.newDoc,o,r,(l,a)=>a.update(l,e),e)}replaceSelection(e){return typeof e=="string"&&(e=this.toText(e)),this.changeByRange(t=>({changes:{from:t.from,to:t.to,insert:e},range:b.cursor(t.from+e.length)}))}changeByRange(e){let t=this.selection,i=e(t.ranges[0]),s=this.changes(i.changes),r=[i.range],o=Pt(i.effects);for(let l=1;l<t.ranges.length;l++){let a=e(t.ranges[l]),h=this.changes(a.changes),c=h.map(s);for(let u=0;u<l;u++)r[u]=r[u].map(c);let f=s.mapDesc(h,!0);r.push(a.range.map(f)),s=s.compose(c),o=K.mapEffects(o,c).concat(K.mapEffects(Pt(a.effects),f))}return{changes:s,selection:b.create(r,t.mainIndex),effects:o}}changes(e=[]){return e instanceof X?e:X.of(e,this.doc.length,this.facet(N.lineSeparator))}toText(e){return W.of(e.split(this.facet(N.lineSeparator)||cs))}sliceDoc(e=0,t=this.doc.length){return this.doc.sliceString(e,t,this.lineBreak)}facet(e){let t=this.config.address[e.id];return t==null?e.default:(oi(this,t),ln(this,t))}toJSON(e){let t={doc:this.sliceDoc(),selection:this.selection.toJSON()};if(e)for(let i in e){let s=e[i];s instanceof Ge&&this.config.address[s.id]!=null&&(t[i]=s.spec.toJSON(this.field(e[i]),this))}return t}static fromJSON(e,t={},i){if(!e||typeof e.doc!="string")throw new RangeError("Invalid JSON representation for EditorState");let s=[];if(i){for(let r in i)if(Object.prototype.hasOwnProperty.call(e,r)){let o=i[r],l=e[r];s.push(o.init(a=>o.spec.fromJSON(l,a)))}}return N.create({doc:e.doc,selection:b.fromJSON(e.selection),extensions:t.extensions?s.concat([t.extensions]):s})}static create(e={}){let t=on.resolve(e.extensions||[],new Map),i=e.doc instanceof W?e.doc:W.of((e.doc||"").split(t.staticFacet(N.lineSeparator)||cs)),s=e.selection?e.selection instanceof b?e.selection:b.single(e.selection.anchor,e.selection.head):b.single(0);return hl(s,i.length),t.staticFacet(gs)||(s=s.asSingle()),new N(t,i,s,t.dynamicSlots.map(()=>null),(r,o)=>o.create(r),null)}get tabSize(){return this.facet(N.tabSize)}get lineBreak(){return this.facet(N.lineSeparator)||`
|