@sdeverywhere/create 0.2.26 → 0.2.27

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/step-code-format.ts","../src/step-config.ts","../src/step-deps.ts","../src/step-directory.ts","../src/step-emsdk.ts","../src/step-git.ts","../src/step-mdl.ts","../src/step-template.ts"],"sourcesContent":["// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { relative, resolve as resolvePath } from 'path'\n\nimport { bgCyan, black, bold, cyan, dim, green } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport detectPackageManager from 'which-pm-runs'\nimport yargs from 'yargs-parser'\n\nimport { chooseCodeFormat } from './step-code-format'\nimport { chooseGenConfig, generateSampleYamlFiles, updateSdeConfig } from './step-config'\nimport { chooseInstallDeps } from './step-deps'\nimport { chooseProjectDir } from './step-directory'\nimport { chooseInstallEmsdk } from './step-emsdk'\nimport { chooseGitInit } from './step-git'\nimport { chooseMdlFile } from './step-mdl'\nimport { chooseTemplate } from './step-template'\n\nexport async function main(): Promise<void> {\n // Detect the package manager\n const pkgManager = detectPackageManager()?.name || 'npm'\n\n // Parse command line arguments\n const args = yargs(process.argv)\n prompts.override(args)\n\n if (args.dryRun) {\n console.log()\n ora().info(dim(`--dry-run enabled, no files will be written.`))\n }\n\n // Display welcome message\n console.log(`\\n${bold('Welcome to SDEverywhere!')}`)\n console.log(`Let's create a new SDEverywhere project for your model.\\n`)\n\n // Prompt the user to select a project directory\n const projDir = await chooseProjectDir(args)\n console.log()\n\n // See if there is a pre-existing `config` directory\n const configDirExisted = existsSync(resolvePath(projDir, 'config'))\n\n // Prompt the user to select a template\n const templateName = await chooseTemplate(projDir, args, pkgManager)\n console.log()\n\n // Prompt the user to select an mdl file\n const mdlPath = await chooseMdlFile(projDir)\n console.log()\n\n // Prompt the user to select a code generation format\n const genFormat = await chooseCodeFormat()\n\n // Update the `sde.config.js` file to use the chosen mdl file and\n // generate sample `checks.yaml` and `comparisons.yaml` files\n if (!args.dryRun) {\n await updateSdeConfig(projDir, mdlPath, genFormat)\n await generateSampleYamlFiles(projDir)\n }\n console.log()\n\n // If the user chose the default template, and there isn't already an\n // existing `config` directory, offer to set up CSV files\n if (templateName === 'template-default') {\n if (configDirExisted) {\n ora().succeed(`Found existing \"${bold('config')}\" directory.`)\n ora().info(\n dim(`You can edit the files in the \"${cyan('config')}\" directory later to configure graphs and sliders.`)\n )\n console.log()\n } else {\n if (!args.dryRun) {\n await chooseGenConfig(projDir, mdlPath)\n console.log()\n }\n }\n }\n\n // If the user chose C as the code generation format, prompt the user to\n // install Emscripten SDK\n if (genFormat === 'c') {\n await chooseInstallEmsdk(projDir, args)\n console.log()\n }\n\n // Prompt the user to install dependencies\n await chooseInstallDeps(projDir, args, pkgManager)\n console.log()\n\n // Prompt the user to initialize a git repo\n await chooseGitInit(projDir, args)\n console.log()\n\n ora(green('Setup complete!')).succeed()\n\n console.log(`\\n${bgCyan(black(' Next steps '))}\\n`)\n\n const relProjDir = relative(process.cwd(), projDir)\n const devCmd = pkgManager === 'npm' ? 'npm run dev' : `${pkgManager} dev`\n\n // If the project dir is the current dir, no need to tell users to cd\n if (relProjDir !== '') {\n console.log(`You can now ${bold(cyan('cd'))} into the ${bold(cyan(relProjDir))} project directory.`)\n }\n console.log(`Run ${bold(cyan(devCmd))} to start the local dev server. ${bold(cyan('CTRL-C'))} to close.`)\n console.log('')\n}\n","// Copyright (c) 2024 Climate Interactive / New Venture Fund\n\nimport { bold, dim, green } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\n\nconst promptMessage = `Would you like your project to use WebAssembly?`\n\nconst noDesc = `\\\n* Choose this if you want to get started using SDEverywhere quickly\nand you don't want to install the Emscripten SDK.\n* This will generate a model that uses JavaScript code only, which\ndoesn't require extra build tools, but runs slower than WebAssembly.`\nconst yesDesc = `\\\n* Choose this if you want this script to install the Emscripten SDK\nfor you, or if you already have it installed.\n* This will generate a model that uses WebAssembly, which requires an\nadditional build step, but runs faster than pure JavaScript code.`\n\nconst FORMATS = [\n {\n title: 'No, generate a JavaScript model',\n description: noDesc,\n value: 'js'\n },\n {\n title: 'Yes, generate a WebAssembly model',\n description: yesDesc,\n value: 'c'\n }\n]\n\nexport async function chooseCodeFormat(): Promise<string> {\n // Prompt the user\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'format',\n message: promptMessage,\n choices: FORMATS\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n const target = options.format === 'c' ? 'WebAssembly' : 'JavaScript'\n const successMessage = green(\n `Configuring your project to generate ${target}. See \"${bold('sde.config.js')}\" for details.`\n )\n ora(successMessage).succeed()\n\n return options.format\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { mkdir, readFile, writeFile } from 'fs/promises'\nimport { dirname, join as joinPath, parse as parsePath, relative, resolve as resolvePath } from 'path'\n\nimport { bold, cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport type { Choice } from 'prompts'\nimport prompts from 'prompts'\n\nimport { parseAndGenerate } from '@sdeverywhere/compile'\n\ninterface MdlConstVariable {\n kind: 'const'\n name: string\n value: number\n}\n\ninterface MdlAuxVariable {\n kind: 'aux'\n name: string\n}\n\ninterface MdlLevelVariable {\n kind: 'level'\n name: string\n}\n\ntype MdlVariable = MdlConstVariable | MdlAuxVariable | MdlLevelVariable\n\nconst sampleChecksContent = `\\\n# yaml-language-server: $schema=SCHEMA_PATH\n\n#\n# This file contains \"check\" tests that exercise your model under different input\n# scenarios. For more guidance, consult this wiki page:\n# https://github.com/climateinteractive/SDEverywhere/wiki/Testing-and-Comparing-Your-Model\n#\n\n# NOTE: The following is an example of a simple check just to get you started.\n# Replace \"Some output\" with the name of some variable you'd like to test.\n- describe: Some output\n tests:\n - it: should be > 0 for all input scenarios\n scenarios:\n - preset: matrix\n datasets:\n - name: Some output\n predicates:\n - gt: 0\n`\n\nconst sampleComparisonsContent = `\\\n# yaml-language-server: $schema=SCHEMA_PATH\n\n#\n# This file contains definitions of custom comparison scenarios, which allow you to see\n# how the behavior of the model compares to that of previous versions. For more guidance,\n# consult the following wiki page:\n# https://github.com/climateinteractive/SDEverywhere/wiki/Testing-and-Comparing-Your-Model\n#\n\n# NOTE: The following is an example of a custom scenario just to get you started.\n# Replace \"Some input\" and \"Another input\" with the names of some variables you'd\n# like to test.\n- scenario:\n title: Custom scenario\n subtitle: gradual ramp-up\n with:\n - input: Some input\n at: 10\n - input: Another input\n at: 20\n`\n\nexport async function updateSdeConfig(projDir: string, mdlPath: string, genFormat: string): Promise<void> {\n // Read the `sde.config.js` file from the template\n const configPath = joinPath(projDir, 'sde.config.js')\n let configText = await readFile(configPath, 'utf8')\n\n // Set the code generation format to the chosen format\n configText = configText.replace(`const genFormat = 'js'`, `const genFormat = '${genFormat}'`)\n\n // Replace instances of `MODEL_NAME.mdl` with the path to the chosen mdl file\n configText = configText.replaceAll('MODEL_NAME.mdl', mdlPath)\n\n // Write the updated file\n await writeFile(configPath, configText)\n}\n\nasync function generateYaml(projDir: string, kind: 'checks' | 'comparisons', template: string): Promise<void> {\n const yamlDir = joinPath(projDir, 'model', kind)\n const yamlPath = joinPath(yamlDir, `${kind}.yaml`)\n if (!existsSync(yamlPath)) {\n // Get relative path from yaml file parent dir to project dir\n let relProjPath = relative(dirname(yamlPath), projDir)\n if (relProjPath.length === 0) {\n relProjPath = './'\n }\n\n // Create the directory for the yaml file, if needed\n await mkdir(yamlDir, { recursive: true })\n\n // TODO: This path is normally different depending on whether using npm/yarn or\n // pnpm. For npm/yarn, `check-core` is hoisted under top-level `node_modules`,\n // but for pnpm, it is nested under `node_modules/.pnpm`. As an ugly workaround\n // the templates declare `check-core` as a direct dependency even though it is\n // not really needed (a transitive dependency via `plugin-check` would normally\n // suffice). This allows us to use the same path here that works for all\n // three package managers.\n const nodeModulesPart = joinPath(relProjPath, 'node_modules')\n const schemaName = kind === 'checks' ? 'check' : 'comparison'\n const checkCorePart = `@sdeverywhere/check-core/schema/${schemaName}.schema.json`\n const schemaPath = `${nodeModulesPart}/${checkCorePart}`\n const yamlContent = template.replace('SCHEMA_PATH', schemaPath)\n await writeFile(yamlPath, yamlContent)\n }\n}\n\nexport async function generateSampleYamlFiles(projDir: string): Promise<void> {\n // Generate a sample `checks.yaml` file if one doesn't already exist\n await generateYaml(projDir, 'checks', sampleChecksContent)\n\n // Generate a sample `comparisons.yaml` file if one doesn't already exist\n await generateYaml(projDir, 'comparisons', sampleComparisonsContent)\n}\n\nexport async function chooseGenConfig(projDir: string, mdlPath: string): Promise<void> {\n // TODO: For now we eagerly read the mdl file; maybe change this to only load it if\n // the user chooses to generate graph and/or slider config\n let mdlVars: MdlVariable[]\n try {\n // Get the list of variables available in the model\n mdlVars = await readModelVars(projDir, mdlPath)\n } catch (e) {\n console.log(e)\n ora(\n yellow('The mdl file failed to load. We will continue setting things up, and you can diagnose the issue later.')\n ).warn()\n return\n }\n\n // Extract `INITIAL TIME` and `FINAL TIME` values and remove special control variables from the list\n let initialTime: number\n let finalTime: number\n const validVars: MdlVariable[] = []\n for (const v of mdlVars) {\n const varName = v.name.toLowerCase()\n let skip = false\n switch (varName) {\n case 'final time':\n skip = true\n if (v.kind === 'const') {\n finalTime = v.value\n }\n break\n case 'initial time':\n skip = true\n if (v.kind === 'const') {\n initialTime = v.value\n }\n break\n case 'saveper':\n case 'time':\n case 'time step':\n skip = true\n break\n default:\n break\n }\n if (!skip) {\n validVars.push(v)\n }\n }\n\n // Set the values in `model.csv`\n if (initialTime === undefined) {\n initialTime = 0\n }\n if (finalTime === undefined) {\n finalTime = 100\n }\n\n // TODO: Auto-detect dat files that are referenced by the mdl and include them here\n const datFiles: string[] = []\n const datPart = datFiles.join(';')\n\n // Preserve the `model.csv` header but drop other existing content (if any)\n const modelCsvFile = joinPath(projDir, 'config', 'model.csv')\n const origModelCsvContent = await readFile(modelCsvFile, 'utf8')\n const modelCsvHeader = origModelCsvContent.split('\\n')[0]\n\n // Disable bundled listing and customization features by default\n const bundleListing = 'false'\n const customLookups = 'false'\n const customOutputs = 'false'\n\n // Add line and write out updated `model.csv`\n const modelCsvLine = `${initialTime},${finalTime},${datPart},${bundleListing},${customLookups},${customOutputs}`\n const newModelCsvContent = `${modelCsvHeader}\\n${modelCsvLine}\\n`\n await writeFile(modelCsvFile, newModelCsvContent)\n\n // See if the user wants to generate graph config\n await chooseGenGraphConfig(projDir, validVars)\n console.log()\n\n // See if the user wants to generate slider config\n await chooseGenSliderConfig(projDir, validVars)\n}\n\nasync function chooseGenGraphConfig(projDir: string, mdlVars: MdlVariable[]): Promise<void> {\n // Prompt the user\n const genResponse = await prompts(\n {\n type: 'confirm',\n name: 'genGraph',\n message: `Would you like to configure a graph to get you started? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (!genResponse.genGraph) {\n ora().info(dim(`No problem! You can edit the \"${cyan('config/graphs.csv')}\" file later.`))\n return\n }\n\n // Offer multi-select with available output variables\n const outputVarNames: string[] = []\n for (const mdlVar of mdlVars) {\n if (mdlVar.kind === 'aux' || mdlVar.kind === 'level') {\n outputVarNames.push(mdlVar.name)\n }\n }\n outputVarNames.sort((a, b) => {\n return a.toLowerCase().localeCompare(b.toLowerCase())\n })\n const choices = outputVarNames.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n const varsResponse = await prompts(\n {\n type: 'autocompleteMultiselect',\n name: 'vars',\n message: 'Choose up to three output variables to display in the graph',\n choices,\n max: 3\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n if (varsResponse.vars.length === 0) {\n ora().info(dim(`No variables selected. You can edit the \"${cyan('config/graphs.csv')}\" file later.`))\n return\n }\n\n // Add line to `graphs.csv`\n const graphsCsvFile = joinPath(projDir, 'config', 'graphs.csv')\n const csvLine = graphsCsvLine(varsResponse.vars)\n let graphsCsvContent = await readFile(graphsCsvFile, 'utf8')\n graphsCsvContent += `${csvLine}\\n`\n await writeFile(graphsCsvFile, graphsCsvContent)\n\n ora(\n green(`Added graph to \"${bold('config/graphs.csv')}\". ${dim('You can configure graphs in that file later.')}`)\n ).succeed()\n}\n\n// TODO: Ideally the `plugin-config` package would expose an API for generating CSV, but\n// until then, we will generate a comma-separated line of values in hardcoded fashion\nfunction graphsCsvLine(outputVarNames: string[]): string {\n const colors = ['blue', 'red', 'green']\n\n // Fill the line with blanks initially, then set the small subset of fields\n const a = Array(131).fill('')\n // id\n a[0] = '1'\n // parent menu\n a[2] = 'Graphs'\n // graph title\n a[3] = 'Graph Title'\n // kind\n a[7] = 'line'\n // Plots start at 26\n let index = 26\n let colorIndex = 0\n for (const outputVarName of outputVarNames) {\n // Surround the name in quotes if it contains a comma\n const escapedName = escapeCsvField(outputVarName)\n // plot N variable\n a[index + 0] = escapedName\n // plot N style\n a[index + 2] = 'line'\n // plot N label\n a[index + 3] = escapedName\n // plot N color\n a[index + 4] = colors[colorIndex]\n index += 7\n colorIndex++\n }\n\n return a.join(',')\n}\n\nasync function chooseGenSliderConfig(projDir: string, mdlVars: MdlVariable[]): Promise<void> {\n // Prompt the user\n const genResponse = await prompts(\n {\n type: 'confirm',\n name: 'genSliders',\n message: `Would you like to configure a few sliders to get you started? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (!genResponse.genSliders) {\n ora().info(dim(`No problem! You can edit the \"${cyan('config/inputs.csv')}\" file later.`))\n return\n }\n\n // Offer multi-select with available input variables\n const inputVarNames: string[] = []\n for (const mdlVar of mdlVars) {\n if (mdlVar.kind === 'const') {\n inputVarNames.push(mdlVar.name)\n }\n }\n inputVarNames.sort((a, b) => {\n return a.toLowerCase().localeCompare(b.toLowerCase())\n })\n const choices = inputVarNames.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n const varsResponse = await prompts(\n {\n type: 'autocompleteMultiselect',\n name: 'vars',\n message: 'Choose up to three input variables to control with sliders',\n choices,\n max: 3\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n if (varsResponse.vars.length === 0) {\n ora().info(dim(`No variables selected. You can edit the \"${cyan('config/inputs.csv')}\" file later.`))\n return\n }\n\n // Add lines to `inputs.csv`\n const inputsCsvFile = joinPath(projDir, 'config', 'inputs.csv')\n let inputsCsvContent = await readFile(inputsCsvFile, 'utf8')\n let idNumber = 1\n for (const inputVarName of varsResponse.vars) {\n const inputVar = mdlVars.find(v => v.name === inputVarName)\n if (inputVar && inputVar.kind === 'const') {\n const defaultValue = inputVar.value\n const csvLine = inputsCsvLine(inputVarName, defaultValue, idNumber.toString())\n inputsCsvContent += `${csvLine}\\n`\n idNumber++\n }\n }\n await writeFile(inputsCsvFile, inputsCsvContent)\n\n const slidersText = varsResponse.vars.length > 1 ? 'sliders' : 'sliders'\n ora(\n green(\n `Added ${slidersText} to \"${bold('config/inputs.csv')}\". ${dim('You can configure sliders in that file later.')}`\n )\n ).succeed()\n}\n\n// TODO: Ideally the `plugin-config` package would expose an API for generating CSV, but\n// until then, we will generate a comma-separated line of values in hardcoded fashion\nfunction inputsCsvLine(inputVarName: string, defaultValue: number, id: string): string {\n // Surround the name in quotes if it contains a comma\n const escapedName = escapeCsvField(inputVarName)\n\n // TODO: Be smarter about automatically choosing min/max/step values\n const minValue = defaultValue - 1\n const maxValue = defaultValue + 1\n const step = 0.1\n\n // Fill the line with blanks initially, then set the small subset of fields\n const a = Array(28).fill('')\n // id\n a[0] = id\n // input type\n a[1] = 'slider'\n // viewid\n a[2] = 'view1'\n // varname\n a[3] = escapedName\n // label\n a[4] = escapedName\n // group name\n a[6] = 'Sliders'\n // slider min\n a[7] = minValue\n // slider max\n a[8] = maxValue\n // slider default\n a[9] = defaultValue\n // slider step\n a[10] = step\n // units\n a[11] = '(units)'\n\n return a.join(',')\n}\n\nfunction escapeCsvField(s: string): string {\n // Surround the value in quotes if it contains a comma\n // TODO: Escape double quotes as well\n return s.includes(',') ? `\"${s}\"` : s\n}\n\nasync function readModelVars(projDir: string, mdlPath: string): Promise<MdlVariable[]> {\n // TODO: This function contains a subset of the logic from `sde-generate.js` in\n // the `cli` package; should revisit\n // let { modelDirname, modelName, modelPathname } = modelPathProps(model)\n\n // Ensure the `build` directory exists (under the `sde-prep` directory)\n const buildDir = resolvePath(projDir, 'sde-prep', 'build')\n await mkdir(buildDir, { recursive: true })\n\n // Use an empty model spec; this will make SDE look at all variables in the mdl\n const spec = {}\n\n // Try parsing the mdl file to generate the list of variables\n // TODO: This depends on some `compile` package APIs that are not yet considered stable.\n // Ideally we'd use an API that does not write files but instead returns an in-memory\n // object in a specified format.\n\n // Read the model file\n const mdlFile = resolvePath(projDir, mdlPath)\n const mdlContent = await readFile(mdlFile, 'utf8')\n\n // Parse the model and generate the variable list\n const mdlDir = dirname(mdlFile)\n const mdlName = parsePath(mdlFile).name\n await parseAndGenerate(mdlContent, spec, ['printVarList'], mdlDir, mdlName, buildDir)\n\n // Read `build/{mdl}.json`\n const jsonListFile = joinPath(buildDir, `${mdlName}.json`)\n const jsonListContent = await readFile(jsonListFile, 'utf8')\n const jsonList = JSON.parse(jsonListContent)\n const varObjs = jsonList.variables\n\n // Create a simplified array of variables\n const mdlVars: MdlVariable[] = []\n for (const varObj of varObjs) {\n // Only include certain variables for now\n // TODO: Include \"data\" vars\n switch (varObj.varType) {\n case 'const':\n mdlVars.push({\n kind: 'const',\n name: varObj.modelLHS,\n value: Number.parseFloat(varObj.modelFormula)\n })\n break\n case 'aux':\n mdlVars.push({\n kind: 'aux',\n name: varObj.modelLHS\n })\n break\n case 'level':\n mdlVars.push({\n kind: 'level',\n name: varObj.modelLHS\n })\n break\n default:\n break\n }\n }\n\n return mdlVars\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { execa } from 'execa'\nimport { bold, cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseInstallDeps(projDir: string, args: Arguments, pkgManager: string): Promise<void> {\n // Prompt the user\n const installResponse = await prompts(\n {\n type: 'confirm',\n name: 'install',\n message: `Would you like to install ${pkgManager} dependencies? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(\n dim('Operation cancelled. Your project folder has been created, but no dependencies have been installed.')\n )\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (!installResponse.install) {\n ora().info(dim(`No problem! Remember to install dependencies after setup.`))\n return\n }\n\n // Install dependencies\n const installExec = execa(pkgManager, ['install'], { cwd: projDir })\n const installingPackagesMsg = 'Installing packages...'\n const installSpinner = ora(installingPackagesMsg).start()\n try {\n await new Promise<void>((resolve, reject) => {\n installExec.stdout?.on('data', function (data) {\n installSpinner.text = `${installingPackagesMsg}\\n${bold(`[${pkgManager}]`)} ${data}`\n })\n installExec.stderr?.on('data', function (data) {\n installSpinner.text = `${installingPackagesMsg}\\n${bold(`[${pkgManager}]`)} ${data}`\n })\n installExec.on('error', error => reject(error))\n installExec.on('close', code => {\n if (code !== 0) {\n reject(`Install failed (code=${code})`)\n } else {\n resolve()\n }\n })\n })\n installSpinner.text = green('Packages installed!')\n installSpinner.succeed()\n } catch {\n installSpinner.text = yellow(\n `There was an error installing packages. Try running ${cyan(\n `${pkgManager} install`\n )} in your project directory later.`\n )\n installSpinner.warn()\n }\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { resolve as resolvePath } from 'path'\n\nimport { bold, dim, green, red } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseProjectDir(args: Arguments): Promise<string> {\n /**\n * Return true if the given directory does not exist, or it does not contain important files\n * like `package.json`.\n */\n function isValidDir(dir: string): boolean {\n const packageJson = resolvePath(dir, 'package.json')\n const packagesDir = resolvePath(dir, 'packages')\n return !existsSync(dir) || (!existsSync(packageJson) && !existsSync(packagesDir))\n }\n\n const showValidDirMsg = (dir: string) => {\n ora(green(`Using \"${bold(dir)}\" as the project directory.`)).succeed()\n }\n\n const showInvalidDirMsg = (dir: string) => {\n ora(red(`\"${bold(dir)}\" contains existing 'package.json' and/or 'packages' directory, stopping.`)).fail()\n }\n\n // See if project directory is provided on command line\n let projDir = args['_'][2] as string\n if (projDir) {\n // Directory was provided, see if it is valid\n if (isValidDir(projDir)) {\n // The provided directory is valid, so proceed\n showValidDirMsg(projDir)\n } else {\n // The provided directory is not valid, so show error message and exit\n showInvalidDirMsg(projDir)\n process.exit(0)\n }\n } else {\n // Directory was not provided, so prompt the user\n const dirResponse = await prompts(\n {\n type: 'text',\n name: 'directory',\n message: 'Where would you like to create your new project?',\n initial: '<current directory>'\n // validate(value) {\n // if (value === '<current directory>') {\n // value = process.cwd()\n // }\n // if (!isValidDir(value)) {\n // return notValidMsg(value)\n // }\n // return true\n // }\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n projDir = dirResponse.directory\n if (projDir === '<current directory>') {\n projDir = process.cwd()\n }\n if (isValidDir(projDir)) {\n showValidDirMsg(projDir)\n } else {\n showInvalidDirMsg(projDir)\n process.exit(0)\n }\n }\n\n return projDir\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync, rmSync } from 'fs'\nimport { join as joinPath, resolve as resolvePath } from 'path'\n\nimport { execa } from 'execa'\nimport { findUp } from 'find-up'\nimport { bold, cyan, dim, green, red } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\n// TODO: Make this configurable; we're using this older version for now because it is\n// relatively stable and has been used to build En-ROADS and C-ROADS for a long time\nconst version = '2.0.34'\n\nexport async function chooseInstallEmsdk(projDir: string, args: Arguments): Promise<void> {\n // Walk up the directory structure to see if there is an existing `emsdk` directory\n const existingEmsdkDir = await findUp('emsdk', {\n cwd: projDir,\n type: 'directory'\n })\n if (existingEmsdkDir) {\n ora().succeed('Found existing Emscripten SDK installation.')\n ora().info(dim(`Your project will use \"${cyan(existingEmsdkDir)}\".`))\n return\n }\n\n // Prompt the user\n const underParentDir = resolvePath(projDir, '..', 'emsdk')\n const underProjDir = joinPath(projDir, 'emsdk')\n const installResponse = await prompts(\n {\n type: 'select',\n name: 'install',\n message: `Would you like to install the Emscripten SDK that is used to generate WebAssembly?`,\n choices: [\n // ${reset(dim('(recommended)'))\n {\n title: `Install under parent directory (${bold(underParentDir)})`,\n description: 'This is recommended so that it can be shared by multiple projects',\n value: 'parent'\n },\n {\n title: `Install under project directory (${bold(underProjDir)})\"`,\n description: 'This is useful for keeping everything under a single project directory',\n value: 'project'\n },\n {\n title: `Don't install`,\n description: `It's OK, you can install it later`,\n value: 'skip'\n }\n ]\n },\n {\n onCancel: () => {\n ora().info(\n dim(\n 'Operation cancelled. Your project folder has been created, but the Emscripten SDK and other dependencies have not been installed.'\n )\n )\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (installResponse.install === 'skip') {\n ora().info(\n dim(\n `No problem! Be sure to install the Emscripten SDK and configure it in \"${cyan('sde.config.js')}\" after setup.`\n )\n )\n return\n }\n\n const installDir = installResponse.install === 'parent' ? underParentDir : underProjDir\n try {\n // TODO: Use spinner here\n await installEmscripten(installDir)\n } catch (e) {\n ora(red(`Failed to install Emscripten SDK: ${e.message}`)).fail()\n process.exit(0)\n }\n\n ora(green(`Installed the Emscripten SDK in \"${bold(installDir)}\"`)).succeed()\n}\n\n/**\n * Install the Emscripten SDK to the `emsdk` directory under the\n * given directory (if `emsdk` is not already present), then\n * activates the requested version (specified with `version`).\n *\n * The implementation is similar to the existing `setup-emsdk` action\n * (https://github.com/mymindstorm/setup-emsdk) except that one has issues\n * with the cache directory on Windows, so having our own script gives us\n * more control over installation and caching behavior.\n */\nasync function installEmscripten(emsdkDir: string /*, options?: { verbose?: boolean }*/): Promise<void> {\n // Only download if the emsdk directory wasn't restored from a cache\n if (!existsSync(emsdkDir)) {\n console.log(`Downloading Emscripten SDK to ${emsdkDir}`)\n // console.log()\n await execa('git', ['clone', 'https://github.com/emscripten-core/emsdk.git', emsdkDir])\n } else {\n console.log(`Found existing Emscripten SDK directory: ${emsdkDir}`)\n }\n // console.log()\n\n if (process.env.CI) {\n // On GitHub Actions, remove the `.git` directory to keep the cache smaller.\n // When we update to a new version, the cache key will miss and the emsdk\n // repo will be redownloaded.\n console.log('CI detected, removing .git directory...')\n const gitDir = joinPath(emsdkDir, '.git')\n rmSync(gitDir, { recursive: true, force: true })\n } else {\n // For local development, pull to get the latest\n console.log('Local development detected, performing git pull...')\n await execa('git', ['pull'], { cwd: emsdkDir })\n // console.log()\n }\n\n const emsdkCmd = async (...args: string[]) => {\n return execa('python3', ['emsdk.py', ...args], { cwd: emsdkDir })\n }\n\n console.log(`Activating Emscripten SDK ${version}...`)\n await emsdkCmd('install', version)\n await emsdkCmd('activate', version)\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { execaCommand } from 'execa'\nimport { cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseGitInit(projDir: string, args: Arguments): Promise<void> {\n // Prompt the user\n const gitResponse = await prompts(\n {\n type: 'confirm',\n name: 'git',\n message: `Would you like to initialize a new git repository? ${reset(dim('(optional)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled. Your project folder has already been created.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (!gitResponse.git) {\n ora().info(dim(`No problem! You can come back and run ${cyan(`git init`)} later.`))\n return\n }\n\n // Init git repo\n try {\n await execaCommand('git init', { cwd: projDir })\n ora().succeed(green('Git repository initialized!'))\n } catch {\n ora().warn(\n yellow(\n `There was a problem initializing the Git repository, but no problem, you can run ${cyan(`git init`)} later.`\n )\n )\n }\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { readdir, writeFile } from 'fs/promises'\nimport { join as joinPath, relative, resolve as resolvePath, sep, posix } from 'path'\n\nimport { bold, cyan, dim, green, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport type { Choice } from 'prompts'\nimport prompts from 'prompts'\n\nconst sampleMdlContent = `\\\n{UTF-8}\n\nX = TIME\n ~~|\n\nY = 0\n ~ [-10,10,0.1]\n ~\n |\n\nZ = X + Y\n ~~|\n\nINITIAL TIME = 2000 ~~|\nFINAL TIME = 2100 ~~|\nTIME STEP = 1 ~~|\nSAVEPER = TIME STEP ~~|\n`\n\nexport async function chooseMdlFile(projDir: string): Promise<string> {\n // Find all `.mdl` files in the project directory\n // From https://stackoverflow.com/a/45130990\n async function getFiles(dir: string): Promise<string[]> {\n const dirents = await readdir(dir, { withFileTypes: true })\n const files = await Promise.all(\n dirents.map(dirent => {\n const res = resolvePath(dir, dirent.name)\n return dirent.isDirectory() ? getFiles(res) : res\n })\n )\n return files.flat()\n }\n const allFiles = await getFiles(projDir)\n const mdlFiles = allFiles\n // Only include files ending with '.mdl'\n .filter(f => f.endsWith('.mdl'))\n // Convert to a relative path with POSIX path separators (we want\n // paths in the 'sde.config.js' file to use POSIX path style only,\n // since that works on any OS including Windows)\n .map(f => relative(projDir, f).replaceAll(sep, posix.sep))\n const mdlChoices = mdlFiles.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n\n let mdlFile: string\n if (mdlFiles.length === 0) {\n // No mdl files found; write a sample mdl to get the user started\n const sampleMdlFile = joinPath(projDir, 'sample.mdl')\n await writeFile(sampleMdlFile, sampleMdlContent)\n ora(\n yellow(\n `No mdl files were found in \"${projDir}\". A \"${cyan(\n 'sample.mdl'\n )}\" file has been added to the project to get you started.`\n )\n ).warn()\n mdlFile = 'sample.mdl'\n } else if (mdlFiles.length === 1) {\n // Only one mdl file\n ora().succeed(`Found \"${mdlFiles[0]}\", will configure the project to use that mdl file.`)\n mdlFile = mdlFiles[0]\n } else {\n // Multiple mdl files found; allow the user to choose one\n // TODO: Eventually we should allow the user to choose to flatten if there are multiple submodels\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'mdlFile',\n message: 'It looks like there are multiple mdl files. Which one would you like to use?',\n choices: mdlChoices\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n mdlFile = options.mdlFile\n }\n\n ora(green(`Using \"${bold(mdlFile)}\" as the model for the project.`)).succeed()\n\n return mdlFile\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync, mkdtempSync, readdirSync, rmSync } from 'fs'\nimport { writeFile } from 'fs/promises'\nimport { copy } from 'fs-extra'\nimport { tmpdir } from 'os'\nimport { join as joinPath } from 'path'\n\nimport { downloadTemplate } from 'giget'\nimport { dim, green, red, yellow } from 'kleur/colors'\nimport type { Ora } from 'ora'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nconst TEMPLATES = [\n {\n title: 'Default project',\n description: 'Includes recommended structure with config files, app, core library, model-check, etc',\n value: 'template-default'\n },\n {\n title: 'Minimal project',\n description: 'Includes simple config for model-check',\n value: 'template-minimal'\n }\n]\n\nexport async function chooseTemplate(projDir: string, args: Arguments, pkgManager: string): Promise<string> {\n // Prompt the user\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'template',\n message: 'Which template would you like to use?',\n choices: TEMPLATES\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n }\n\n // Allow branch name or commit hash to be overridden on command line\n const defaultRev = 'main'\n const commit = args.commit || defaultRev\n\n // Copy the template files to the project directory\n const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}#${commit}`\n const templateSpinner = ora('Copying project files...').start()\n await copyTemplate(templateTarget, projDir, templateSpinner)\n templateSpinner.text = green('Template copied!')\n templateSpinner.succeed()\n\n if (options.template === 'template-default' && pkgManager === 'pnpm') {\n // pnpm doesn't use the \"workspaces\" config from `package.json` (like npm and yarn use),\n // so in the case of pnpm, write a `pnpm-workspace.yaml` file so that the default\n // template monorepo layout is set up correctly\n const workspaceFile = joinPath(projDir, 'pnpm-workspace.yaml')\n const workspaceContent = `packages:\\n - packages/*\\n`\n await writeFile(workspaceFile, workspaceContent)\n }\n\n return options.template\n}\n\nasync function copyTemplate(templateTarget: string, dstDir: string, spinner: Ora): Promise<void> {\n try {\n // Make giget write to a temporary directory\n const tmpDir = mkdtempSync(joinPath(tmpdir(), 'sde-create-'))\n\n // Use giget to download the template (we will be writing to a temporary directory,\n // so `force` is safe)\n await downloadTemplate(`github:${templateTarget}`, {\n force: true,\n provider: 'github',\n dir: tmpDir\n })\n\n // In case giget doesn't return an error when an invalid template is provided, check\n // that the temporary directory is non-empty\n if (!existsSync(tmpDir) || readdirSync(tmpDir).length === 0) {\n throw new Error('Failed to download the requested template: the temporary directory is empty.')\n }\n\n // Copy files to destination without overwriting\n await copy(tmpDir, dstDir, {\n overwrite: false,\n errorOnExist: false\n })\n\n // Remove the temporary directory\n rmSync(tmpDir, { recursive: true, force: true })\n } catch (e) {\n // The download failed; show an error message\n // TODO: Handle common download issues; for now, just log the error message and exit\n spinner.fail()\n console.error(red(e.message))\n console.error(yellow('\\nThere was a problem copying the template.'))\n console.error(\n yellow(\n 'Please start a new discussion thread and include the command output so that we can help:\\n https://github.com/climateinteractive/SDEverywhere/discussions/categories/q-a\\n'\n )\n )\n process.exit(0)\n }\n}\n"],"mappings":"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","names":["import_fs","import_path","import_colors","import_ora","import_prompts","prompts","ora","import_colors","import_ora","import_prompts","joinPath","ora","prompts","resolvePath","parsePath","import_colors","import_ora","import_prompts","prompts","ora","import_fs","import_path","import_colors","import_ora","import_prompts","resolvePath","ora","prompts","import_fs","import_path","import_execa","import_colors","import_ora","import_prompts","ora","resolvePath","joinPath","prompts","import_execa","import_colors","import_ora","import_prompts","prompts","ora","import_promises","import_path","import_colors","import_ora","import_prompts","resolvePath","joinPath","ora","prompts","import_fs","import_promises","import_path","import_colors","import_ora","import_prompts","prompts","ora","joinPath","detectPackageManager","yargs","prompts","ora","resolvePath"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/step-code-format.ts","../src/step-config.ts","../src/step-deps.ts","../src/step-directory.ts","../src/step-emsdk.ts","../src/step-git.ts","../src/step-mdl.ts","../src/step-template.ts"],"sourcesContent":["// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { posix, relative, resolve as resolvePath } from 'path'\n\nimport { bgCyan, black, bold, cyan, dim, green } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport detectPackageManager from 'which-pm-runs'\nimport yargs from 'yargs-parser'\n\nimport { chooseCodeFormat } from './step-code-format'\nimport { chooseGenConfig, generateSampleYamlFiles, updateSdeConfig } from './step-config'\nimport { chooseInstallDeps } from './step-deps'\nimport { chooseProjectDir } from './step-directory'\nimport { chooseInstallEmsdk } from './step-emsdk'\nimport { chooseGitInit } from './step-git'\nimport { chooseMdlFile } from './step-mdl'\nimport { chooseTemplate, copyTemplate } from './step-template'\n\nexport async function main(): Promise<void> {\n // Detect the package manager\n const pkgManager = detectPackageManager()?.name || 'npm'\n\n // Parse command line arguments\n const args = yargs(process.argv)\n prompts.override(args)\n\n if (args.dryRun) {\n console.log()\n ora().info(dim(`--dry-run enabled, no files will be written.`))\n }\n\n // Display welcome message\n console.log(`\\n${bold('Welcome to SDEverywhere!')}`)\n console.log(`Let's create a new SDEverywhere project for your model.\\n`)\n\n // Prompt the user to select a project directory\n const projDir = await chooseProjectDir(args)\n console.log()\n\n // See if there is a pre-existing `config` directory\n const configDirExisted = existsSync(resolvePath(projDir, 'config'))\n\n // Prompt the user to select a template\n const template = await chooseTemplate(args)\n console.log()\n\n // Prompt the user to select an mdl file\n let mdlPath = await chooseMdlFile(projDir)\n const mdlExisted = mdlPath !== undefined\n console.log()\n\n if (!args.dryRun) {\n // Copy the template files to the project directory\n await copyTemplate(template, projDir, pkgManager, configDirExisted, mdlExisted)\n console.log()\n }\n\n if (mdlPath === undefined) {\n // There wasn't already an mdl file in the project directory, so we will use\n // the one supplied by the template. The template is expected to have a\n // `model/MODEL_NAME.mdl` file, which gets renamed to `model/sample.mdl`\n // in the `copyTemplate` step. Note that `chooseMdlFile` returns a\n // POSIX-style relative path, so we will also use a relative path here.\n mdlPath = `model${posix.sep}sample.mdl`\n }\n\n // Prompt the user to select a code generation format\n const genFormat = await chooseCodeFormat()\n\n if (!args.dryRun) {\n // Update the `sde.config.js` file to use the chosen mdl file\n await updateSdeConfig(projDir, mdlPath, genFormat)\n\n // Generate sample `checks.yaml` and `comparisons.yaml` files if needed\n const modelCheckFilesExist =\n existsSync(resolvePath(projDir, 'model', 'checks')) || existsSync(resolvePath(projDir, 'model', 'comparisons'))\n if (!modelCheckFilesExist) {\n await generateSampleYamlFiles(projDir)\n }\n }\n console.log()\n\n if (configDirExisted) {\n // There was already a `config` directory, so don't offer to set up CSV files\n ora().succeed(`Found existing \"${bold('config')}\" directory.`)\n ora().info(\n dim(`You can edit the files in the \"${cyan('config')}\" directory later to configure graphs and sliders.`)\n )\n console.log()\n } else {\n // There wasn't already a `config` directory, but there was already an mdl file,\n // so offer to set up CSV files\n const configDirExistsNow = existsSync(resolvePath(projDir, 'config'))\n if (configDirExistsNow && mdlExisted && !args.dryRun) {\n await chooseGenConfig(projDir, mdlPath)\n console.log()\n }\n }\n\n // If the user chose C as the code generation format, prompt the user to\n // install Emscripten SDK\n if (genFormat === 'c') {\n await chooseInstallEmsdk(projDir, args)\n console.log()\n }\n\n // Prompt the user to install dependencies\n await chooseInstallDeps(projDir, args, pkgManager)\n console.log()\n\n // Prompt the user to initialize a git repo\n await chooseGitInit(projDir, args)\n console.log()\n\n ora(green('Setup complete!')).succeed()\n\n console.log(`\\n${bgCyan(black(' Next steps '))}\\n`)\n\n const relProjDir = relative(process.cwd(), projDir)\n const devCmd = pkgManager === 'npm' ? 'npm run dev' : `${pkgManager} dev`\n\n // If the project dir is the current dir, no need to tell users to cd\n if (relProjDir !== '') {\n console.log(`You can now ${bold(cyan('cd'))} into the ${bold(cyan(relProjDir))} project directory.`)\n }\n console.log(`Run ${bold(cyan(devCmd))} to start the local dev server. ${bold(cyan('CTRL-C'))} to close.`)\n console.log('')\n}\n","// Copyright (c) 2024 Climate Interactive / New Venture Fund\n\nimport { bold, dim, green } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\n\nconst promptMessage = `Would you like your project to use WebAssembly?`\n\nconst noDesc = `\\\n* Choose this if you want to get started using SDEverywhere quickly\nand you don't want to install the Emscripten SDK.\n* This will generate a model that uses JavaScript code only, which\ndoesn't require extra build tools, but runs slower than WebAssembly.`\nconst yesDesc = `\\\n* Choose this if you want this script to install the Emscripten SDK\nfor you, or if you already have it installed.\n* This will generate a model that uses WebAssembly, which requires an\nadditional build step, but runs faster than pure JavaScript code.`\n\nconst FORMATS = [\n {\n title: 'No, generate a JavaScript model',\n description: noDesc,\n value: 'js'\n },\n {\n title: 'Yes, generate a WebAssembly model',\n description: yesDesc,\n value: 'c'\n }\n]\n\nexport async function chooseCodeFormat(): Promise<string> {\n // Prompt the user\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'format',\n message: promptMessage,\n choices: FORMATS\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n const target = options.format === 'c' ? 'WebAssembly' : 'JavaScript'\n const successMessage = green(\n `Configuring your project to generate ${target}. See \"${bold('sde.config.js')}\" for details.`\n )\n ora(successMessage).succeed()\n\n return options.format\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { mkdir, readFile, writeFile } from 'fs/promises'\nimport { dirname, join as joinPath, parse as parsePath, relative, resolve as resolvePath } from 'path'\n\nimport { bold, cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport type { Choice } from 'prompts'\nimport prompts from 'prompts'\n\nimport { parseAndGenerate } from '@sdeverywhere/compile'\n\ninterface MdlConstVariable {\n kind: 'const'\n name: string\n value: number\n}\n\ninterface MdlAuxVariable {\n kind: 'aux'\n name: string\n}\n\ninterface MdlLevelVariable {\n kind: 'level'\n name: string\n}\n\ntype MdlVariable = MdlConstVariable | MdlAuxVariable | MdlLevelVariable\n\nconst sampleChecksContent = `\\\n# yaml-language-server: $schema=SCHEMA_PATH\n\n#\n# This file contains \"check\" tests that exercise your model under different input\n# scenarios. For more guidance, consult this wiki page:\n# https://github.com/climateinteractive/SDEverywhere/wiki/Testing-and-Comparing-Your-Model\n#\n\n# NOTE: The following is an example of a simple check just to get you started.\n# Replace \"Some output\" with the name of some variable you'd like to test.\n- describe: Some output\n tests:\n - it: should be > 0 for all input scenarios\n scenarios:\n - preset: matrix\n datasets:\n - name: Some output\n predicates:\n - gt: 0\n`\n\nconst sampleComparisonsContent = `\\\n# yaml-language-server: $schema=SCHEMA_PATH\n\n#\n# This file contains definitions of custom comparison scenarios, which allow you to see\n# how the behavior of the model compares to that of previous versions. For more guidance,\n# consult the following wiki page:\n# https://github.com/climateinteractive/SDEverywhere/wiki/Testing-and-Comparing-Your-Model\n#\n\n# NOTE: The following is an example of a custom scenario just to get you started.\n# Replace \"Some input\" and \"Another input\" with the names of some variables you'd\n# like to test.\n- scenario:\n title: Custom scenario\n subtitle: gradual ramp-up\n with:\n - input: Some input\n at: 10\n - input: Another input\n at: 20\n`\n\nexport async function updateSdeConfig(projDir: string, mdlPath: string, genFormat: string): Promise<void> {\n // Read the `sde.config.js` file from the template\n const configPath = joinPath(projDir, 'sde.config.js')\n let configText = await readFile(configPath, 'utf8')\n\n // Set the code generation format to the chosen format\n configText = configText.replace(`const genFormat = 'js'`, `const genFormat = '${genFormat}'`)\n\n // Replace instances of `model/MODEL_NAME.mdl` with the path to the chosen mdl file\n configText = configText.replaceAll('model/MODEL_NAME.mdl', mdlPath)\n\n // Write the updated file\n await writeFile(configPath, configText)\n}\n\nasync function generateYaml(projDir: string, kind: 'checks' | 'comparisons', template: string): Promise<void> {\n const yamlDir = joinPath(projDir, 'model', kind)\n const yamlPath = joinPath(yamlDir, `${kind}.yaml`)\n if (!existsSync(yamlPath)) {\n // Get relative path from yaml file parent dir to project dir\n let relProjPath = relative(dirname(yamlPath), projDir)\n if (relProjPath.length === 0) {\n relProjPath = './'\n }\n\n // Create the directory for the yaml file, if needed\n await mkdir(yamlDir, { recursive: true })\n\n // TODO: This path is normally different depending on whether using npm/yarn or\n // pnpm. For npm/yarn, `check-core` is hoisted under top-level `node_modules`,\n // but for pnpm, it is nested under `node_modules/.pnpm`. As an ugly workaround\n // the templates declare `check-core` as a direct dependency even though it is\n // not really needed (a transitive dependency via `plugin-check` would normally\n // suffice). This allows us to use the same path here that works for all\n // three package managers.\n const nodeModulesPart = joinPath(relProjPath, 'node_modules')\n const schemaName = kind === 'checks' ? 'check' : 'comparison'\n const checkCorePart = `@sdeverywhere/check-core/schema/${schemaName}.schema.json`\n const schemaPath = `${nodeModulesPart}/${checkCorePart}`\n const yamlContent = template.replace('SCHEMA_PATH', schemaPath)\n await writeFile(yamlPath, yamlContent)\n }\n}\n\nexport async function generateSampleYamlFiles(projDir: string): Promise<void> {\n // Generate a sample `checks.yaml` file if one doesn't already exist\n await generateYaml(projDir, 'checks', sampleChecksContent)\n\n // Generate a sample `comparisons.yaml` file if one doesn't already exist\n await generateYaml(projDir, 'comparisons', sampleComparisonsContent)\n}\n\nexport async function chooseGenConfig(projDir: string, mdlPath: string): Promise<void> {\n // TODO: For now we eagerly read the mdl file; maybe change this to only load it if\n // the user chooses to generate graph and/or slider config\n let mdlVars: MdlVariable[]\n try {\n // Get the list of variables available in the model\n mdlVars = await readModelVars(projDir, mdlPath)\n } catch (e) {\n console.log(e)\n ora(\n yellow('The mdl file failed to load. We will continue setting things up, and you can diagnose the issue later.')\n ).warn()\n return\n }\n\n // Extract `INITIAL TIME` and `FINAL TIME` values and remove special control variables from the list\n let initialTime: number\n let finalTime: number\n const validVars: MdlVariable[] = []\n for (const v of mdlVars) {\n const varName = v.name.toLowerCase()\n let skip = false\n switch (varName) {\n case 'final time':\n skip = true\n if (v.kind === 'const') {\n finalTime = v.value\n }\n break\n case 'initial time':\n skip = true\n if (v.kind === 'const') {\n initialTime = v.value\n }\n break\n case 'saveper':\n case 'time':\n case 'time step':\n skip = true\n break\n default:\n break\n }\n if (!skip) {\n validVars.push(v)\n }\n }\n\n // Set the values in `model.csv`\n if (initialTime === undefined) {\n initialTime = 0\n }\n if (finalTime === undefined) {\n finalTime = 100\n }\n\n // TODO: Auto-detect dat files that are referenced by the mdl and include them here\n const datFiles: string[] = []\n const datPart = datFiles.join(';')\n\n // Preserve the `model.csv` header but drop other existing content (if any)\n const modelCsvFile = joinPath(projDir, 'config', 'model.csv')\n const origModelCsvContent = await readFile(modelCsvFile, 'utf8')\n const modelCsvHeader = origModelCsvContent.split('\\n')[0]\n\n // Disable bundled listing and customization features by default\n const bundleListing = 'false'\n const customLookups = 'false'\n const customOutputs = 'false'\n\n // Add line and write out updated `model.csv`\n const modelCsvLine = `${initialTime},${finalTime},${datPart},${bundleListing},${customLookups},${customOutputs}`\n const newModelCsvContent = `${modelCsvHeader}\\n${modelCsvLine}\\n`\n await writeFile(modelCsvFile, newModelCsvContent)\n\n // See if the user wants to generate graph config\n await chooseGenGraphConfig(projDir, validVars)\n console.log()\n\n // See if the user wants to generate slider config\n await chooseGenSliderConfig(projDir, validVars)\n}\n\nasync function chooseGenGraphConfig(projDir: string, mdlVars: MdlVariable[]): Promise<void> {\n // Prompt the user\n const genResponse = await prompts(\n {\n type: 'confirm',\n name: 'genGraph',\n message: `Would you like to configure a graph to get you started? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (!genResponse.genGraph) {\n ora().info(dim(`No problem! You can edit the \"${cyan('config/graphs.csv')}\" file later.`))\n return\n }\n\n // Offer multi-select with available output variables\n const outputVarNames: string[] = []\n for (const mdlVar of mdlVars) {\n if (mdlVar.kind === 'aux' || mdlVar.kind === 'level') {\n outputVarNames.push(mdlVar.name)\n }\n }\n outputVarNames.sort((a, b) => {\n return a.toLowerCase().localeCompare(b.toLowerCase())\n })\n const choices = outputVarNames.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n const varsResponse = await prompts(\n {\n type: 'autocompleteMultiselect',\n name: 'vars',\n message: 'Choose up to three output variables to display in the graph',\n choices,\n max: 3\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Preserve the `graphs.csv` header but drop other existing content (if any)\n const graphsCsvFile = joinPath(projDir, 'config', 'graphs.csv')\n const origGraphsCsvContent = await readFile(graphsCsvFile, 'utf8')\n const graphsCsvHeader = origGraphsCsvContent.split('\\n')[0]\n\n // Write the updated `graphs.csv` file\n let newGraphsCsvContent = `${graphsCsvHeader}\\n`\n if (varsResponse.vars.length > 0) {\n // Add line to `graphs.csv`\n const csvLine = graphsCsvLine(varsResponse.vars)\n newGraphsCsvContent += `${csvLine}\\n`\n }\n await writeFile(graphsCsvFile, newGraphsCsvContent)\n\n if (varsResponse.vars.length === 0) {\n ora().info(dim(`No variables selected. You can edit the \"${cyan('config/graphs.csv')}\" file later.`))\n return\n }\n\n ora(\n green(`Added graph to \"${bold('config/graphs.csv')}\". ${dim('You can configure graphs in that file later.')}`)\n ).succeed()\n}\n\n// TODO: Ideally the `plugin-config` package would expose an API for generating CSV, but\n// until then, we will generate a comma-separated line of values in hardcoded fashion\nfunction graphsCsvLine(outputVarNames: string[]): string {\n const colors = ['blue', 'red', 'green']\n\n // Fill the line with blanks initially, then set the small subset of fields\n const a = Array(131).fill('')\n // id\n a[0] = '1'\n // parent menu\n a[2] = 'Graphs'\n // graph title\n a[3] = 'Graph Title'\n // kind\n a[7] = 'line'\n // Plots start at 26\n let index = 26\n let colorIndex = 0\n for (const outputVarName of outputVarNames) {\n // Surround the name in quotes if it contains a comma\n const escapedName = escapeCsvField(outputVarName)\n // plot N variable\n a[index + 0] = escapedName\n // plot N style\n a[index + 2] = 'line'\n // plot N label\n a[index + 3] = escapedName\n // plot N color\n a[index + 4] = colors[colorIndex]\n index += 7\n colorIndex++\n }\n\n return a.join(',')\n}\n\nasync function chooseGenSliderConfig(projDir: string, mdlVars: MdlVariable[]): Promise<void> {\n // Prompt the user\n const genResponse = await prompts(\n {\n type: 'confirm',\n name: 'genSliders',\n message: `Would you like to configure a few sliders to get you started? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (!genResponse.genSliders) {\n ora().info(dim(`No problem! You can edit the \"${cyan('config/inputs.csv')}\" file later.`))\n return\n }\n\n // Offer multi-select with available input variables\n const inputVarNames: string[] = []\n for (const mdlVar of mdlVars) {\n if (mdlVar.kind === 'const') {\n inputVarNames.push(mdlVar.name)\n }\n }\n inputVarNames.sort((a, b) => {\n return a.toLowerCase().localeCompare(b.toLowerCase())\n })\n const choices = inputVarNames.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n const varsResponse = await prompts(\n {\n type: 'autocompleteMultiselect',\n name: 'vars',\n message: 'Choose up to three input variables to control with sliders',\n choices,\n max: 3\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Preserve the `inputs.csv` header but drop other existing content (if any)\n const inputsCsvFile = joinPath(projDir, 'config', 'inputs.csv')\n const origInputsCsvContent = await readFile(inputsCsvFile, 'utf8')\n const inputsCsvHeader = origInputsCsvContent.split('\\n')[0]\n\n // Write the updated `inputs.csv` file\n let newInputsCsvContent = `${inputsCsvHeader}\\n`\n if (varsResponse.vars.length > 0) {\n // Add lines to `inputs.csv`\n let idNumber = 1\n for (const inputVarName of varsResponse.vars) {\n const inputVar = mdlVars.find(v => v.name === inputVarName)\n if (inputVar && inputVar.kind === 'const') {\n const defaultValue = inputVar.value\n const csvLine = inputsCsvLine(inputVarName, defaultValue, idNumber.toString())\n newInputsCsvContent += `${csvLine}\\n`\n idNumber++\n }\n }\n }\n await writeFile(inputsCsvFile, newInputsCsvContent)\n\n if (varsResponse.vars.length === 0) {\n ora().info(dim(`No variables selected. You can edit the \"${cyan('config/inputs.csv')}\" file later.`))\n return\n }\n\n const slidersText = varsResponse.vars.length > 1 ? 'sliders' : 'sliders'\n ora(\n green(\n `Added ${slidersText} to \"${bold('config/inputs.csv')}\". ${dim('You can configure sliders in that file later.')}`\n )\n ).succeed()\n}\n\n// TODO: Ideally the `plugin-config` package would expose an API for generating CSV, but\n// until then, we will generate a comma-separated line of values in hardcoded fashion\nfunction inputsCsvLine(inputVarName: string, defaultValue: number, id: string): string {\n // Surround the name in quotes if it contains a comma\n const escapedName = escapeCsvField(inputVarName)\n\n // TODO: Be smarter about automatically choosing min/max/step values\n const minValue = defaultValue - 1\n const maxValue = defaultValue + 1\n const step = 0.1\n\n // Fill the line with blanks initially, then set the small subset of fields\n const a = Array(28).fill('')\n // id\n a[0] = id\n // input type\n a[1] = 'slider'\n // viewid\n a[2] = 'view1'\n // varname\n a[3] = escapedName\n // label\n a[4] = escapedName\n // group name\n a[6] = 'Sliders'\n // slider min\n a[7] = minValue\n // slider max\n a[8] = maxValue\n // slider default\n a[9] = defaultValue\n // slider step\n a[10] = step\n // units\n a[11] = '(units)'\n\n return a.join(',')\n}\n\nfunction escapeCsvField(s: string): string {\n // Surround the value in quotes if it contains a comma\n // TODO: Escape double quotes as well\n return s.includes(',') ? `\"${s}\"` : s\n}\n\nasync function readModelVars(projDir: string, mdlPath: string): Promise<MdlVariable[]> {\n // TODO: This function contains a subset of the logic from `sde-generate.js` in\n // the `cli` package; should revisit\n // let { modelDirname, modelName, modelPathname } = modelPathProps(model)\n\n // Ensure the `build` directory exists (under the `sde-prep` directory)\n const buildDir = resolvePath(projDir, 'sde-prep', 'build')\n await mkdir(buildDir, { recursive: true })\n\n // Use an empty model spec; this will make SDE look at all variables in the mdl\n const spec = {}\n\n // Try parsing the mdl file to generate the list of variables\n // TODO: This depends on some `compile` package APIs that are not yet considered stable.\n // Ideally we'd use an API that does not write files but instead returns an in-memory\n // object in a specified format.\n\n // Read the model file\n const mdlFile = resolvePath(projDir, mdlPath)\n const mdlContent = await readFile(mdlFile, 'utf8')\n\n // Parse the model and generate the variable list\n const mdlDir = dirname(mdlFile)\n const mdlName = parsePath(mdlFile).name\n await parseAndGenerate(mdlContent, spec, ['printVarList'], mdlDir, mdlName, buildDir)\n\n // Read `build/{mdl}.json`\n const jsonListFile = joinPath(buildDir, `${mdlName}.json`)\n const jsonListContent = await readFile(jsonListFile, 'utf8')\n const jsonList = JSON.parse(jsonListContent)\n const varObjs = jsonList.variables\n\n // Create a simplified array of variables\n const mdlVars: MdlVariable[] = []\n for (const varObj of varObjs) {\n // Only include certain variables for now\n // TODO: Include \"data\" vars\n switch (varObj.varType) {\n case 'const':\n mdlVars.push({\n kind: 'const',\n name: varObj.modelLHS,\n value: Number.parseFloat(varObj.modelFormula)\n })\n break\n case 'aux':\n mdlVars.push({\n kind: 'aux',\n name: varObj.modelLHS\n })\n break\n case 'level':\n mdlVars.push({\n kind: 'level',\n name: varObj.modelLHS\n })\n break\n default:\n break\n }\n }\n\n return mdlVars\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { execa } from 'execa'\nimport { bold, cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseInstallDeps(projDir: string, args: Arguments, pkgManager: string): Promise<void> {\n // Prompt the user\n const installResponse = await prompts(\n {\n type: 'confirm',\n name: 'install',\n message: `Would you like to install ${pkgManager} dependencies? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(\n dim('Operation cancelled. Your project folder has been created, but no dependencies have been installed.')\n )\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (!installResponse.install) {\n ora().info(dim(`No problem! Remember to install dependencies after setup.`))\n return\n }\n\n // Install dependencies\n const installExec = execa(pkgManager, ['install'], { cwd: projDir })\n const installingPackagesMsg = 'Installing packages...'\n const installSpinner = ora(installingPackagesMsg).start()\n try {\n await new Promise<void>((resolve, reject) => {\n installExec.stdout?.on('data', function (data) {\n installSpinner.text = `${installingPackagesMsg}\\n${bold(`[${pkgManager}]`)} ${data}`\n })\n installExec.stderr?.on('data', function (data) {\n installSpinner.text = `${installingPackagesMsg}\\n${bold(`[${pkgManager}]`)} ${data}`\n })\n installExec.on('error', error => reject(error))\n installExec.on('close', code => {\n if (code !== 0) {\n reject(`Install failed (code=${code})`)\n } else {\n resolve()\n }\n })\n })\n installSpinner.text = green('Packages installed!')\n installSpinner.succeed()\n } catch {\n installSpinner.text = yellow(\n `There was an error installing packages. Try running ${cyan(\n `${pkgManager} install`\n )} in your project directory later.`\n )\n installSpinner.warn()\n }\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { resolve as resolvePath } from 'path'\n\nimport { bold, dim, green, red } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseProjectDir(args: Arguments): Promise<string> {\n /**\n * Return true if the given directory does not exist, or it does not contain important files\n * like `package.json`.\n */\n function isValidDir(dir: string): boolean {\n const packageJson = resolvePath(dir, 'package.json')\n const packagesDir = resolvePath(dir, 'packages')\n return !existsSync(dir) || (!existsSync(packageJson) && !existsSync(packagesDir))\n }\n\n const showValidDirMsg = (dir: string) => {\n ora(green(`Using \"${bold(dir)}\" as the project directory.`)).succeed()\n }\n\n const showInvalidDirMsg = (dir: string) => {\n ora(red(`\"${bold(dir)}\" contains existing 'package.json' and/or 'packages' directory, stopping.`)).fail()\n }\n\n // See if project directory is provided on command line\n let projDir = args['_'][2] as string\n if (projDir) {\n // Directory was provided, see if it is valid\n if (isValidDir(projDir)) {\n // The provided directory is valid, so proceed\n showValidDirMsg(projDir)\n } else {\n // The provided directory is not valid, so show error message and exit\n showInvalidDirMsg(projDir)\n process.exit(0)\n }\n } else {\n // Directory was not provided, so prompt the user\n const dirResponse = await prompts(\n {\n type: 'text',\n name: 'directory',\n message: 'Where would you like to create your new project?',\n initial: '<current directory>'\n // validate(value) {\n // if (value === '<current directory>') {\n // value = process.cwd()\n // }\n // if (!isValidDir(value)) {\n // return notValidMsg(value)\n // }\n // return true\n // }\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n projDir = dirResponse.directory\n if (projDir === '<current directory>') {\n projDir = process.cwd()\n }\n if (isValidDir(projDir)) {\n showValidDirMsg(projDir)\n } else {\n showInvalidDirMsg(projDir)\n process.exit(0)\n }\n }\n\n return projDir\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync, rmSync } from 'fs'\nimport { join as joinPath, resolve as resolvePath } from 'path'\n\nimport { execa } from 'execa'\nimport { findUp } from 'find-up'\nimport { bold, cyan, dim, green, red } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\n// TODO: Make this configurable; we're using this older version for now because it is\n// relatively stable and has been used to build En-ROADS and C-ROADS for a long time\nconst version = '2.0.34'\n\nexport async function chooseInstallEmsdk(projDir: string, args: Arguments): Promise<void> {\n // Walk up the directory structure to see if there is an existing `emsdk` directory\n const existingEmsdkDir = await findUp('emsdk', {\n cwd: projDir,\n type: 'directory'\n })\n if (existingEmsdkDir) {\n ora().succeed('Found existing Emscripten SDK installation.')\n ora().info(dim(`Your project will use \"${cyan(existingEmsdkDir)}\".`))\n return\n }\n\n // Prompt the user\n const underParentDir = resolvePath(projDir, '..', 'emsdk')\n const underProjDir = joinPath(projDir, 'emsdk')\n const installResponse = await prompts(\n {\n type: 'select',\n name: 'install',\n message: `Would you like to install the Emscripten SDK that is used to generate WebAssembly?`,\n choices: [\n // ${reset(dim('(recommended)'))\n {\n title: `Install under parent directory (${bold(underParentDir)})`,\n description: 'This is recommended so that it can be shared by multiple projects',\n value: 'parent'\n },\n {\n title: `Install under project directory (${bold(underProjDir)})\"`,\n description: 'This is useful for keeping everything under a single project directory',\n value: 'project'\n },\n {\n title: `Don't install`,\n description: `It's OK, you can install it later`,\n value: 'skip'\n }\n ]\n },\n {\n onCancel: () => {\n ora().info(\n dim(\n 'Operation cancelled. Your project folder has been created, but the Emscripten SDK and other dependencies have not been installed.'\n )\n )\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (installResponse.install === 'skip') {\n ora().info(\n dim(\n `No problem! Be sure to install the Emscripten SDK and configure it in \"${cyan('sde.config.js')}\" after setup.`\n )\n )\n return\n }\n\n const installDir = installResponse.install === 'parent' ? underParentDir : underProjDir\n try {\n // TODO: Use spinner here\n await installEmscripten(installDir)\n } catch (e) {\n ora(red(`Failed to install Emscripten SDK: ${e.message}`)).fail()\n process.exit(0)\n }\n\n ora(green(`Installed the Emscripten SDK in \"${bold(installDir)}\"`)).succeed()\n}\n\n/**\n * Install the Emscripten SDK to the `emsdk` directory under the\n * given directory (if `emsdk` is not already present), then\n * activates the requested version (specified with `version`).\n *\n * The implementation is similar to the existing `setup-emsdk` action\n * (https://github.com/mymindstorm/setup-emsdk) except that one has issues\n * with the cache directory on Windows, so having our own script gives us\n * more control over installation and caching behavior.\n */\nasync function installEmscripten(emsdkDir: string /*, options?: { verbose?: boolean }*/): Promise<void> {\n // Only download if the emsdk directory wasn't restored from a cache\n if (!existsSync(emsdkDir)) {\n console.log(`Downloading Emscripten SDK to ${emsdkDir}`)\n // console.log()\n await execa('git', ['clone', 'https://github.com/emscripten-core/emsdk.git', emsdkDir])\n } else {\n console.log(`Found existing Emscripten SDK directory: ${emsdkDir}`)\n }\n // console.log()\n\n if (process.env.CI) {\n // On GitHub Actions, remove the `.git` directory to keep the cache smaller.\n // When we update to a new version, the cache key will miss and the emsdk\n // repo will be redownloaded.\n console.log('CI detected, removing .git directory...')\n const gitDir = joinPath(emsdkDir, '.git')\n rmSync(gitDir, { recursive: true, force: true })\n } else {\n // For local development, pull to get the latest\n console.log('Local development detected, performing git pull...')\n await execa('git', ['pull'], { cwd: emsdkDir })\n // console.log()\n }\n\n const emsdkCmd = async (...args: string[]) => {\n return execa('python3', ['emsdk.py', ...args], { cwd: emsdkDir })\n }\n\n console.log(`Activating Emscripten SDK ${version}...`)\n await emsdkCmd('install', version)\n await emsdkCmd('activate', version)\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { execaCommand } from 'execa'\nimport { cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseGitInit(projDir: string, args: Arguments): Promise<void> {\n // Prompt the user\n const gitResponse = await prompts(\n {\n type: 'confirm',\n name: 'git',\n message: `Would you like to initialize a new git repository? ${reset(dim('(optional)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled. Your project folder has already been created.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (!gitResponse.git) {\n ora().info(dim(`No problem! You can come back and run ${cyan(`git init`)} later.`))\n return\n }\n\n // Init git repo\n try {\n await execaCommand('git init', { cwd: projDir })\n ora().succeed(green('Git repository initialized!'))\n } catch {\n ora().warn(\n yellow(\n `There was a problem initializing the Git repository, but no problem, you can run ${cyan(`git init`)} later.`\n )\n )\n }\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { readdir } from 'fs/promises'\nimport { relative, resolve as resolvePath, sep, posix } from 'path'\n\nimport { bold, dim, green, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport type { Choice } from 'prompts'\nimport prompts from 'prompts'\n\nexport async function chooseMdlFile(projDir: string): Promise<string | undefined> {\n // Find all `.mdl` files in the project directory\n // From https://stackoverflow.com/a/45130990\n async function getFiles(dir: string): Promise<string[]> {\n const dirents = await readdir(dir, { withFileTypes: true })\n const files = await Promise.all(\n dirents.map(dirent => {\n const res = resolvePath(dir, dirent.name)\n return dirent.isDirectory() ? getFiles(res) : res\n })\n )\n return files.flat()\n }\n const allFiles = await getFiles(projDir)\n const mdlFiles = allFiles\n // Only include files ending with '.mdl'\n .filter(f => f.endsWith('.mdl'))\n // Convert to a relative path with POSIX path separators (we want\n // paths in the 'sde.config.js' file to use POSIX path style only,\n // since that works on any OS including Windows)\n .map(f => relative(projDir, f).replaceAll(sep, posix.sep))\n const mdlChoices = mdlFiles.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n\n let mdlFile: string\n if (mdlFiles.length === 0) {\n // No mdl files found; return undefined so that the mdl from the template is copied over\n ora(yellow(`No mdl files were found in \"${projDir}\". The mdl file from the template will be used instead.`)).warn()\n mdlFile = undefined\n } else if (mdlFiles.length === 1) {\n // Only one mdl file\n mdlFile = mdlFiles[0]\n ora().succeed(`Found \"${mdlFile}\", will configure the project to use that mdl file.`)\n } else {\n // Multiple mdl files found; allow the user to choose one\n // TODO: Eventually we should allow the user to choose to flatten if there are multiple submodels\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'mdlFile',\n message: 'It looks like there are multiple mdl files. Which one would you like to use?',\n choices: mdlChoices\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n mdlFile = options.mdlFile\n ora(green(`Using \"${bold(mdlFile)}\" as the model for the project.`)).succeed()\n }\n\n return mdlFile\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync, mkdtempSync, readdirSync, renameSync, rmSync } from 'fs'\nimport { writeFile } from 'fs/promises'\nimport { copy } from 'fs-extra'\nimport { tmpdir } from 'os'\nimport { join as joinPath } from 'path'\n\nimport { downloadTemplate } from 'giget'\nimport { bold, dim, green, red, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nconst TEMPLATES = [\n {\n title: 'Default (jQuery) project',\n description: 'Includes recommended structure with config files, jQuery-based app, core library, model-check, etc',\n value: 'default'\n },\n {\n title: 'Svelte project',\n description: 'Includes recommended structure with config files, Svelte-based app, core library, model-check, etc',\n value: 'svelte'\n },\n {\n title: 'Minimal project',\n description: 'Includes simple config for model-check',\n value: 'minimal'\n }\n]\n\ninterface Template {\n /** The template URI that can be passed to `giget` to download the template. */\n uri: string\n /** The template name that will be displayed to the user. */\n name: string\n}\n\nexport async function chooseTemplate(args: Arguments): Promise<Template> {\n let templateName: string\n if (args.template) {\n // Allow template name or repository to be provided on command line\n templateName = args.template\n } else {\n // Prompt the user\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'template',\n message: 'Which template would you like to use?',\n choices: TEMPLATES\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n templateName = options.template\n }\n\n // Allow branch name or commit hash to be overridden on command line\n const defaultRev = 'main'\n const commit = args.commit || defaultRev\n\n // Construct the template repository URL\n let baseTemplateUri: string\n if (templateName.includes(':')) {\n // Assume the template name is already in the form of a giget template, for example:\n // github:owner/repo\n // gitlab:owner/repo\n baseTemplateUri = templateName\n } else if (templateName.includes('/')) {\n // Assume the template name is a GitHub repository name, for example:\n // owner/repo\n baseTemplateUri = `github:${templateName}`\n } else {\n // Otherwise, assume the template name is one of the available `template-*`\n // projects under `examples` in the SDEverywhere repository, for example:\n // default\n // svelte\n // minimal\n baseTemplateUri = `github:climateinteractive/SDEverywhere/examples/template-${templateName}`\n }\n const templateUri = `${baseTemplateUri}#${commit}`\n\n ora(green(`Using \"${bold(templateUri)}\" as the template for the project.`)).succeed()\n\n return {\n uri: templateUri,\n name: templateName\n }\n}\n\nexport async function copyTemplate(\n template: Template,\n projDir: string,\n pkgManager: string,\n configDirExisted: boolean,\n mdlExisted: boolean\n): Promise<void> {\n // Show a spinner while copying the template files\n const templateSpinner = ora('Copying template files...').start()\n\n try {\n // Make giget write to a temporary directory\n const tmpDir = mkdtempSync(joinPath(tmpdir(), 'sde-create-'))\n\n // Use giget to download the template (we will be writing to a temporary directory,\n // so `force` is safe)\n await downloadTemplate(template.uri, {\n force: true,\n dir: tmpDir\n })\n\n // In case giget doesn't return an error when an invalid template is provided, check\n // that the temporary directory is non-empty\n if (!existsSync(tmpDir) || readdirSync(tmpDir).length === 0) {\n throw new Error('Failed to download the requested template: the temporary directory is empty.')\n }\n\n if (configDirExisted) {\n // There is already a `config` directory in the project directory; remove the\n // `config` directory from the template so that we don't write files from the\n // template that conflict with the existing files\n rmSync(joinPath(tmpDir, 'config'), { recursive: true, force: true })\n }\n\n if (mdlExisted) {\n // There is already an mdl file in the project directory; remove the `model`\n // directory (including the mdl file and the model-check yaml files) from the\n // template so that we don't copy them into the project directory\n rmSync(joinPath(tmpDir, 'model'), { recursive: true, force: true })\n }\n\n // Copy files to destination without overwriting\n await copy(tmpDir, projDir, {\n overwrite: false,\n errorOnExist: false\n })\n\n if (!mdlExisted) {\n // There wasn't already an mdl file in the project directory, so we will use\n // the one supplied by the template. Rename it from `MODEL_NAME.mdl` to\n // `sample.mdl`.\n renameSync(joinPath(projDir, 'model', 'MODEL_NAME.mdl'), joinPath(projDir, 'model', 'sample.mdl'))\n }\n\n // Remove the temporary directory\n rmSync(tmpDir, { recursive: true, force: true })\n } catch (e) {\n // The download failed; show an error message\n // TODO: Handle common download issues; for now, just log the error message and exit\n templateSpinner.fail()\n console.error(red(e.message))\n console.error(yellow('\\nThere was a problem copying the template.'))\n console.error(\n yellow(\n 'Please start a new discussion thread and include the command output so that we can help:\\n https://github.com/climateinteractive/SDEverywhere/discussions/categories/q-a\\n'\n )\n )\n process.exit(0)\n }\n\n if (existsSync(joinPath(projDir, 'packages')) && pkgManager === 'pnpm') {\n // When using pnpm and the template has a `packages` folder (i.e., it has a monorepo\n // layout), we need to write a `pnpm-workspace.yaml` file since pnpm doesn't use the\n // \"workspaces\" config from `package.json` (like npm and yarn use)\n const workspaceFile = joinPath(projDir, 'pnpm-workspace.yaml')\n const workspaceContent = `packages:\\n - packages/*\\n`\n await writeFile(workspaceFile, workspaceContent)\n }\n\n templateSpinner.text = green('Template copied!')\n templateSpinner.succeed()\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAAA,aAA2B;AAC3B,IAAAC,eAAwD;AAExD,IAAAC,iBAAsD;AACtD,IAAAC,cAAgB;AAChB,IAAAC,kBAAoB;AACpB,2BAAiC;AACjC,0BAAkB;;;ACPlB,oBAAiC;AACjC,iBAAgB;AAChB,qBAAoB;AAEpB,IAAM,gBAAgB;AAEtB,IAAM,SAAS;AAAA;AAAA;AAAA;AAKf,IAAM,UAAU;AAAA;AAAA;AAAA;AAMhB,IAAM,UAAU;AAAA,EACd;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,EACT;AACF;AAEA,eAAsB,mBAAoC;AAExD,QAAM,UAAU,UAAM,eAAAC;AAAA,IACpB;AAAA,MACE;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,uBAAAC,SAAI,EAAE,SAAK,mBAAI,sBAAsB,CAAC;AACtC,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,WAAW,MAAM,gBAAgB;AACxD,QAAM,qBAAiB;AAAA,IACrB,wCAAwC,MAAM,cAAU,oBAAK,eAAe,CAAC;AAAA,EAC/E;AACA,iBAAAA,SAAI,cAAc,EAAE,QAAQ;AAE5B,SAAO,QAAQ;AACjB;;;ACxDA,gBAA2B;AAC3B,sBAA2C;AAC3C,kBAAgG;AAEhG,IAAAC,iBAAsD;AACtD,IAAAC,cAAgB;AAEhB,IAAAC,kBAAoB;AAEpB,qBAAiC;AAoBjC,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsB5B,IAAM,2BAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBjC,eAAsB,gBAAgB,SAAiB,SAAiB,WAAkC;AAExG,QAAM,iBAAa,YAAAC,MAAS,SAAS,eAAe;AACpD,MAAI,aAAa,UAAM,0BAAS,YAAY,MAAM;AAGlD,eAAa,WAAW,QAAQ,0BAA0B,sBAAsB,SAAS,GAAG;AAG5F,eAAa,WAAW,WAAW,wBAAwB,OAAO;AAGlE,YAAM,2BAAU,YAAY,UAAU;AACxC;AAEA,eAAe,aAAa,SAAiB,MAAgC,UAAiC;AAC5G,QAAM,cAAU,YAAAA,MAAS,SAAS,SAAS,IAAI;AAC/C,QAAM,eAAW,YAAAA,MAAS,SAAS,GAAG,IAAI,OAAO;AACjD,MAAI,KAAC,sBAAW,QAAQ,GAAG;AAEzB,QAAI,kBAAc,0BAAS,qBAAQ,QAAQ,GAAG,OAAO;AACrD,QAAI,YAAY,WAAW,GAAG;AAC5B,oBAAc;AAAA,IAChB;AAGA,cAAM,uBAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AASxC,UAAM,sBAAkB,YAAAA,MAAS,aAAa,cAAc;AAC5D,UAAM,aAAa,SAAS,WAAW,UAAU;AACjD,UAAM,gBAAgB,mCAAmC,UAAU;AACnE,UAAM,aAAa,GAAG,eAAe,IAAI,aAAa;AACtD,UAAM,cAAc,SAAS,QAAQ,eAAe,UAAU;AAC9D,cAAM,2BAAU,UAAU,WAAW;AAAA,EACvC;AACF;AAEA,eAAsB,wBAAwB,SAAgC;AAE5E,QAAM,aAAa,SAAS,UAAU,mBAAmB;AAGzD,QAAM,aAAa,SAAS,eAAe,wBAAwB;AACrE;AAEA,eAAsB,gBAAgB,SAAiB,SAAgC;AAGrF,MAAI;AACJ,MAAI;AAEF,cAAU,MAAM,cAAc,SAAS,OAAO;AAAA,EAChD,SAAS,GAAG;AACV,YAAQ,IAAI,CAAC;AACb,oBAAAC;AAAA,UACE,uBAAO,wGAAwG;AAAA,IACjH,EAAE,KAAK;AACP;AAAA,EACF;AAGA,MAAI;AACJ,MAAI;AACJ,QAAM,YAA2B,CAAC;AAClC,aAAW,KAAK,SAAS;AACvB,UAAM,UAAU,EAAE,KAAK,YAAY;AACnC,QAAI,OAAO;AACX,YAAQ,SAAS;AAAA,MACf,KAAK;AACH,eAAO;AACP,YAAI,EAAE,SAAS,SAAS;AACtB,sBAAY,EAAE;AAAA,QAChB;AACA;AAAA,MACF,KAAK;AACH,eAAO;AACP,YAAI,EAAE,SAAS,SAAS;AACtB,wBAAc,EAAE;AAAA,QAClB;AACA;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AACP;AAAA,MACF;AACE;AAAA,IACJ;AACA,QAAI,CAAC,MAAM;AACT,gBAAU,KAAK,CAAC;AAAA,IAClB;AAAA,EACF;AAGA,MAAI,gBAAgB,QAAW;AAC7B,kBAAc;AAAA,EAChB;AACA,MAAI,cAAc,QAAW;AAC3B,gBAAY;AAAA,EACd;AAGA,QAAM,WAAqB,CAAC;AAC5B,QAAM,UAAU,SAAS,KAAK,GAAG;AAGjC,QAAM,mBAAe,YAAAD,MAAS,SAAS,UAAU,WAAW;AAC5D,QAAM,sBAAsB,UAAM,0BAAS,cAAc,MAAM;AAC/D,QAAM,iBAAiB,oBAAoB,MAAM,IAAI,EAAE,CAAC;AAGxD,QAAM,gBAAgB;AACtB,QAAM,gBAAgB;AACtB,QAAM,gBAAgB;AAGtB,QAAM,eAAe,GAAG,WAAW,IAAI,SAAS,IAAI,OAAO,IAAI,aAAa,IAAI,aAAa,IAAI,aAAa;AAC9G,QAAM,qBAAqB,GAAG,cAAc;AAAA,EAAK,YAAY;AAAA;AAC7D,YAAM,2BAAU,cAAc,kBAAkB;AAGhD,QAAM,qBAAqB,SAAS,SAAS;AAC7C,UAAQ,IAAI;AAGZ,QAAM,sBAAsB,SAAS,SAAS;AAChD;AAEA,eAAe,qBAAqB,SAAiB,SAAuC;AAE1F,QAAM,cAAc,UAAM,gBAAAE;AAAA,IACxB;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,+DAA2D,0BAAM,oBAAI,eAAe,CAAC,CAAC;AAAA,MAC/F,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,wBAAAD,SAAI,EAAE,SAAK,oBAAI,sBAAsB,CAAC;AACtC,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,CAAC,YAAY,UAAU;AACzB,oBAAAA,SAAI,EAAE,SAAK,oBAAI,qCAAiC,qBAAK,mBAAmB,CAAC,eAAe,CAAC;AACzF;AAAA,EACF;AAGA,QAAM,iBAA2B,CAAC;AAClC,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,SAAS,SAAS,OAAO,SAAS,SAAS;AACpD,qBAAe,KAAK,OAAO,IAAI;AAAA,IACjC;AAAA,EACF;AACA,iBAAe,KAAK,CAAC,GAAG,MAAM;AAC5B,WAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC;AAAA,EACtD,CAAC;AACD,QAAM,UAAU,eAAe,IAAI,OAAK;AACtC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AACD,QAAM,eAAe,UAAM,gBAAAC;AAAA,IACzB;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,wBAAAD,SAAI,EAAE,SAAK,oBAAI,sBAAsB,CAAC;AACtC,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,QAAM,oBAAgB,YAAAD,MAAS,SAAS,UAAU,YAAY;AAC9D,QAAM,uBAAuB,UAAM,0BAAS,eAAe,MAAM;AACjE,QAAM,kBAAkB,qBAAqB,MAAM,IAAI,EAAE,CAAC;AAG1D,MAAI,sBAAsB,GAAG,eAAe;AAAA;AAC5C,MAAI,aAAa,KAAK,SAAS,GAAG;AAEhC,UAAM,UAAU,cAAc,aAAa,IAAI;AAC/C,2BAAuB,GAAG,OAAO;AAAA;AAAA,EACnC;AACA,YAAM,2BAAU,eAAe,mBAAmB;AAElD,MAAI,aAAa,KAAK,WAAW,GAAG;AAClC,oBAAAC,SAAI,EAAE,SAAK,oBAAI,gDAA4C,qBAAK,mBAAmB,CAAC,eAAe,CAAC;AACpG;AAAA,EACF;AAEA,kBAAAA;AAAA,QACE,sBAAM,uBAAmB,qBAAK,mBAAmB,CAAC,UAAM,oBAAI,8CAA8C,CAAC,EAAE;AAAA,EAC/G,EAAE,QAAQ;AACZ;AAIA,SAAS,cAAc,gBAAkC;AACvD,QAAM,SAAS,CAAC,QAAQ,OAAO,OAAO;AAGtC,QAAM,IAAI,MAAM,GAAG,EAAE,KAAK,EAAE;AAE5B,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,MAAI,QAAQ;AACZ,MAAI,aAAa;AACjB,aAAW,iBAAiB,gBAAgB;AAE1C,UAAM,cAAc,eAAe,aAAa;AAEhD,MAAE,QAAQ,CAAC,IAAI;AAEf,MAAE,QAAQ,CAAC,IAAI;AAEf,MAAE,QAAQ,CAAC,IAAI;AAEf,MAAE,QAAQ,CAAC,IAAI,OAAO,UAAU;AAChC,aAAS;AACT;AAAA,EACF;AAEA,SAAO,EAAE,KAAK,GAAG;AACnB;AAEA,eAAe,sBAAsB,SAAiB,SAAuC;AAE3F,QAAM,cAAc,UAAM,gBAAAC;AAAA,IACxB;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,qEAAiE,0BAAM,oBAAI,eAAe,CAAC,CAAC;AAAA,MACrG,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,wBAAAD,SAAI,EAAE,SAAK,oBAAI,sBAAsB,CAAC;AACtC,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,CAAC,YAAY,YAAY;AAC3B,oBAAAA,SAAI,EAAE,SAAK,oBAAI,qCAAiC,qBAAK,mBAAmB,CAAC,eAAe,CAAC;AACzF;AAAA,EACF;AAGA,QAAM,gBAA0B,CAAC;AACjC,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,SAAS,SAAS;AAC3B,oBAAc,KAAK,OAAO,IAAI;AAAA,IAChC;AAAA,EACF;AACA,gBAAc,KAAK,CAAC,GAAG,MAAM;AAC3B,WAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC;AAAA,EACtD,CAAC;AACD,QAAM,UAAU,cAAc,IAAI,OAAK;AACrC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AACD,QAAM,eAAe,UAAM,gBAAAC;AAAA,IACzB;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,wBAAAD,SAAI,EAAE,SAAK,oBAAI,sBAAsB,CAAC;AACtC,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,QAAM,oBAAgB,YAAAD,MAAS,SAAS,UAAU,YAAY;AAC9D,QAAM,uBAAuB,UAAM,0BAAS,eAAe,MAAM;AACjE,QAAM,kBAAkB,qBAAqB,MAAM,IAAI,EAAE,CAAC;AAG1D,MAAI,sBAAsB,GAAG,eAAe;AAAA;AAC5C,MAAI,aAAa,KAAK,SAAS,GAAG;AAEhC,QAAI,WAAW;AACf,eAAW,gBAAgB,aAAa,MAAM;AAC5C,YAAM,WAAW,QAAQ,KAAK,OAAK,EAAE,SAAS,YAAY;AAC1D,UAAI,YAAY,SAAS,SAAS,SAAS;AACzC,cAAM,eAAe,SAAS;AAC9B,cAAM,UAAU,cAAc,cAAc,cAAc,SAAS,SAAS,CAAC;AAC7E,+BAAuB,GAAG,OAAO;AAAA;AACjC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,YAAM,2BAAU,eAAe,mBAAmB;AAElD,MAAI,aAAa,KAAK,WAAW,GAAG;AAClC,oBAAAC,SAAI,EAAE,SAAK,oBAAI,gDAA4C,qBAAK,mBAAmB,CAAC,eAAe,CAAC;AACpG;AAAA,EACF;AAEA,QAAM,cAAc,aAAa,KAAK,SAAS,IAAI,YAAY;AAC/D,kBAAAA;AAAA,QACE;AAAA,MACE,SAAS,WAAW,YAAQ,qBAAK,mBAAmB,CAAC,UAAM,oBAAI,+CAA+C,CAAC;AAAA,IACjH;AAAA,EACF,EAAE,QAAQ;AACZ;AAIA,SAAS,cAAc,cAAsB,cAAsB,IAAoB;AAErF,QAAM,cAAc,eAAe,YAAY;AAG/C,QAAM,WAAW,eAAe;AAChC,QAAM,WAAW,eAAe;AAChC,QAAM,OAAO;AAGb,QAAM,IAAI,MAAM,EAAE,EAAE,KAAK,EAAE;AAE3B,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,EAAE,IAAI;AAER,IAAE,EAAE,IAAI;AAER,SAAO,EAAE,KAAK,GAAG;AACnB;AAEA,SAAS,eAAe,GAAmB;AAGzC,SAAO,EAAE,SAAS,GAAG,IAAI,IAAI,CAAC,MAAM;AACtC;AAEA,eAAe,cAAc,SAAiB,SAAyC;AAMrF,QAAM,eAAW,YAAAE,SAAY,SAAS,YAAY,OAAO;AACzD,YAAM,uBAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAGzC,QAAM,OAAO,CAAC;AAQd,QAAM,cAAU,YAAAA,SAAY,SAAS,OAAO;AAC5C,QAAM,aAAa,UAAM,0BAAS,SAAS,MAAM;AAGjD,QAAM,aAAS,qBAAQ,OAAO;AAC9B,QAAM,cAAU,YAAAC,OAAU,OAAO,EAAE;AACnC,YAAM,iCAAiB,YAAY,MAAM,CAAC,cAAc,GAAG,QAAQ,SAAS,QAAQ;AAGpF,QAAM,mBAAe,YAAAJ,MAAS,UAAU,GAAG,OAAO,OAAO;AACzD,QAAM,kBAAkB,UAAM,0BAAS,cAAc,MAAM;AAC3D,QAAM,WAAW,KAAK,MAAM,eAAe;AAC3C,QAAM,UAAU,SAAS;AAGzB,QAAM,UAAyB,CAAC;AAChC,aAAW,UAAU,SAAS;AAG5B,YAAQ,OAAO,SAAS;AAAA,MACtB,KAAK;AACH,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM,OAAO;AAAA,UACb,OAAO,OAAO,WAAW,OAAO,YAAY;AAAA,QAC9C,CAAC;AACD;AAAA,MACF,KAAK;AACH,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM,OAAO;AAAA,QACf,CAAC;AACD;AAAA,MACF,KAAK;AACH,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM,OAAO;AAAA,QACf,CAAC;AACD;AAAA,MACF;AACE;AAAA,IACJ;AAAA,EACF;AAEA,SAAO;AACT;;;AC1gBA,mBAAsB;AACtB,IAAAK,iBAAsD;AACtD,IAAAC,cAAgB;AAChB,IAAAC,kBAAoB;AAGpB,eAAsB,kBAAkB,SAAiB,MAAiB,YAAmC;AAE3G,QAAM,kBAAkB,UAAM,gBAAAC;AAAA,IAC5B;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,6BAA6B,UAAU,sBAAkB,0BAAM,oBAAI,eAAe,CAAC,CAAC;AAAA,MAC7F,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,wBAAAC,SAAI,EAAE;AAAA,cACJ,oBAAI,qGAAqG;AAAA,QAC3G;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ;AACf,oBAAAA,SAAI,EAAE,SAAK,oBAAI,8BAA8B,CAAC;AAC9C;AAAA,EACF,WAAW,CAAC,gBAAgB,SAAS;AACnC,oBAAAA,SAAI,EAAE,SAAK,oBAAI,2DAA2D,CAAC;AAC3E;AAAA,EACF;AAGA,QAAM,kBAAc,oBAAM,YAAY,CAAC,SAAS,GAAG,EAAE,KAAK,QAAQ,CAAC;AACnE,QAAM,wBAAwB;AAC9B,QAAM,qBAAiB,YAAAA,SAAI,qBAAqB,EAAE,MAAM;AACxD,MAAI;AACF,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,kBAAY,QAAQ,GAAG,QAAQ,SAAU,MAAM;AAC7C,uBAAe,OAAO,GAAG,qBAAqB;AAAA,MAAK,qBAAK,IAAI,UAAU,GAAG,CAAC,IAAI,IAAI;AAAA,MACpF,CAAC;AACD,kBAAY,QAAQ,GAAG,QAAQ,SAAU,MAAM;AAC7C,uBAAe,OAAO,GAAG,qBAAqB;AAAA,MAAK,qBAAK,IAAI,UAAU,GAAG,CAAC,IAAI,IAAI;AAAA,MACpF,CAAC;AACD,kBAAY,GAAG,SAAS,WAAS,OAAO,KAAK,CAAC;AAC9C,kBAAY,GAAG,SAAS,UAAQ;AAC9B,YAAI,SAAS,GAAG;AACd,iBAAO,wBAAwB,IAAI,GAAG;AAAA,QACxC,OAAO;AACL,kBAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AACD,mBAAe,WAAO,sBAAM,qBAAqB;AACjD,mBAAe,QAAQ;AAAA,EACzB,QAAQ;AACN,mBAAe,WAAO;AAAA,MACpB,2DAAuD;AAAA,QACrD,GAAG,UAAU;AAAA,MACf,CAAC;AAAA,IACH;AACA,mBAAe,KAAK;AAAA,EACtB;AACF;;;ACjEA,IAAAC,aAA2B;AAC3B,IAAAC,eAAuC;AAEvC,IAAAC,iBAAsC;AACtC,IAAAC,cAAgB;AAChB,IAAAC,kBAAoB;AAGpB,eAAsB,iBAAiB,MAAkC;AAKvE,WAAS,WAAW,KAAsB;AACxC,UAAM,kBAAc,aAAAC,SAAY,KAAK,cAAc;AACnD,UAAM,kBAAc,aAAAA,SAAY,KAAK,UAAU;AAC/C,WAAO,KAAC,uBAAW,GAAG,KAAM,KAAC,uBAAW,WAAW,KAAK,KAAC,uBAAW,WAAW;AAAA,EACjF;AAEA,QAAM,kBAAkB,CAAC,QAAgB;AACvC,oBAAAC,aAAI,sBAAM,cAAU,qBAAK,GAAG,CAAC,6BAA6B,CAAC,EAAE,QAAQ;AAAA,EACvE;AAEA,QAAM,oBAAoB,CAAC,QAAgB;AACzC,oBAAAA,aAAI,oBAAI,QAAI,qBAAK,GAAG,CAAC,2EAA2E,CAAC,EAAE,KAAK;AAAA,EAC1G;AAGA,MAAI,UAAU,KAAK,GAAG,EAAE,CAAC;AACzB,MAAI,SAAS;AAEX,QAAI,WAAW,OAAO,GAAG;AAEvB,sBAAgB,OAAO;AAAA,IACzB,OAAO;AAEL,wBAAkB,OAAO;AACzB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,OAAO;AAEL,UAAM,cAAc,UAAM,gBAAAC;AAAA,MACxB;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUX;AAAA,MACA;AAAA,QACE,UAAU,MAAM;AACd,0BAAAD,SAAI,EAAE,SAAK,oBAAI,sBAAsB,CAAC;AACtC,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AACA,cAAU,YAAY;AACtB,QAAI,YAAY,uBAAuB;AACrC,gBAAU,QAAQ,IAAI;AAAA,IACxB;AACA,QAAI,WAAW,OAAO,GAAG;AACvB,sBAAgB,OAAO;AAAA,IACzB,OAAO;AACL,wBAAkB,OAAO;AACzB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AACT;;;AC7EA,IAAAE,aAAmC;AACnC,IAAAC,eAAyD;AAEzD,IAAAC,gBAAsB;AACtB,qBAAuB;AACvB,IAAAC,iBAA4C;AAC5C,IAAAC,cAAgB;AAChB,IAAAC,kBAAoB;AAKpB,IAAM,UAAU;AAEhB,eAAsB,mBAAmB,SAAiB,MAAgC;AAExF,QAAM,mBAAmB,UAAM,uBAAO,SAAS;AAAA,IAC7C,KAAK;AAAA,IACL,MAAM;AAAA,EACR,CAAC;AACD,MAAI,kBAAkB;AACpB,oBAAAC,SAAI,EAAE,QAAQ,6CAA6C;AAC3D,oBAAAA,SAAI,EAAE,SAAK,oBAAI,8BAA0B,qBAAK,gBAAgB,CAAC,IAAI,CAAC;AACpE;AAAA,EACF;AAGA,QAAM,qBAAiB,aAAAC,SAAY,SAAS,MAAM,OAAO;AACzD,QAAM,mBAAe,aAAAC,MAAS,SAAS,OAAO;AAC9C,QAAM,kBAAkB,UAAM,gBAAAC;AAAA,IAC5B;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA;AAAA,QAEP;AAAA,UACE,OAAO,uCAAmC,qBAAK,cAAc,CAAC;AAAA,UAC9D,aAAa;AAAA,UACb,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,OAAO,wCAAoC,qBAAK,YAAY,CAAC;AAAA,UAC7D,aAAa;AAAA,UACb,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,aAAa;AAAA,UACb,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,wBAAAH,SAAI,EAAE;AAAA,cACJ;AAAA,YACE;AAAA,UACF;AAAA,QACF;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ;AACf,oBAAAA,SAAI,EAAE,SAAK,oBAAI,8BAA8B,CAAC;AAC9C;AAAA,EACF,WAAW,gBAAgB,YAAY,QAAQ;AAC7C,oBAAAA,SAAI,EAAE;AAAA,UACJ;AAAA,QACE,8EAA0E,qBAAK,eAAe,CAAC;AAAA,MACjG;AAAA,IACF;AACA;AAAA,EACF;AAEA,QAAM,aAAa,gBAAgB,YAAY,WAAW,iBAAiB;AAC3E,MAAI;AAEF,UAAM,kBAAkB,UAAU;AAAA,EACpC,SAAS,GAAG;AACV,oBAAAA,aAAI,oBAAI,qCAAqC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK;AAChE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,kBAAAA,aAAI,sBAAM,wCAAoC,qBAAK,UAAU,CAAC,GAAG,CAAC,EAAE,QAAQ;AAC9E;AAYA,eAAe,kBAAkB,UAAuE;AAEtG,MAAI,KAAC,uBAAW,QAAQ,GAAG;AACzB,YAAQ,IAAI,iCAAiC,QAAQ,EAAE;AAEvD,cAAM,qBAAM,OAAO,CAAC,SAAS,gDAAgD,QAAQ,CAAC;AAAA,EACxF,OAAO;AACL,YAAQ,IAAI,4CAA4C,QAAQ,EAAE;AAAA,EACpE;AAGA,MAAI,QAAQ,IAAI,IAAI;AAIlB,YAAQ,IAAI,yCAAyC;AACrD,UAAM,aAAS,aAAAE,MAAS,UAAU,MAAM;AACxC,2BAAO,QAAQ,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACjD,OAAO;AAEL,YAAQ,IAAI,oDAAoD;AAChE,cAAM,qBAAM,OAAO,CAAC,MAAM,GAAG,EAAE,KAAK,SAAS,CAAC;AAAA,EAEhD;AAEA,QAAM,WAAW,UAAU,SAAmB;AAC5C,eAAO,qBAAM,WAAW,CAAC,YAAY,GAAG,IAAI,GAAG,EAAE,KAAK,SAAS,CAAC;AAAA,EAClE;AAEA,UAAQ,IAAI,6BAA6B,OAAO,KAAK;AACrD,QAAM,SAAS,WAAW,OAAO;AACjC,QAAM,SAAS,YAAY,OAAO;AACpC;;;ACpIA,IAAAE,gBAA6B;AAC7B,IAAAC,iBAAgD;AAChD,IAAAC,cAAgB;AAChB,IAAAC,kBAAoB;AAGpB,eAAsB,cAAc,SAAiB,MAAgC;AAEnF,QAAM,cAAc,UAAM,gBAAAC;AAAA,IACxB;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,0DAAsD,0BAAM,oBAAI,YAAY,CAAC,CAAC;AAAA,MACvF,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,wBAAAC,SAAI,EAAE,SAAK,oBAAI,oEAAoE,CAAC;AACpF,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ;AACf,oBAAAA,SAAI,EAAE,SAAK,oBAAI,8BAA8B,CAAC;AAC9C;AAAA,EACF,WAAW,CAAC,YAAY,KAAK;AAC3B,oBAAAA,SAAI,EAAE,SAAK,oBAAI,6CAAyC,qBAAK,UAAU,CAAC,SAAS,CAAC;AAClF;AAAA,EACF;AAGA,MAAI;AACF,cAAM,4BAAa,YAAY,EAAE,KAAK,QAAQ,CAAC;AAC/C,oBAAAA,SAAI,EAAE,YAAQ,sBAAM,6BAA6B,CAAC;AAAA,EACpD,QAAQ;AACN,oBAAAA,SAAI,EAAE;AAAA,UACJ;AAAA,QACE,wFAAoF,qBAAK,UAAU,CAAC;AAAA,MACtG;AAAA,IACF;AAAA,EACF;AACF;;;AC3CA,IAAAC,mBAAwB;AACxB,IAAAC,eAA6D;AAE7D,IAAAC,iBAAyC;AACzC,IAAAC,cAAgB;AAEhB,IAAAC,kBAAoB;AAEpB,eAAsB,cAAc,SAA8C;AAGhF,iBAAe,SAAS,KAAgC;AACtD,UAAM,UAAU,UAAM,0BAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,UAAM,QAAQ,MAAM,QAAQ;AAAA,MAC1B,QAAQ,IAAI,YAAU;AACpB,cAAM,UAAM,aAAAC,SAAY,KAAK,OAAO,IAAI;AACxC,eAAO,OAAO,YAAY,IAAI,SAAS,GAAG,IAAI;AAAA,MAChD,CAAC;AAAA,IACH;AACA,WAAO,MAAM,KAAK;AAAA,EACpB;AACA,QAAM,WAAW,MAAM,SAAS,OAAO;AACvC,QAAM,WAAW,SAEd,OAAO,OAAK,EAAE,SAAS,MAAM,CAAC,EAI9B,IAAI,WAAK,uBAAS,SAAS,CAAC,EAAE,WAAW,kBAAK,mBAAM,GAAG,CAAC;AAC3D,QAAM,aAAa,SAAS,IAAI,OAAK;AACnC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAI;AACJ,MAAI,SAAS,WAAW,GAAG;AAEzB,oBAAAC,aAAI,uBAAO,+BAA+B,OAAO,yDAAyD,CAAC,EAAE,KAAK;AAClH,cAAU;AAAA,EACZ,WAAW,SAAS,WAAW,GAAG;AAEhC,cAAU,SAAS,CAAC;AACpB,oBAAAA,SAAI,EAAE,QAAQ,UAAU,OAAO,qDAAqD;AAAA,EACtF,OAAO;AAGL,UAAM,UAAU,UAAM,gBAAAC;AAAA,MACpB;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF;AAAA,MACA;AAAA,QACE,UAAU,MAAM;AACd,0BAAAD,SAAI,EAAE,SAAK,oBAAI,sBAAsB,CAAC;AACtC,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AACA,cAAU,QAAQ;AAClB,oBAAAA,aAAI,sBAAM,cAAU,qBAAK,OAAO,CAAC,iCAAiC,CAAC,EAAE,QAAQ;AAAA,EAC/E;AAEA,SAAO;AACT;;;ACrEA,IAAAE,aAAyE;AACzE,IAAAC,mBAA0B;AAC1B,sBAAqB;AACrB,gBAAuB;AACvB,IAAAC,eAAiC;AAEjC,mBAAiC;AACjC,IAAAC,iBAA8C;AAC9C,IAAAC,cAAgB;AAChB,IAAAC,kBAAoB;AAGpB,IAAM,YAAY;AAAA,EAChB;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,EACT;AACF;AASA,eAAsB,eAAe,MAAoC;AACvE,MAAI;AACJ,MAAI,KAAK,UAAU;AAEjB,mBAAe,KAAK;AAAA,EACtB,OAAO;AAEL,UAAM,UAAU,UAAM,gBAAAC;AAAA,MACpB;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF;AAAA,MACA;AAAA,QACE,UAAU,MAAM;AACd,0BAAAC,SAAI,EAAE,SAAK,oBAAI,sBAAsB,CAAC;AACtC,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AACA,mBAAe,QAAQ;AAAA,EACzB;AAGA,QAAM,aAAa;AACnB,QAAM,SAAS,KAAK,UAAU;AAG9B,MAAI;AACJ,MAAI,aAAa,SAAS,GAAG,GAAG;AAI9B,sBAAkB;AAAA,EACpB,WAAW,aAAa,SAAS,GAAG,GAAG;AAGrC,sBAAkB,UAAU,YAAY;AAAA,EAC1C,OAAO;AAML,sBAAkB,4DAA4D,YAAY;AAAA,EAC5F;AACA,QAAM,cAAc,GAAG,eAAe,IAAI,MAAM;AAEhD,kBAAAA,aAAI,sBAAM,cAAU,qBAAK,WAAW,CAAC,oCAAoC,CAAC,EAAE,QAAQ;AAEpF,SAAO;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACF;AAEA,eAAsB,aACpB,UACA,SACA,YACA,kBACA,YACe;AAEf,QAAM,sBAAkB,YAAAA,SAAI,2BAA2B,EAAE,MAAM;AAE/D,MAAI;AAEF,UAAM,aAAS,4BAAY,aAAAC,UAAS,kBAAO,GAAG,aAAa,CAAC;AAI5D,cAAM,+BAAiB,SAAS,KAAK;AAAA,MACnC,OAAO;AAAA,MACP,KAAK;AAAA,IACP,CAAC;AAID,QAAI,KAAC,uBAAW,MAAM,SAAK,wBAAY,MAAM,EAAE,WAAW,GAAG;AAC3D,YAAM,IAAI,MAAM,8EAA8E;AAAA,IAChG;AAEA,QAAI,kBAAkB;AAIpB,iCAAO,aAAAA,MAAS,QAAQ,QAAQ,GAAG,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACrE;AAEA,QAAI,YAAY;AAId,iCAAO,aAAAA,MAAS,QAAQ,OAAO,GAAG,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACpE;AAGA,cAAM,sBAAK,QAAQ,SAAS;AAAA,MAC1B,WAAW;AAAA,MACX,cAAc;AAAA,IAChB,CAAC;AAED,QAAI,CAAC,YAAY;AAIf,qCAAW,aAAAA,MAAS,SAAS,SAAS,gBAAgB,OAAG,aAAAA,MAAS,SAAS,SAAS,YAAY,CAAC;AAAA,IACnG;AAGA,2BAAO,QAAQ,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACjD,SAAS,GAAG;AAGV,oBAAgB,KAAK;AACrB,YAAQ,UAAM,oBAAI,EAAE,OAAO,CAAC;AAC5B,YAAQ,UAAM,uBAAO,6CAA6C,CAAC;AACnE,YAAQ;AAAA,UACN;AAAA,QACE;AAAA,MACF;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAI,2BAAW,aAAAA,MAAS,SAAS,UAAU,CAAC,KAAK,eAAe,QAAQ;AAItE,UAAM,oBAAgB,aAAAA,MAAS,SAAS,qBAAqB;AAC7D,UAAM,mBAAmB;AAAA;AAAA;AACzB,cAAM,4BAAU,eAAe,gBAAgB;AAAA,EACjD;AAEA,kBAAgB,WAAO,sBAAM,kBAAkB;AAC/C,kBAAgB,QAAQ;AAC1B;;;AR/JA,eAAsB,OAAsB;AAE1C,QAAM,iBAAa,qBAAAC,SAAqB,GAAG,QAAQ;AAGnD,QAAM,WAAO,oBAAAC,SAAM,QAAQ,IAAI;AAC/B,kBAAAC,QAAQ,SAAS,IAAI;AAErB,MAAI,KAAK,QAAQ;AACf,YAAQ,IAAI;AACZ,oBAAAC,SAAI,EAAE,SAAK,oBAAI,8CAA8C,CAAC;AAAA,EAChE;AAGA,UAAQ,IAAI;AAAA,MAAK,qBAAK,0BAA0B,CAAC,EAAE;AACnD,UAAQ,IAAI;AAAA,CAA2D;AAGvE,QAAM,UAAU,MAAM,iBAAiB,IAAI;AAC3C,UAAQ,IAAI;AAGZ,QAAM,uBAAmB,2BAAW,aAAAC,SAAY,SAAS,QAAQ,CAAC;AAGlE,QAAM,WAAW,MAAM,eAAe,IAAI;AAC1C,UAAQ,IAAI;AAGZ,MAAI,UAAU,MAAM,cAAc,OAAO;AACzC,QAAM,aAAa,YAAY;AAC/B,UAAQ,IAAI;AAEZ,MAAI,CAAC,KAAK,QAAQ;AAEhB,UAAM,aAAa,UAAU,SAAS,YAAY,kBAAkB,UAAU;AAC9E,YAAQ,IAAI;AAAA,EACd;AAEA,MAAI,YAAY,QAAW;AAMzB,cAAU,QAAQ,mBAAM,GAAG;AAAA,EAC7B;AAGA,QAAM,YAAY,MAAM,iBAAiB;AAEzC,MAAI,CAAC,KAAK,QAAQ;AAEhB,UAAM,gBAAgB,SAAS,SAAS,SAAS;AAGjD,UAAM,2BACJ,2BAAW,aAAAA,SAAY,SAAS,SAAS,QAAQ,CAAC,SAAK,2BAAW,aAAAA,SAAY,SAAS,SAAS,aAAa,CAAC;AAChH,QAAI,CAAC,sBAAsB;AACzB,YAAM,wBAAwB,OAAO;AAAA,IACvC;AAAA,EACF;AACA,UAAQ,IAAI;AAEZ,MAAI,kBAAkB;AAEpB,oBAAAD,SAAI,EAAE,QAAQ,uBAAmB,qBAAK,QAAQ,CAAC,cAAc;AAC7D,oBAAAA,SAAI,EAAE;AAAA,UACJ,oBAAI,sCAAkC,qBAAK,QAAQ,CAAC,oDAAoD;AAAA,IAC1G;AACA,YAAQ,IAAI;AAAA,EACd,OAAO;AAGL,UAAM,yBAAqB,2BAAW,aAAAC,SAAY,SAAS,QAAQ,CAAC;AACpE,QAAI,sBAAsB,cAAc,CAAC,KAAK,QAAQ;AACpD,YAAM,gBAAgB,SAAS,OAAO;AACtC,cAAQ,IAAI;AAAA,IACd;AAAA,EACF;AAIA,MAAI,cAAc,KAAK;AACrB,UAAM,mBAAmB,SAAS,IAAI;AACtC,YAAQ,IAAI;AAAA,EACd;AAGA,QAAM,kBAAkB,SAAS,MAAM,UAAU;AACjD,UAAQ,IAAI;AAGZ,QAAM,cAAc,SAAS,IAAI;AACjC,UAAQ,IAAI;AAEZ,kBAAAD,aAAI,sBAAM,iBAAiB,CAAC,EAAE,QAAQ;AAEtC,UAAQ,IAAI;AAAA,MAAK,2BAAO,sBAAM,cAAc,CAAC,CAAC;AAAA,CAAI;AAElD,QAAM,iBAAa,uBAAS,QAAQ,IAAI,GAAG,OAAO;AAClD,QAAM,SAAS,eAAe,QAAQ,gBAAgB,GAAG,UAAU;AAGnE,MAAI,eAAe,IAAI;AACrB,YAAQ,IAAI,mBAAe,yBAAK,qBAAK,IAAI,CAAC,CAAC,iBAAa,yBAAK,qBAAK,UAAU,CAAC,CAAC,qBAAqB;AAAA,EACrG;AACA,UAAQ,IAAI,WAAO,yBAAK,qBAAK,MAAM,CAAC,CAAC,uCAAmC,yBAAK,qBAAK,QAAQ,CAAC,CAAC,YAAY;AACxG,UAAQ,IAAI,EAAE;AAChB;","names":["import_fs","import_path","import_colors","import_ora","import_prompts","prompts","ora","import_colors","import_ora","import_prompts","joinPath","ora","prompts","resolvePath","parsePath","import_colors","import_ora","import_prompts","prompts","ora","import_fs","import_path","import_colors","import_ora","import_prompts","resolvePath","ora","prompts","import_fs","import_path","import_execa","import_colors","import_ora","import_prompts","ora","resolvePath","joinPath","prompts","import_execa","import_colors","import_ora","import_prompts","prompts","ora","import_promises","import_path","import_colors","import_ora","import_prompts","resolvePath","ora","prompts","import_fs","import_promises","import_path","import_colors","import_ora","import_prompts","prompts","ora","joinPath","detectPackageManager","yargs","prompts","ora","resolvePath"]}