@staticbolt/core 1.0.0-beta.3 → 1.0.0-beta.31

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 CHANGED
@@ -21,7 +21,7 @@
21
21
  - [HTML Markdown Plugin](./src/plugins/html-markdown/README.md)
22
22
  - [HTML Inline Script Plugin](./src/plugins/html-inline-script/README.md)
23
23
  - [HTML Inline Style Plugin](./src/plugins/html-inline-style/README.md)
24
- - [HTML Inline SVG Plugin](./src/plugins/html-import/README.md)
24
+ - [HTML Inline SVG Plugin](./src/plugins/html-inline-svg/README.md)
25
25
  - [HTML Inline Text Plugin](./src/plugins/html-inline-text/README.md)
26
26
  - [HTML Bundle Script Plugin](./src/plugins/html-bundle-script/README.md)
27
27
  - [HTML Bundle Style Plugin](./src/plugins/html-bundle-style/README.md)
@@ -29,6 +29,7 @@
29
29
  - [HTML Build Time Script Plugin](./src/plugins/html-build-time-script/README.md)
30
30
  - [HTML Preload Plugin](./src/plugins/html-preload/README.md)
31
31
  - [HTML Merge Styles Plugin](./src/plugins/html-merge-styles/README.md)
32
+ - [HTML Env Only Plugin](./src/plugins/html-env-only/README.md)
32
33
 
33
34
  ### Scripts and Styles
34
35
 
@@ -1 +1 @@
1
- export { };
1
+ export {}
package/lib/cli/index.mjs CHANGED
@@ -1,21 +1,11 @@
1
- #!/usr/bin/env -S node --experimental-vm-modules --no-warnings
2
- import { f as join, r as CONFIG_FILE_NAME, t as Log, u as isAbsolute, y as resolve } from "../logger-BuxMGhij.mjs";
1
+ #!/usr/bin/env node
2
+ import { c as isAbsolute, d as join, r as Log, t as CONFIG_FILE_NAME, v as resolve } from "../common-D1QTZ8ra.mjs";
3
+ import { t as loadConfigFile } from "../load-config-CsbiJ01A.mjs";
4
+ import { createRequire } from "node:module";
5
+ import { existsSync } from "node:fs";
3
6
  import * as z from "zod";
4
- import { parseArgs } from "node:util";
5
7
  import { coerce, defineArguments, defineCLI, defineOptions, defineSubcommand } from "@staticbolt/args-parser";
6
8
 
7
- //#region src/helpers/load-config.ts
8
- async function loadConfigFile(configPath) {
9
- try {
10
- const loadedConfig = await import(configPath + `?update=${Date.now()}`);
11
- if (!loadedConfig.default) return [null, /* @__PURE__ */ new Error(`Failed to load config file at "${configPath}"`)];
12
- return [loadedConfig.default, null];
13
- } catch (error) {
14
- return [null, error];
15
- }
16
- }
17
-
18
- //#endregion
19
9
  //#region src/cli/commands/help.ts
20
10
  const helpCommand = defineSubcommand({
21
11
  name: "help",
@@ -41,6 +31,8 @@ helpCommand.onExecute((results) => {
41
31
 
42
32
  //#endregion
43
33
  //#region src/cli/cli.ts
34
+ /** The package's own manifest, which sits two levels up from both `src/cli` and `lib/cli`. */
35
+ const { version: packageVersion } = createRequire(import.meta.url)("../../package.json");
44
36
  var CliProgram = class CliProgram {
45
37
  program = defineCLI({
46
38
  cliName: "staticbolt",
@@ -49,6 +41,20 @@ var CliProgram = class CliProgram {
49
41
  example: "staticbolt build \nstaticbolt serve"
50
42
  },
51
43
  options: {
44
+ cwd: {
45
+ schema: z.string().optional(),
46
+ meta: {
47
+ placeholder: "<directory>",
48
+ description: "The directory to run in. Works with every command."
49
+ }
50
+ },
51
+ config: {
52
+ schema: z.string().optional(),
53
+ meta: {
54
+ placeholder: "<path>",
55
+ description: `The config file, relative to the directory. Works with every command. Defaults to "${CONFIG_FILE_NAME}".`
56
+ }
57
+ },
52
58
  help: {
53
59
  aliases: ["h"],
54
60
  schema: z.boolean().optional(),
@@ -74,19 +80,22 @@ var CliProgram = class CliProgram {
74
80
  return;
75
81
  }
76
82
  if (version) {
77
- console.log("v0.0.0");
83
+ console.log(`v${packageVersion}`);
78
84
  return;
79
85
  }
80
- console.error("No arguments provided. Use `static --help` for more information");
86
+ console.error("No arguments provided. Use `staticbolt --help` for more information");
81
87
  });
82
88
  }
83
- async initializePlugins(config, configPath) {
89
+ async initializePlugins(config, configPath, projectDirectory) {
84
90
  const plugins = config.plugins ?? [];
85
- for (const pluginOrPlugins of plugins) for (const plugin of Array.isArray(pluginOrPlugins) ? pluginOrPlugins : [pluginOrPlugins]) if (plugin.cli) await plugin.cli.call(this, config, configPath);
91
+ for (const pluginOrPlugins of plugins) {
92
+ const pluginsAsArray = Array.isArray(pluginOrPlugins) ? pluginOrPlugins : [pluginOrPlugins];
93
+ for (const plugin of pluginsAsArray) if (plugin.cli) await plugin.cli.call(this, config, configPath, projectDirectory);
94
+ }
86
95
  }
87
- static async init(config, configPath) {
96
+ static async init(config, configPath, projectDirectory) {
88
97
  const cliProgram = new CliProgram();
89
- await cliProgram.initializePlugins(config, configPath);
98
+ await cliProgram.initializePlugins(config, configPath, projectDirectory);
90
99
  return cliProgram;
91
100
  }
92
101
  run(cliArguments) {
@@ -101,7 +110,8 @@ var CliProgram = class CliProgram {
101
110
  this.#programWideType.subcommands = [newSubcommand];
102
111
  return;
103
112
  }
104
- return this.#programWideType.subcommands.push(newSubcommand);
113
+ this.#programWideType.subcommands.push(newSubcommand);
114
+ return this.#programWideType.subcommands.length;
105
115
  }
106
116
  addOptions(newOptions) {
107
117
  if (!this.#programWideType.options) {
@@ -145,32 +155,56 @@ var CliProgram = class CliProgram {
145
155
 
146
156
  //#endregion
147
157
  //#region src/cli/index.ts
148
- const { values } = parseArgs({
149
- options: {
150
- cwd: { type: "string" },
151
- config: { type: "string" }
152
- },
153
- allowPositionals: true,
154
- strict: false
155
- });
156
- const inputCwd = values.cwd ?? process.cwd();
157
- const inputConfigPath = values.config ?? ".staticbolt.ts";
158
- const projectDirectory = resolve(inputCwd);
159
- const configPath = isAbsolute(inputConfigPath) ? inputConfigPath : join(projectDirectory, inputConfigPath);
160
- const [loadedConfig, configError] = await loadConfigFile(configPath);
161
- if (configError) {
162
- Log.warn(`Failed to load config file at "${configPath}"`);
163
- throw configError;
164
- }
165
- const config = loadedConfig ?? {};
166
- if (config.root && !isAbsolute(config.root)) config.root = join(projectDirectory, config.root);
167
- if (!config.root) config.root = projectDirectory;
168
- const results = (await CliProgram.init(config, configPath)).run(process.argv.slice(2));
158
+ const cliArguments = process.argv.slice(2);
159
+ const projectDirectory = resolve(takeOption(cliArguments, "cwd") ?? process.cwd());
160
+ const configFile = takeOption(cliArguments, "config") ?? ".staticbolt.ts";
161
+ const configPath = isAbsolute(configFile) ? configFile : join(projectDirectory, configFile);
162
+ const config = await loadConfig();
163
+ const results = (await CliProgram.init(config, configPath, projectDirectory)).run(cliArguments);
169
164
  if (results.error) {
170
165
  console.error(results.error.message);
171
- console.log("\n`static --help` for more information, or `static help <command>` for command-specific help\n");
166
+ console.log("\n`staticbolt --help` for more information, or `staticbolt help <command>` for command-specific help\n");
172
167
  process.exit(1);
173
168
  }
169
+ /** Removes every `--name value` or `--name=value` from the arguments and returns the last value. */
170
+ function takeOption(cliArguments, name) {
171
+ const flag = `--${name}`;
172
+ const findFlag = () => cliArguments.findIndex((argument) => argument === flag || argument.startsWith(`${flag}=`));
173
+ let value;
174
+ for (let index = findFlag(); index !== -1; index = findFlag()) {
175
+ const isInlineValue = cliArguments[index] !== flag;
176
+ value = isInlineValue ? cliArguments[index].slice(flag.length + 1) : cliArguments[index + 1];
177
+ if (!value || !isInlineValue && value.startsWith("-")) {
178
+ console.error(`Option ${flag} requires a value`);
179
+ process.exit(1);
180
+ }
181
+ cliArguments.splice(index, isInlineValue ? 1 : 2);
182
+ }
183
+ return value;
184
+ }
185
+ /** The project's config. Without a config file only the root options are served, so `--help` and `--version` still answer. */
186
+ async function loadConfig() {
187
+ if (!existsSync(configPath)) {
188
+ if (cliArguments.some((argument) => [
189
+ "--help",
190
+ "-h",
191
+ "--version",
192
+ "-v"
193
+ ].includes(argument))) return { root: projectDirectory };
194
+ Log.error(`No config file at "${configPath}". Create one, or point at it with --cwd or --config.`);
195
+ process.exit(1);
196
+ }
197
+ const [config, configError] = await loadConfigFile(configPath, projectDirectory);
198
+ if (configError) {
199
+ Log.error(`Failed to load the config file at "${configPath}":`);
200
+ console.error(isCompileError(configError) ? configError.message : configError);
201
+ process.exit(1);
202
+ }
203
+ return config;
204
+ }
205
+ function isCompileError(error) {
206
+ return "errors" in error || error.cause instanceof Error && "errors" in error.cause;
207
+ }
174
208
 
175
209
  //#endregion
176
210
  export { };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["#programWideType"],"sources":["../../src/helpers/load-config.ts","../../src/cli/commands/help.ts","../../src/cli/cli.ts","../../src/cli/index.ts"],"sourcesContent":["import type { ValueOrError } from \"../utilities/value-or-error.ts\";\nimport type { AppConfig } from \"@staticbolt/core\";\n\nexport async function loadConfigFile(configPath: string): Promise<ValueOrError<AppConfig>> {\n try {\n const loadedConfig = (await import(configPath + `?update=${Date.now()}`)) as { default: AppConfig };\n if (!loadedConfig.default) {\n return [null, new Error(`Failed to load config file at \"${configPath}\"`)];\n }\n\n return [loadedConfig.default, null];\n } catch (error) {\n return [null, error as Error];\n }\n}\n","import { defineSubcommand } from \"@staticbolt/args-parser\";\nimport * as z from \"zod\";\n\nexport const helpCommand = defineSubcommand({\n name: \"help\",\n meta: {\n placeholder: \"<command>\",\n description: \"Print help message for a specific command.\",\n example: \"staticbolt help build\",\n },\n\n arguments: {\n command: {\n schema: z.string().optional(),\n meta: {\n description: \"The command to get help for.\",\n },\n },\n },\n});\n\nhelpCommand.onExecute(results => {\n const { command } = results.arguments;\n\n if (!helpCommand.generateCliHelpMessage || !helpCommand.generateSubcommandHelpMessage) {\n throw new Error(\"internal error: missing help functions\");\n }\n\n if (command) {\n console.log(helpCommand.generateSubcommandHelpMessage(command));\n return;\n }\n\n console.log(helpCommand.generateCliHelpMessage());\n});\n","import { coerce, defineArguments, defineCLI, defineOptions, defineSubcommand } from \"@staticbolt/args-parser\";\nimport * as z from \"zod\";\n\nimport { Log } from \"../utilities/logger.ts\";\nimport { helpCommand } from \"./commands/help.ts\";\n\nimport type { Argument, Cli, Option, Subcommand } from \"@staticbolt/args-parser\";\nimport type { AppConfig } from \"@staticbolt/core\";\n\nexport class CliProgram {\n program = defineCLI({\n cliName: \"staticbolt\",\n meta: {\n description: \"Build fast static websites.\",\n example: \"staticbolt build \\nstaticbolt serve\",\n },\n\n options: {\n help: {\n aliases: [\"h\"],\n schema: z.boolean().optional(),\n coerce: coerce.boolean,\n meta: {\n description: \"Show this help message.\",\n },\n },\n version: {\n aliases: [\"v\"],\n schema: z.boolean().optional(),\n coerce: coerce.boolean,\n meta: {\n description: \"Show current version.\",\n },\n },\n },\n });\n\n #programWideType: Cli = this.program;\n\n constructor() {\n this.addCommand(helpCommand);\n\n this.program.onExecute(results => {\n const { help, version } = results.options;\n\n if (help) {\n if (!this.program.generateCliHelpMessage) throw new Error(\"internal error: missing help functions\");\n console.log(this.program.generateCliHelpMessage());\n return;\n }\n\n if (version) {\n console.log(\"v0.0.0\");\n return;\n }\n\n console.error(\"No arguments provided. Use `static --help` for more information\");\n });\n }\n\n async initializePlugins(config: AppConfig, configPath: string) {\n const plugins = config.plugins ?? [];\n\n for (const pluginOrPlugins of plugins) {\n for (const plugin of Array.isArray(pluginOrPlugins) ? pluginOrPlugins : [pluginOrPlugins]) {\n if (plugin.cli) {\n await plugin.cli.call(this, config, configPath);\n }\n }\n }\n }\n\n static async init(config: AppConfig, configPath: string) {\n const cliProgram = new CliProgram();\n await cliProgram.initializePlugins(config, configPath);\n return cliProgram;\n }\n\n run(cliArguments: string[]) {\n return this.program.run(cliArguments);\n }\n\n readonly defineSubcommand = defineSubcommand;\n readonly defineOptions = defineOptions;\n readonly defineArguments = defineArguments;\n readonly coerce = coerce;\n\n addCommand(newSubcommand: Subcommand) {\n if (!this.#programWideType.subcommands) {\n this.#programWideType.subcommands = [newSubcommand];\n return;\n }\n\n return this.#programWideType.subcommands.push(newSubcommand);\n }\n\n addOptions(newOptions: Record<string, Option>) {\n if (!this.#programWideType.options) {\n this.#programWideType.options = newOptions;\n return;\n }\n\n return Object.assign(this.#programWideType.options, newOptions);\n }\n\n addArguments(newArguments: Record<string, Argument>) {\n if (!this.#programWideType.arguments) {\n this.#programWideType.arguments = newArguments;\n return;\n }\n\n return Object.assign(this.#programWideType.arguments, newArguments);\n }\n\n addOptionsToCommand(commandName: string, newOptions: Record<string, Option>) {\n const command = this.#programWideType.subcommands?.find(command => command.name === commandName);\n if (!command) {\n Log.error(`Command \"${commandName}\" not found`);\n return;\n }\n\n if (!command.options) {\n command.options = newOptions;\n return;\n }\n\n return Object.assign(command.options, newOptions);\n }\n\n addArgumentsToCommand(commandName: string, newArguments: Record<string, Argument>) {\n const command = this.#programWideType.subcommands?.find(command => command.name === commandName);\n if (!command) {\n Log.error(`Command \"${commandName}\" not found`);\n return;\n }\n\n if (!command.arguments) {\n command.arguments = newArguments;\n return;\n }\n\n return Object.assign(command.arguments, newArguments);\n }\n}\n","#!/usr/bin/env -S node --experimental-vm-modules --no-warnings\nimport { parseArgs } from \"node:util\";\n\nimport { loadConfigFile } from \"../helpers/load-config.ts\";\nimport { CONFIG_FILE_NAME } from \"../types/common.ts\";\nimport { Log } from \"../utilities/logger.ts\";\nimport { isAbsolute, join, resolve } from \"../utilities/path.ts\";\nimport { CliProgram } from \"./cli.ts\";\n\nconst { values } = parseArgs({\n options: {\n cwd: {\n type: \"string\",\n },\n config: {\n type: \"string\",\n },\n },\n allowPositionals: true,\n strict: false,\n});\n\nconst inputCwd: string = (values.cwd ?? process.cwd()) as string;\nconst inputConfigPath: string = (values.config ?? CONFIG_FILE_NAME) as string;\n\nconst projectDirectory = resolve(inputCwd);\nconst configPath = isAbsolute(inputConfigPath) ? inputConfigPath : join(projectDirectory, inputConfigPath);\n\nconst [loadedConfig, configError] = await loadConfigFile(configPath);\nif (configError) {\n Log.warn(`Failed to load config file at \"${configPath}\"`);\n throw configError;\n}\n\nconst config = loadedConfig ?? {};\n\nif (config.root && !isAbsolute(config.root)) {\n config.root = join(projectDirectory, config.root);\n}\n\nif (!config.root) {\n config.root = projectDirectory;\n}\n\nconst cli = await CliProgram.init(config, configPath);\nconst results = cli.run(process.argv.slice(2));\n\nif (results.error) {\n console.error(results.error.message);\n console.log(\"\\n`static --help` for more information, or `static help <command>` for command-specific help\\n\");\n process.exit(1);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["#programWideType"],"sources":["../../src/cli/commands/help.ts","../../src/cli/cli.ts","../../src/cli/index.ts"],"sourcesContent":["import { defineSubcommand } from \"@staticbolt/args-parser\";\nimport * as z from \"zod\";\n\nexport const helpCommand = defineSubcommand({\n name: \"help\",\n meta: {\n placeholder: \"<command>\",\n description: \"Print help message for a specific command.\",\n example: \"staticbolt help build\",\n },\n\n arguments: {\n command: {\n schema: z.string().optional(),\n meta: {\n description: \"The command to get help for.\",\n },\n },\n },\n});\n\nhelpCommand.onExecute(results => {\n const { command } = results.arguments;\n\n if (!helpCommand.generateCliHelpMessage || !helpCommand.generateSubcommandHelpMessage) {\n throw new Error(\"internal error: missing help functions\");\n }\n\n if (command) {\n console.log(helpCommand.generateSubcommandHelpMessage(command));\n return;\n }\n\n console.log(helpCommand.generateCliHelpMessage());\n});\n","import { createRequire } from \"node:module\";\nimport { coerce, defineArguments, defineCLI, defineOptions, defineSubcommand } from \"@staticbolt/args-parser\";\nimport * as z from \"zod\";\n\nimport { CONFIG_FILE_NAME } from \"../types/common.ts\";\nimport { Log } from \"../utilities/logger.ts\";\nimport { helpCommand } from \"./commands/help.ts\";\n\nimport type { Argument, Cli, Option, Subcommand } from \"@staticbolt/args-parser\";\nimport type { AppConfig } from \"@staticbolt/core\";\n\n/** The package's own manifest, which sits two levels up from both `src/cli` and `lib/cli`. */\nconst { version: packageVersion } = createRequire(import.meta.url)(\"../../package.json\") as { version: string };\n\nexport class CliProgram {\n program = defineCLI({\n cliName: \"staticbolt\",\n meta: {\n description: \"Build fast static websites.\",\n example: \"staticbolt build \\nstaticbolt serve\",\n },\n\n options: {\n cwd: {\n schema: z.string().optional(),\n meta: {\n placeholder: \"<directory>\",\n description: \"The directory to run in. Works with every command.\",\n },\n },\n config: {\n schema: z.string().optional(),\n meta: {\n placeholder: \"<path>\",\n description: `The config file, relative to the directory. Works with every command. Defaults to \"${CONFIG_FILE_NAME}\".`,\n },\n },\n help: {\n aliases: [\"h\"],\n schema: z.boolean().optional(),\n coerce: coerce.boolean,\n meta: {\n description: \"Show this help message.\",\n },\n },\n version: {\n aliases: [\"v\"],\n schema: z.boolean().optional(),\n coerce: coerce.boolean,\n meta: {\n description: \"Show current version.\",\n },\n },\n },\n });\n\n #programWideType: Cli = this.program;\n\n constructor() {\n this.addCommand(helpCommand);\n\n this.program.onExecute(results => {\n const { help, version } = results.options;\n\n if (help) {\n if (!this.program.generateCliHelpMessage) throw new Error(\"internal error: missing help functions\");\n console.log(this.program.generateCliHelpMessage());\n return;\n }\n\n if (version) {\n console.log(`v${packageVersion}`);\n return;\n }\n\n console.error(\"No arguments provided. Use `staticbolt --help` for more information\");\n });\n }\n\n async initializePlugins(config: AppConfig, configPath: string, projectDirectory: string) {\n const plugins = config.plugins ?? [];\n\n for (const pluginOrPlugins of plugins) {\n const pluginsAsArray = Array.isArray(pluginOrPlugins) ? pluginOrPlugins : [pluginOrPlugins];\n\n for (const plugin of pluginsAsArray) {\n if (plugin.cli) {\n await plugin.cli.call(this, config, configPath, projectDirectory);\n }\n }\n }\n }\n\n static async init(config: AppConfig, configPath: string, projectDirectory: string) {\n const cliProgram = new CliProgram();\n await cliProgram.initializePlugins(config, configPath, projectDirectory);\n return cliProgram;\n }\n\n run(cliArguments: string[]) {\n return this.program.run(cliArguments);\n }\n\n readonly defineSubcommand = defineSubcommand;\n readonly defineOptions = defineOptions;\n readonly defineArguments = defineArguments;\n readonly coerce = coerce;\n\n addCommand(newSubcommand: Subcommand) {\n if (!this.#programWideType.subcommands) {\n this.#programWideType.subcommands = [newSubcommand];\n return;\n }\n\n this.#programWideType.subcommands.push(newSubcommand);\n\n return this.#programWideType.subcommands.length;\n }\n\n addOptions(newOptions: Record<string, Option>) {\n if (!this.#programWideType.options) {\n this.#programWideType.options = newOptions;\n return;\n }\n\n return Object.assign(this.#programWideType.options, newOptions);\n }\n\n addArguments(newArguments: Record<string, Argument>) {\n if (!this.#programWideType.arguments) {\n this.#programWideType.arguments = newArguments;\n return;\n }\n\n return Object.assign(this.#programWideType.arguments, newArguments);\n }\n\n addOptionsToCommand(commandName: string, newOptions: Record<string, Option>) {\n const command = this.#programWideType.subcommands?.find(command => command.name === commandName);\n if (!command) {\n Log.error(`Command \"${commandName}\" not found`);\n return;\n }\n\n if (!command.options) {\n command.options = newOptions;\n return;\n }\n\n return Object.assign(command.options, newOptions);\n }\n\n addArgumentsToCommand(commandName: string, newArguments: Record<string, Argument>) {\n const command = this.#programWideType.subcommands?.find(command => command.name === commandName);\n if (!command) {\n Log.error(`Command \"${commandName}\" not found`);\n return;\n }\n\n if (!command.arguments) {\n command.arguments = newArguments;\n return;\n }\n\n return Object.assign(command.arguments, newArguments);\n }\n}\n","#!/usr/bin/env node\nimport { existsSync } from \"node:fs\";\n\nimport { loadConfigFile } from \"../helpers/load-config.ts\";\nimport { CONFIG_FILE_NAME } from \"../types/common.ts\";\nimport { Log } from \"../utilities/logger.ts\";\nimport { isAbsolute, join, resolve } from \"../utilities/path.ts\";\nimport { CliProgram } from \"./cli.ts\";\n\nimport type { AppConfig } from \"@staticbolt/core\";\n\nconst cliArguments = process.argv.slice(2);\n\nconst projectDirectory = resolve(takeOption(cliArguments, \"cwd\") ?? process.cwd());\nconst configFile = takeOption(cliArguments, \"config\") ?? CONFIG_FILE_NAME;\nconst configPath = isAbsolute(configFile) ? configFile : join(projectDirectory, configFile);\nconst config = await loadConfig();\n\nconst cli = await CliProgram.init(config, configPath, projectDirectory);\nconst results = cli.run(cliArguments);\n\nif (results.error) {\n console.error(results.error.message);\n console.log(\"\\n`staticbolt --help` for more information, or `staticbolt help <command>` for command-specific help\\n\");\n process.exit(1);\n}\n\n/** Removes every `--name value` or `--name=value` from the arguments and returns the last value. */\nfunction takeOption(cliArguments: string[], name: string): string | undefined {\n const flag = `--${name}`;\n const findFlag = () => cliArguments.findIndex(argument => argument === flag || argument.startsWith(`${flag}=`));\n let value: string | undefined;\n\n for (let index = findFlag(); index !== -1; index = findFlag()) {\n const isInlineValue = cliArguments[index] !== flag;\n value = isInlineValue ? cliArguments[index].slice(flag.length + 1) : cliArguments[index + 1];\n\n if (!value || (!isInlineValue && value.startsWith(\"-\"))) {\n console.error(`Option ${flag} requires a value`);\n process.exit(1);\n }\n\n cliArguments.splice(index, isInlineValue ? 1 : 2);\n }\n\n return value;\n}\n\n/** The project's config. Without a config file only the root options are served, so `--help` and `--version` still answer. */\nasync function loadConfig(): Promise<AppConfig> {\n if (!existsSync(configPath)) {\n const isAskingAbout = cliArguments.some(argument => [\"--help\", \"-h\", \"--version\", \"-v\"].includes(argument));\n if (isAskingAbout) return { root: projectDirectory };\n\n Log.error(`No config file at \"${configPath}\". Create one, or point at it with --cwd or --config.`);\n process.exit(1);\n }\n\n const [config, configError] = await loadConfigFile(configPath, projectDirectory);\n if (configError) {\n Log.error(`Failed to load the config file at \"${configPath}\":`);\n // A compile error already says where it is; a stack would only point into esbuild\n console.error(isCompileError(configError) ? configError.message : configError);\n process.exit(1);\n }\n\n return config;\n}\n\nfunction isCompileError(error: Error): boolean {\n return \"errors\" in error || (error.cause instanceof Error && \"errors\" in error.cause);\n}\n"],"mappings":"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"}
@@ -1,19 +1,50 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-DXywRVcq.mjs";
1
2
  import nodePath, { basename, extname, isAbsolute, parse, resolve } from "node:path";
2
3
  import micromatch from "micromatch";
3
- import c from "chalk";
4
+ import chalk from "chalk";
4
5
 
5
6
  //#region src/utilities/path.ts
7
+ var path_exports = /* @__PURE__ */ __exportAll({
8
+ appendForwardSlash: () => appendForwardSlash,
9
+ basename: () => basename,
10
+ dirname: () => dirname,
11
+ extname: () => extname,
12
+ firstPart: () => firstPart,
13
+ isAbsolute: () => isAbsolute,
14
+ isPathMatch: () => isPathMatch,
15
+ isSubpath: () => isSubpath,
16
+ join: () => join,
17
+ normalize: () => normalize,
18
+ parse: () => parse,
19
+ parsePatterns: () => parsePatterns,
20
+ rebaseRelativePath: () => rebaseRelativePath,
21
+ relative: () => relative,
22
+ replaceExtension: () => replaceExtension,
23
+ resolve: () => resolve,
24
+ sourceRelativeToRoot: () => sourceRelativeToRoot,
25
+ trimDotPrefix: () => trimDotPrefix
26
+ });
6
27
  const separatorRe = /\\/g;
7
28
  /** Normalizes a path result to unix separators and ensures relative paths start with `./` */
8
29
  function unixify(path) {
9
- const unix = path.replace(separatorRe, "/");
30
+ const unix = path.includes("\\") ? path.replace(separatorRe, "/") : path;
10
31
  if (unix === ".") return "./";
11
32
  if (unix === "/" || nodePath.isAbsolute(unix)) return unix;
12
33
  if (unix.startsWith("./") || unix.startsWith("../")) return unix;
13
34
  return `./${unix}`;
14
35
  }
15
36
  const join = (...arguments_) => unixify(nodePath.join(...arguments_));
16
- const relative = (from, to) => unixify(nodePath.relative(from, to));
37
+ /** `relative` is pure and called with highly repetitive inputs on hot paths, so cache results. */
38
+ const relativeCache = /* @__PURE__ */ new Map();
39
+ const relative = (from, to) => {
40
+ const key = from + "\0" + to;
41
+ let result = relativeCache.get(key);
42
+ if (result === void 0) {
43
+ result = unixify(nodePath.relative(from, to));
44
+ relativeCache.set(key, result);
45
+ }
46
+ return result;
47
+ };
17
48
  const dirname = (path) => unixify(nodePath.dirname(path));
18
49
  const normalize = (path) => unixify(nodePath.normalize(path));
19
50
  /**
@@ -60,25 +91,46 @@ const appendForwardSlash = (path) => path.endsWith("/") ? path : `${path}/`;
60
91
  const trimDotPrefix = (path) => path.startsWith("./") ? path.slice(2) : path;
61
92
  /** Returns the first segment of a path. */
62
93
  function firstPart(path) {
63
- return normalize(path).replace(/\/$/, "").split("/")[0] ?? "";
94
+ return normalize(path).replace(/\/$/, "").split("/", 1)[0] ?? "";
95
+ }
96
+ /**
97
+ * Splits a semicolon-separated attribute value into an array of trimmed glob patterns.
98
+ *
99
+ * Returns `undefined` when the input is not a string, and an empty array for an empty string.
100
+ */
101
+ function parsePatterns(string) {
102
+ if (typeof string !== "string") return;
103
+ if (!string) return [];
104
+ return string.split(";").flatMap((pattern) => {
105
+ const trimmed = pattern.trim();
106
+ return trimmed ? [trimmed] : [];
107
+ });
108
+ }
109
+ const matcherCache = /* @__PURE__ */ new Map();
110
+ /** `micromatch.isMatch` compiles its patterns on every call; cache the compiled matcher per patterns+options instead. */
111
+ function getMatcher(include, ignore, cwd) {
112
+ const key = JSON.stringify([
113
+ include,
114
+ ignore,
115
+ cwd
116
+ ]);
117
+ let matcher = matcherCache.get(key);
118
+ if (!matcher) {
119
+ matcher = micromatch.matcher(include, cwd === void 0 ? { ignore } : {
120
+ cwd,
121
+ ignore
122
+ });
123
+ matcherCache.set(key, matcher);
124
+ }
125
+ return matcher;
64
126
  }
65
127
  /** Checks if a file path matches a set of patterns. */
66
- function matchPath(filePath, { include, ignore, root }) {
67
- if (filePath.startsWith("..")) return micromatch.isMatch(join(root, filePath), include, { ignore });
128
+ function isPathMatch(filePath, { include, ignore, root }) {
129
+ if (filePath.startsWith("..")) return getMatcher(include, ignore, void 0)(join(root, filePath));
68
130
  const withoutDotPrefix = filePath.replace(/^\.\//, "");
69
- return micromatch.isMatch(withoutDotPrefix, include, {
70
- cwd: root,
71
- ignore
72
- });
131
+ return getMatcher(include, ignore, root)(withoutDotPrefix);
73
132
  }
74
133
 
75
- //#endregion
76
- //#region src/types/common.ts
77
- const CUSTOM_ATTRIBUTES = Object.freeze({
78
- /** For script and style tags to grab the metadata */
79
- MetadataID: "data-metadata-id" });
80
- const CONFIG_FILE_NAME = ".staticbolt.ts";
81
-
82
134
  //#endregion
83
135
  //#region src/utilities/logger.ts
84
136
  const logConfig = {
@@ -87,15 +139,15 @@ const logConfig = {
87
139
  titleWidth: 10,
88
140
  spacer: " ",
89
141
  style: {
90
- success: c.green,
91
- error: c.red,
92
- fatal: c.red,
93
- warning: c.yellow,
94
- verbose: c.dim,
95
- info: c.blueBright,
96
- tip: c.magenta,
97
- log: c.white,
98
- spacer: c.dim
142
+ success: chalk.green,
143
+ error: chalk.red,
144
+ fatal: chalk.red,
145
+ warning: chalk.yellow,
146
+ verbose: chalk.dim,
147
+ info: chalk.blueBright,
148
+ tip: chalk.magenta,
149
+ log: chalk.white,
150
+ spacer: chalk.dim
99
151
  }
100
152
  };
101
153
  function createLog(...defaultMessages) {
@@ -127,8 +179,8 @@ function createLog(...defaultMessages) {
127
179
  if (logConfig.verboseFilter && !logConfig.verboseFilter.test(joined)) return;
128
180
  logFormatter("DEBUG", logConfig.style.verbose, joined);
129
181
  };
130
- Log.enableVerbose = (enabled) => {
131
- logConfig.verboseEnabled = enabled;
182
+ Log.enableVerbose = (isEnabled) => {
183
+ logConfig.verboseEnabled = isEnabled;
132
184
  };
133
185
  Log.setVerboseFilter = (filter) => {
134
186
  logConfig.verboseFilter = filter;
@@ -162,13 +214,13 @@ function logFormatter(title, style, ...messages) {
162
214
  const formattedTitle = formatLogTitle(title, style);
163
215
  const splitByNewLines = content.split("\n");
164
216
  let message = "";
165
- for (const [index, splitByNewLine] of splitByNewLines.entries()) {
217
+ for (const [index, splitByNewline] of splitByNewLines.entries()) {
166
218
  if (index > 0) {
167
219
  const width = logConfig.titleWidth / logConfig.spacer.length;
168
220
  const spacer = logConfig.spacer.repeat(width).padEnd(logConfig.titleWidth);
169
- message += "\n" + style.dim(spacer + "");
221
+ message += "\n" + style.dim(spacer + " ");
170
222
  }
171
- message += splitByNewLine;
223
+ message += splitByNewline;
172
224
  }
173
225
  console.log(prefixNewlines + formattedTitle, message, suffixNewlines);
174
226
  }
@@ -186,5 +238,12 @@ function splitOnNewline(input) {
186
238
  }
187
239
 
188
240
  //#endregion
189
- export { relative as _, appendForwardSlash as a, sourceRelativeToRoot as b, extname as c, isSubpath as d, join as f, rebaseRelativePath as g, parse as h, CUSTOM_ATTRIBUTES as i, firstPart as l, normalize as m, createLog as n, basename as o, matchPath as p, CONFIG_FILE_NAME as r, dirname as s, Log as t, isAbsolute as u, replaceExtension as v, trimDotPrefix as x, resolve as y };
190
- //# sourceMappingURL=logger-BuxMGhij.mjs.map
241
+ //#region src/types/common.ts
242
+ const CUSTOM_ATTRIBUTES = Object.freeze({
243
+ /** For script and style tags to grab the metadata */
244
+ MetadataID: "data-metadata-id" });
245
+ const CONFIG_FILE_NAME = ".staticbolt.ts";
246
+
247
+ //#endregion
248
+ export { replaceExtension as _, basename as a, isAbsolute as c, join as d, normalize as f, relative as g, path_exports as h, createLog as i, isPathMatch as l, parsePatterns as m, CUSTOM_ATTRIBUTES as n, dirname as o, parse as p, Log as r, extname as s, CONFIG_FILE_NAME as t, isSubpath as u, resolve as v };
249
+ //# sourceMappingURL=common-D1QTZ8ra.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common-D1QTZ8ra.mjs","names":[],"sources":["../src/utilities/path.ts","../src/utilities/logger.ts","../src/types/common.ts"],"sourcesContent":["import nodePath from \"node:path\";\nimport micromatch from \"micromatch\";\n\nexport { basename, extname, isAbsolute, parse, resolve } from \"node:path\";\n\n// For ESM and CSS compatibility:\n// - Always use unix separators (except `resolve`, which returns an absolute path)\n// - Relative paths should always start with `./`\n\nconst separatorRe = /\\\\/g;\n\n/** Normalizes a path result to unix separators and ensures relative paths start with `./` */\nfunction unixify(path: string): string {\n const unix = path.includes(\"\\\\\") ? path.replace(separatorRe, \"/\") : path;\n\n // Example: dirname(\"index.html\") => \".\"\n if (unix === \".\") {\n return \"./\";\n }\n\n if (unix === \"/\" || nodePath.isAbsolute(unix)) {\n return unix;\n }\n\n if (unix.startsWith(\"./\") || unix.startsWith(\"../\")) {\n return unix;\n }\n\n return `./${unix}`;\n}\n\nexport const join = (...arguments_: string[]) => unixify(nodePath.join(...arguments_));\n\n/** `relative` is pure and called with highly repetitive inputs on hot paths, so cache results. */\nconst relativeCache = new Map<string, string>();\n\nexport const relative = (from: string, to: string) => {\n const key = from + \"\\u{0}\" + to;\n\n let result = relativeCache.get(key);\n if (result === undefined) {\n result = unixify(nodePath.relative(from, to));\n relativeCache.set(key, result);\n }\n\n return result;\n};\n\nexport const dirname = (path: string) => unixify(nodePath.dirname(path));\n\nexport const normalize = (path: string) => unixify(nodePath.normalize(path));\n\n/**\n * Recalculates the relative path for a resource after a file has been moved.\n *\n * @param source - The source found in the `oldPath` file.\n * @param oldPath - Absolute or relative original path of the file.\n * @param newPath - Absolute or relative new path of the file.\n * @returns The updated relative path from the new file's directory to the same resource.\n */\nexport function rebaseRelativePath(source: string, oldPath: string, newPath: string): string {\n return relative(dirname(newPath), join(dirname(oldPath), source));\n}\n\n/**\n * Checks if a path (child) is a subpath of another (parent).\n *\n * Note: both paths must be of the same type — either both absolute or both relative. Mixing them will produce incorrect results.\n *\n * @param parentDirectory - The parent directory.\n * @param childPath - The child path (file or directory).\n */\nexport function isSubpath(parentDirectory: string, childPath: string): boolean {\n if (childPath === \"./\") return false;\n const relativePath = relative(normalize(parentDirectory), normalize(childPath));\n return relativePath === \"\" || (!relativePath.startsWith(\"..\") && !nodePath.isAbsolute(relativePath));\n}\n\ninterface SourceRelativeToRootOptions {\n /** The root directory (absolute or resolvable) */\n root: string;\n /** The file path that contains the source path */\n filePath: string;\n /** The source path */\n sourcePath: string;\n}\n\n/** Calculates the relative path of a source path to the root. */\nexport function sourceRelativeToRoot({ root, filePath, sourcePath }: SourceRelativeToRootOptions): string {\n const absRoot = nodePath.resolve(root);\n return relative(absRoot, nodePath.join(absRoot, dirname(filePath), sourcePath));\n}\n\n/** Replaces the extension of a given path. */\nexport function replaceExtension(filePath: string, extension: string): string {\n const { dir, name } = nodePath.parse(filePath);\n return normalize(nodePath.format({ dir, name, ext: extension }));\n}\n\n/** Appends a forward slash to the end of a path if it doesn't already end with one. */\nexport const appendForwardSlash = (path: string) => (path.endsWith(\"/\") ? path : `${path}/`);\n\n/** Removes the leading `./` from a path. */\nexport const trimDotPrefix = (path: string) => (path.startsWith(\"./\") ? path.slice(2) : path);\n\n/** Returns the first segment of a path. */\nexport function firstPart(path: string): string {\n const cleaned = normalize(path).replace(/\\/$/, \"\");\n return cleaned.split(\"/\", 1)[0] ?? \"\";\n}\n\n/**\n * Splits a semicolon-separated attribute value into an array of trimmed glob patterns.\n *\n * Returns `undefined` when the input is not a string, and an empty array for an empty string.\n */\nexport function parsePatterns(string: string | null | undefined): string[] | undefined {\n if (typeof string !== \"string\") return;\n\n if (!string) return [];\n\n return string.split(\";\").flatMap(pattern => {\n const trimmed = pattern.trim();\n return trimmed ? [trimmed] : [];\n });\n}\n\ninterface MatchPathOptions {\n include: string | string[];\n ignore?: string | string[];\n root: string;\n}\n\nconst matcherCache = new Map<string, (path: string) => boolean>();\n\n/** `micromatch.isMatch` compiles its patterns on every call; cache the compiled matcher per patterns+options instead. */\nfunction getMatcher(include: string | string[], ignore: string | string[] | undefined, cwd: string | undefined) {\n const key = JSON.stringify([include, ignore, cwd]);\n\n let matcher = matcherCache.get(key);\n if (!matcher) {\n // The underlying picomatch accepts `string | string[]` patterns, the micromatch typings are just too narrow\n matcher = micromatch.matcher(include as string, cwd === undefined ? { ignore } : { cwd, ignore });\n matcherCache.set(key, matcher);\n }\n\n return matcher;\n}\n\n/** Checks if a file path matches a set of patterns. */\nexport function isPathMatch(filePath: string, { include, ignore, root }: MatchPathOptions): boolean {\n // Case: outside the root directory\n if (filePath.startsWith(\"..\")) {\n return getMatcher(include, ignore, undefined)(join(root, filePath));\n }\n\n // Case: inside the root dir\n const withoutDotPrefix = filePath.replace(/^\\.\\//, \"\");\n return getMatcher(include, ignore, root)(withoutDotPrefix);\n}\n","import chalk from \"chalk\";\n\ntype ChalkInstance = typeof chalk;\n\nconst logConfig = {\n verboseEnabled: false,\n verboseFilter: null as null | RegExp,\n titleWidth: 10,\n spacer: \" \",\n style: {\n success: chalk.green,\n error: chalk.red,\n fatal: chalk.red,\n warning: chalk.yellow,\n verbose: chalk.dim,\n info: chalk.blueBright,\n tip: chalk.magenta,\n log: chalk.white,\n spacer: chalk.dim,\n },\n};\n\nexport function createLog(...defaultMessages: string[]) {\n function Log(...messages: unknown[]) {\n console.log(formatLogTitle(\"LOG\", logConfig.style.log), ...defaultMessages, ...messages);\n }\n\n Log.warn = (...messages: string[]) => {\n logFormatter(\"WARNING\", logConfig.style.warning, ...defaultMessages, ...messages);\n };\n\n Log.success = (...messages: string[]) => {\n logFormatter(\"SUCCESS\", logConfig.style.success, ...defaultMessages, ...messages);\n };\n\n Log.error = (...messages: string[]) => {\n logFormatter(\"ERROR\", logConfig.style.error, ...defaultMessages, ...messages);\n };\n\n Log.fatal = (...messages: string[]) => {\n logFormatter(\"FATAL\", logConfig.style.fatal, ...defaultMessages, ...messages);\n\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(1);\n };\n\n Log.info = (...messages: string[]) => {\n logFormatter(\"INFO\", logConfig.style.info, ...defaultMessages, ...messages);\n };\n\n Log.tip = (...messages: string[]) => {\n logFormatter(\"TIP\", logConfig.style.tip, ...defaultMessages, ...messages);\n };\n\n Log.debug = (...messages: string[]) => {\n if (!logConfig.verboseEnabled) return;\n\n const joined = defaultMessages.concat(messages).join(\" \");\n if (logConfig.verboseFilter && !logConfig.verboseFilter.test(joined)) return;\n\n logFormatter(\"DEBUG\", logConfig.style.verbose, joined);\n };\n\n Log.enableVerbose = (isEnabled: boolean) => {\n logConfig.verboseEnabled = isEnabled;\n };\n\n Log.setVerboseFilter = (filter: RegExp) => {\n logConfig.verboseFilter = filter;\n };\n\n return Log;\n}\n\n/**\n * - Prints a styled message to the console.\n *\n * @example\n * Log(\"Hello World!\"); // Prints: | LOG | Hello World! |\n * Log.success(\"Hello World!\"); // Prints: | SUCCESS | Hello World! |\n * Log.info(\"Hello World!\"); // Prints: | INFO | Hello World! |\n * Log.error(\"Hello World!\"); // Prints: | ERROR | Hello World! |\n * Log.fatal(\"Hello World!\"); // Prints: | FATAL | Hello World! |\n * Log.warn(\"Hello World!\"); // Prints: | WARNING | Hello World! |\n */\nexport const Log = createLog();\n\nfunction formatLogTitle(title: string, style: ChalkInstance) {\n const width = logConfig.titleWidth;\n const paddingLength = title.length >= width ? 0 : (width - title.length) / 2;\n const paddingStart = \" \".repeat(paddingLength);\n const paddingEnd = \" \".repeat(paddingLength);\n\n title = paddingStart + title + paddingEnd;\n\n // Ensure that the final string has width length\n title = title.padEnd(width, \" \");\n\n // apply style\n title = style(title + \"|\");\n\n return title;\n}\n\nfunction logFormatter(title: string, style: ChalkInstance, ...messages: string[]) {\n const { prefixNewlines, content, suffixNewlines } = splitOnNewline(messages);\n const formattedTitle = formatLogTitle(title, style);\n\n const splitByNewLines = content.split(\"\\n\");\n\n let message = \"\";\n for (const [index, splitByNewline] of splitByNewLines.entries()) {\n if (index > 0) {\n const width = logConfig.titleWidth / logConfig.spacer.length;\n const spacer = logConfig.spacer.repeat(width).padEnd(logConfig.titleWidth);\n message += \"\\n\" + style.dim(spacer + \" \");\n }\n\n message += splitByNewline;\n }\n\n console.log(prefixNewlines + formattedTitle, message, suffixNewlines);\n}\n\nfunction splitOnNewline(input: string[]) {\n const message = input.join(\" \");\n\n // Check for leading newlines\n let newlineStart = 0;\n while (newlineStart < message.length && message[newlineStart] == \"\\n\") {\n newlineStart++;\n }\n\n // Check for trailing newlines\n let newlineEnd = message.length;\n while (newlineEnd > newlineStart && message[newlineEnd - 1] == \"\\n\") {\n newlineEnd--;\n }\n\n const results = {\n prefixNewlines: message.slice(0, Math.max(0, newlineStart)),\n content: message.slice(newlineStart, newlineEnd),\n suffixNewlines: message.slice(Math.max(0, newlineEnd)),\n };\n\n return results;\n}\n","import type { ParseResult } from \"@babel/parser\";\nimport type { Plugin } from \"@staticbolt/core\";\nimport type { Root } from \"mdast\";\nimport type postcss from \"postcss\";\n\nexport type { NodePath } from \"@babel/traverse\";\n\nexport type BabelAst = ParseResult;\nexport type PostcssAst = postcss.Root;\nexport type { HTMLElement, Document } from \"@staticbolt/node-html-parser\";\n\nexport interface MarkdownAst {\n root: Root;\n frontmatter: Record<string, string>;\n render(): Promise<string>;\n}\n\nexport const CUSTOM_ATTRIBUTES = Object.freeze({\n /** For script and style tags to grab the metadata */\n MetadataID: \"data-metadata-id\",\n});\n\nexport const CONFIG_FILE_NAME = \".staticbolt.ts\";\n\nexport interface AppConfig {\n /**\n * The project root. Relative paths in the config are resolved against it.\n *\n * @default process.cwd()\n */\n root?: string;\n\n /** Plugins to run, in order. Nested arrays are flattened, so a plugin preset can be spread in as a single entry. */\n plugins?: (Plugin[] | Plugin)[];\n\n /**\n * The output directory, either absolute or relative to {@link AppConfig.root}.\n *\n * @default \"./dist\"\n */\n outdir?: string;\n\n /**\n * Whether to build for production. In development the project is watched for file changes.\n *\n * @default false\n */\n production?: boolean;\n\n /**\n * Browsers to target, as [browserslist](https://github.com/browserslist/browserslist) queries. Defaults to the project's\n * browserslist configuration.\n *\n * @example\n * [\"last 2 Chrome versions\", \"last 2 Safari versions\"];\n */\n browserslist?: string[];\n\n /**\n * Whether to time each plugin hook and print a breakdown when the build finishes.\n *\n * @default false\n */\n measureExecutionTime?: boolean;\n\n /**\n * Path aliases, merged on top of the ones resolved from `tsconfig.json` — entries defined here win on key conflicts.\n *\n * Keys ending with `/` are directory aliases, otherwise the key is matched as a whole. Values are resolved relative to the\n * project root.\n *\n * @example\n * { \"~/\": \"./src/\", \"@config\": \"./src/config.ts\" }\n */\n aliases?: Record<string, string>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AASA,MAAM,cAAc;;AAGpB,SAAS,QAAQ,MAAsB;CACrC,MAAM,OAAO,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,aAAa,GAAG,IAAI;CAGpE,IAAI,SAAS,KACX,OAAO;CAGT,IAAI,SAAS,OAAO,SAAS,WAAW,IAAI,GAC1C,OAAO;CAGT,IAAI,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW,KAAK,GAChD,OAAO;CAGT,OAAO,KAAK;AACd;AAEA,MAAa,QAAQ,GAAG,eAAyB,QAAQ,SAAS,KAAK,GAAG,UAAU,CAAC;;AAGrF,MAAM,gCAAgB,IAAI,IAAoB;AAE9C,MAAa,YAAY,MAAc,OAAe;CACpD,MAAM,MAAM,OAAO,OAAU;CAE7B,IAAI,SAAS,cAAc,IAAI,GAAG;CAClC,IAAI,WAAW,QAAW;EACxB,SAAS,QAAQ,SAAS,SAAS,MAAM,EAAE,CAAC;EAC5C,cAAc,IAAI,KAAK,MAAM;CAC/B;CAEA,OAAO;AACT;AAEA,MAAa,WAAW,SAAiB,QAAQ,SAAS,QAAQ,IAAI,CAAC;AAEvE,MAAa,aAAa,SAAiB,QAAQ,SAAS,UAAU,IAAI,CAAC;;;;;;;;;AAU3E,SAAgB,mBAAmB,QAAgB,SAAiB,SAAyB;CAC3F,OAAO,SAAS,QAAQ,OAAO,GAAG,KAAK,QAAQ,OAAO,GAAG,MAAM,CAAC;AAClE;;;;;;;;;AAUA,SAAgB,UAAU,iBAAyB,WAA4B;CAC7E,IAAI,cAAc,MAAM,OAAO;CAC/B,MAAM,eAAe,SAAS,UAAU,eAAe,GAAG,UAAU,SAAS,CAAC;CAC9E,OAAO,iBAAiB,MAAO,CAAC,aAAa,WAAW,IAAI,KAAK,CAAC,SAAS,WAAW,YAAY;AACpG;;AAYA,SAAgB,qBAAqB,EAAE,MAAM,UAAU,cAAmD;CACxG,MAAM,UAAU,SAAS,QAAQ,IAAI;CACrC,OAAO,SAAS,SAAS,SAAS,KAAK,SAAS,QAAQ,QAAQ,GAAG,UAAU,CAAC;AAChF;;AAGA,SAAgB,iBAAiB,UAAkB,WAA2B;CAC5E,MAAM,EAAE,KAAK,SAAS,SAAS,MAAM,QAAQ;CAC7C,OAAO,UAAU,SAAS,OAAO;EAAE;EAAK;EAAM,KAAK;CAAU,CAAC,CAAC;AACjE;;AAGA,MAAa,sBAAsB,SAAkB,KAAK,SAAS,GAAG,IAAI,OAAO,GAAG,KAAK;;AAGzF,MAAa,iBAAiB,SAAkB,KAAK,WAAW,IAAI,IAAI,KAAK,MAAM,CAAC,IAAI;;AAGxF,SAAgB,UAAU,MAAsB;CAE9C,OADgB,UAAU,IAAI,CAAC,CAAC,QAAQ,OAAO,EAClC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,MAAM;AACrC;;;;;;AAOA,SAAgB,cAAc,QAAyD;CACrF,IAAI,OAAO,WAAW,UAAU;CAEhC,IAAI,CAAC,QAAQ,OAAO,CAAC;CAErB,OAAO,OAAO,MAAM,GAAG,CAAC,CAAC,SAAQ,YAAW;EAC1C,MAAM,UAAU,QAAQ,KAAK;EAC7B,OAAO,UAAU,CAAC,OAAO,IAAI,CAAC;CAChC,CAAC;AACH;AAQA,MAAM,+BAAe,IAAI,IAAuC;;AAGhE,SAAS,WAAW,SAA4B,QAAuC,KAAyB;CAC9G,MAAM,MAAM,KAAK,UAAU;EAAC;EAAS;EAAQ;CAAG,CAAC;CAEjD,IAAI,UAAU,aAAa,IAAI,GAAG;CAClC,IAAI,CAAC,SAAS;EAEZ,UAAU,WAAW,QAAQ,SAAmB,QAAQ,SAAY,EAAE,OAAO,IAAI;GAAE;GAAK;EAAO,CAAC;EAChG,aAAa,IAAI,KAAK,OAAO;CAC/B;CAEA,OAAO;AACT;;AAGA,SAAgB,YAAY,UAAkB,EAAE,SAAS,QAAQ,QAAmC;CAElG,IAAI,SAAS,WAAW,IAAI,GAC1B,OAAO,WAAW,SAAS,QAAQ,MAAS,CAAC,CAAC,KAAK,MAAM,QAAQ,CAAC;CAIpE,MAAM,mBAAmB,SAAS,QAAQ,SAAS,EAAE;CACrD,OAAO,WAAW,SAAS,QAAQ,IAAI,CAAC,CAAC,gBAAgB;AAC3D;;;;AC3JA,MAAM,YAAY;CAChB,gBAAgB;CAChB,eAAe;CACf,YAAY;CACZ,QAAQ;CACR,OAAO;EACL,SAAS,MAAM;EACf,OAAO,MAAM;EACb,OAAO,MAAM;EACb,SAAS,MAAM;EACf,SAAS,MAAM;EACf,MAAM,MAAM;EACZ,KAAK,MAAM;EACX,KAAK,MAAM;EACX,QAAQ,MAAM;CAChB;AACF;AAEA,SAAgB,UAAU,GAAG,iBAA2B;CACtD,SAAS,IAAI,GAAG,UAAqB;EACnC,QAAQ,IAAI,eAAe,OAAO,UAAU,MAAM,GAAG,GAAG,GAAG,iBAAiB,GAAG,QAAQ;CACzF;CAEA,IAAI,QAAQ,GAAG,aAAuB;EACpC,aAAa,WAAW,UAAU,MAAM,SAAS,GAAG,iBAAiB,GAAG,QAAQ;CAClF;CAEA,IAAI,WAAW,GAAG,aAAuB;EACvC,aAAa,WAAW,UAAU,MAAM,SAAS,GAAG,iBAAiB,GAAG,QAAQ;CAClF;CAEA,IAAI,SAAS,GAAG,aAAuB;EACrC,aAAa,SAAS,UAAU,MAAM,OAAO,GAAG,iBAAiB,GAAG,QAAQ;CAC9E;CAEA,IAAI,SAAS,GAAG,aAAuB;EACrC,aAAa,SAAS,UAAU,MAAM,OAAO,GAAG,iBAAiB,GAAG,QAAQ;EAG5E,QAAQ,KAAK,CAAC;CAChB;CAEA,IAAI,QAAQ,GAAG,aAAuB;EACpC,aAAa,QAAQ,UAAU,MAAM,MAAM,GAAG,iBAAiB,GAAG,QAAQ;CAC5E;CAEA,IAAI,OAAO,GAAG,aAAuB;EACnC,aAAa,OAAO,UAAU,MAAM,KAAK,GAAG,iBAAiB,GAAG,QAAQ;CAC1E;CAEA,IAAI,SAAS,GAAG,aAAuB;EACrC,IAAI,CAAC,UAAU,gBAAgB;EAE/B,MAAM,SAAS,gBAAgB,OAAO,QAAQ,CAAC,CAAC,KAAK,GAAG;EACxD,IAAI,UAAU,iBAAiB,CAAC,UAAU,cAAc,KAAK,MAAM,GAAG;EAEtE,aAAa,SAAS,UAAU,MAAM,SAAS,MAAM;CACvD;CAEA,IAAI,iBAAiB,cAAuB;EAC1C,UAAU,iBAAiB;CAC7B;CAEA,IAAI,oBAAoB,WAAmB;EACzC,UAAU,gBAAgB;CAC5B;CAEA,OAAO;AACT;;;;;;;;;;;;AAaA,MAAa,MAAM,UAAU;AAE7B,SAAS,eAAe,OAAe,OAAsB;CAC3D,MAAM,QAAQ,UAAU;CACxB,MAAM,gBAAgB,MAAM,UAAU,QAAQ,KAAK,QAAQ,MAAM,UAAU;CAC3E,MAAM,eAAe,IAAI,OAAO,aAAa;CAC7C,MAAM,aAAa,IAAI,OAAO,aAAa;CAE3C,QAAQ,eAAe,QAAQ;CAG/B,QAAQ,MAAM,OAAO,OAAO,GAAG;CAG/B,QAAQ,MAAM,QAAQ,GAAG;CAEzB,OAAO;AACT;AAEA,SAAS,aAAa,OAAe,OAAsB,GAAG,UAAoB;CAChF,MAAM,EAAE,gBAAgB,SAAS,mBAAmB,eAAe,QAAQ;CAC3E,MAAM,iBAAiB,eAAe,OAAO,KAAK;CAElD,MAAM,kBAAkB,QAAQ,MAAM,IAAI;CAE1C,IAAI,UAAU;CACd,KAAK,MAAM,CAAC,OAAO,mBAAmB,gBAAgB,QAAQ,GAAG;EAC/D,IAAI,QAAQ,GAAG;GACb,MAAM,QAAQ,UAAU,aAAa,UAAU,OAAO;GACtD,MAAM,SAAS,UAAU,OAAO,OAAO,KAAK,CAAC,CAAC,OAAO,UAAU,UAAU;GACzE,WAAW,OAAO,MAAM,IAAI,SAAS,IAAI;EAC3C;EAEA,WAAW;CACb;CAEA,QAAQ,IAAI,iBAAiB,gBAAgB,SAAS,cAAc;AACtE;AAEA,SAAS,eAAe,OAAiB;CACvC,MAAM,UAAU,MAAM,KAAK,GAAG;CAG9B,IAAI,eAAe;CACnB,OAAO,eAAe,QAAQ,UAAU,QAAQ,iBAAiB,MAC/D;CAIF,IAAI,aAAa,QAAQ;CACzB,OAAO,aAAa,gBAAgB,QAAQ,aAAa,MAAM,MAC7D;CASF,OAAO;EALL,gBAAgB,QAAQ,MAAM,GAAG,KAAK,IAAI,GAAG,YAAY,CAAC;EAC1D,SAAS,QAAQ,MAAM,cAAc,UAAU;EAC/C,gBAAgB,QAAQ,MAAM,KAAK,IAAI,GAAG,UAAU,CAAC;CAG1C;AACf;;;;ACjIA,MAAa,oBAAoB,OAAO,OAAO;;AAE7C,YAAY,mBACd,CAAC;AAED,MAAa,mBAAmB"}