diff --git a/dist/cli/index.js b/dist/cli/index.js index bea7bcc..5bcf4ba 100644 --- a/dist/cli/index.js +++ b/dist/cli/index.js @@ -785,7 +785,6 @@ let store = (0, _actions.initFiles)(_fileWatcher2.default.watched(), _defaultSto // If building for production, close gaze and exit process once initFiles is done. if (_parseArgs2.default.production) { _fileWatcher2.default.close(); - process.exit(); } /** @module cli/gaze */ diff --git a/dist/cli/index.js.map b/dist/cli/index.js.map index 2f837f1..81b2b5d 100644 --- a/dist/cli/index.js.map +++ b/dist/cli/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["webpack:///webpack/bootstrap 7ca66d3a22fb8a8e58c7","webpack:///external \"path\"","webpack:///src/cli/utils.js","webpack:///external \"chalk\"","webpack:///external \"fs-extra\"","webpack:///src/cli/parseArgs.js","webpack:///external \"webpack\"","webpack:///src/cli/defaultStore.js","webpack:///src/cli/handleTemplates.js","webpack:///src/cli/requireTemplates.js","webpack:///src/cli/index.js","webpack:///config/devServer.config.js","webpack:///src/cli/actions.js","webpack:///src/cli/fileWatcher.js","webpack:///src/cli/generateConfig.js","webpack:///src/cli/handleHTML.js","webpack:///src/cli/handleKSS.js","webpack:///src/cli/requireExternal.js","webpack:///src/cli/server.js","webpack:///src/defaultConfig/huron.config.js","webpack:///src/defaultConfig/webpack.config.js","webpack:///./templates/hotTemplate.js","webpack:///external \"commander\"","webpack:///external \"gaze\"","webpack:///external \"html-webpack-plugin\"","webpack:///external \"immutable\"","webpack:///external \"kss\"","webpack:///external \"lodash/isEqual\"","webpack:///external \"opn\"","webpack:///external \"url\"","webpack:///external \"webpack-dev-server\""],"sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"../\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 30);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 7ca66d3a22fb8a8e58c7","module.exports = require(\"path\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"path\"\n// module id = 0\n// module chunks = 0","/** @module cli/utilities */\nimport path from 'path';\nimport fs from 'fs-extra';\nimport chalk from 'chalk';\n\nconst cwd = process.cwd(); // Current working directory\n\n/**\n * Ensure predictable data structure for KSS section data\n *\n * @function normalizeSectionData\n * @param {object} section - section data\n * @return {object} section data\n */\nexport function normalizeSectionData(section) {\n const data = section.data || section;\n\n if (!data.referenceURI || '' === data.referenceURI) {\n data.referenceURI = section.referenceURI();\n }\n\n return data;\n}\n\n/**\n * Ensure predictable data structure for KSS section data\n *\n * @function writeSectionData\n * @param {object} store - data store\n * @param {object} section - section data\n * @param {string} sectionPath - output destination for section data file\n */\nexport function writeSectionData(store, section, sectionPath = false) {\n let outputPath = sectionPath;\n let sectionFileInfo;\n\n if (!outputPath && {}.hasOwnProperty.call(section, 'kssPath')) {\n sectionFileInfo = path.parse(section.kssPath);\n outputPath = path.join(\n sectionFileInfo.dir,\n `${sectionFileInfo.name}.json`\n );\n }\n\n // Output section data\n if (outputPath) {\n return writeFile(\n section.referenceURI,\n 'section',\n outputPath,\n JSON.stringify(section),\n store\n );\n }\n\n console.warn( // eslint-disable-line no-console\n chalk.red(`Failed to write section data for ${section.referenceURI}`)\n );\n return false;\n}\n\n/**\n * Find .json from a template file or vice versa\n *\n * @function getTemplateDataPair\n * @param {object} file - file object from path.parse()\n * @param {object} section - KSS section data\n * @return {string} relative path to module JSON file\n */\nexport function getTemplateDataPair(file, section, store) {\n const huron = store.get('config');\n const kssDir = matchKssDir(file.dir, huron);\n\n if (kssDir) {\n const componentPath = path.relative(\n path.resolve(cwd, kssDir),\n file.dir\n );\n const partnerType = '.json' === file.ext ? 'template' : 'data';\n const partnerExt = '.json' === file.ext ?\n huron.get('templates').extension :\n '.json';\n\n const pairPath = path.join(\n componentPath,\n generateFilename(\n section.referenceURI,\n partnerType,\n partnerExt,\n store\n )\n );\n\n return `./${pairPath}`;\n }\n\n return false;\n}\n\n/**\n * Normalize a section title for use as a filename\n *\n * @function normalizeHeader\n * @param {string} header - section header extracted from KSS documentation\n * @return {string} modified header, lowercase and words separated by dash\n */\nexport function normalizeHeader(header) {\n return header\n .toLowerCase()\n .replace(/\\s?\\W\\s?/g, '-');\n}\n\n/**\n * Wrap html in required template tags\n *\n * @function wrapMarkup\n * @param {string} content - html or template markup\n * @param {string} templateId - id of template (should be section reference)\n * @return {string} modified HTML\n */\nexport function wrapMarkup(content, templateId) {\n return `\n\n\\n`;\n}\n\n/**\n * Generate a filename based on referenceURI, type and file object\n *\n * @function generateFilename\n * @param {string} id - The name of the file (with extension).\n * @param {string} type - the type of file output\n * @param {object} ext - file extension\n * @param {store} store - data store\n * @return {string} Path to output file, relative to ouput dir (can be use in require statements)\n */\nexport function generateFilename(id, type, ext, store) {\n // Type of file and its corresponding extension(s)\n const types = store.get('types');\n const outputExt = '.scss' !== ext ? ext : '.html';\n\n /* eslint-disable */\n if (-1 === types.indexOf(type)) {\n console.log(`Huron data ${type} does not exist`);\n return false;\n }\n /* eslint-enable */\n\n return `${id}-${type}${outputExt}`;\n}\n\n/**\n * Copy an HTML file into the huron output directory.\n *\n * @function writeFile\n * @param {string} id - The name of the file (with extension).\n * @param {string} content - The content of the file to write.\n * @param {string} type - the type of file output\n * @param {object} store - The data store\n * @return {string} Path to output file, relative to ouput dir (can be use in require statements)\n */\nexport function writeFile(id, type, filepath, content, store) {\n const huron = store.get('config');\n const file = path.parse(filepath);\n const filename = generateFilename(id, type, file.ext, store);\n const kssDir = matchKssDir(filepath, huron);\n\n if (kssDir) {\n const componentPath = path.relative(\n path.resolve(cwd, kssDir),\n file.dir\n );\n const outputRelative = path.join(\n huron.get('output'),\n componentPath,\n `${filename}`\n );\n const outputPath = path.resolve(cwd, huron.get('root'), outputRelative);\n let newContent = content;\n\n if ('data' !== type && 'section' !== type) {\n newContent = wrapMarkup(content, id);\n }\n\n try {\n fs.outputFileSync(outputPath, newContent);\n console.log(chalk.green(`Writing ${outputRelative}`)); // eslint-disable-line no-console\n } catch (e) {\n console.log(chalk.red(`Failed to write ${outputRelative}`)); // eslint-disable-line no-console\n }\n\n return `./${outputRelative.replace(`${huron.get('output')}/`, '')}`;\n }\n\n return false;\n}\n\n/**\n * Delete a file in the huron output directory\n *\n * @function removeFile\n * @param {string} filename - The name of the file (with extension).\n * @param {object} store - The data store\n * @return {string} Path to output file, relative to ouput dir (can be use in require statements)\n */\nexport function removeFile(id, type, filepath, store) {\n const huron = store.get('config');\n const file = path.parse(filepath);\n const filename = generateFilename(id, type, file.ext, store);\n const kssDir = matchKssDir(filepath, huron);\n\n if (kssDir) {\n const componentPath = path.relative(\n path.resolve(cwd, kssDir),\n file.dir\n );\n const outputRelative = path.join(\n huron.get('output'),\n componentPath,\n `${filename}`\n );\n const outputPath = path.resolve(cwd, huron.get('root'), outputRelative);\n\n try {\n fs.removeSync(outputPath);\n console.log(chalk.green(`Removing ${outputRelative}`)); // eslint-disable-line no-console\n } catch (e) {\n console.log( // eslint-disable-line no-console\n chalk.red(`${outputRelative} does not exist or cannot be deleted`)\n );\n }\n\n return `./${outputRelative.replace(`${huron.get('output')}/`, '')}`;\n }\n\n return false;\n}\n\n/**\n * Write a template for sections\n *\n * @function writeSectionTemplate\n * @param {string} filepath - the original template file\n * @param {object} store - data store\n * @return {object} updated store\n */\nexport function writeSectionTemplate(filepath, store) {\n const huron = store.get('config');\n const sectionTemplate = wrapMarkup(fs.readFileSync(filepath, 'utf8'));\n const componentPath = './huron-assets/section.hbs';\n const output = path.join(\n cwd,\n huron.get('root'),\n componentPath\n );\n\n // Move huron script and section template into huron root\n fs.outputFileSync(output, sectionTemplate);\n console.log(chalk.green(`writing section template to ${output}`)); // eslint-disable-line no-console\n\n return store.set('sectionTemplatePath', componentPath);\n}\n\n/**\n * Request for section data based on section reference\n *\n * @function writeSectionTemplate\n * @param {string} search - key on which to match section\n * @param {field} string - field in which to look to determine section\n * @param {obj} store - sections memory store\n */\nexport function getSection(search, field, store) {\n const sectionValues = store\n .getIn(['sections', 'sectionsByPath'])\n .valueSeq();\n let selectedSection = false;\n\n if (field) {\n selectedSection = sectionValues\n .filter((value) => value[field] === search)\n .get(0);\n } else {\n selectedSection = store.getIn(['sections', 'sectionsByPath', search]);\n }\n\n return selectedSection;\n}\n\n/**\n * Find which configured KSS directory a filepath exists in\n *\n * @function matchKssDir\n * @param {string} filepath - filepath to search for\n * @param {object} huron - huron configuration\n * @return {string} kssMatch - relative path to KSS directory\n */\nexport function matchKssDir(filepath, huron) {\n const kssSource = huron.get('kss');\n // Include forward slash in our test to make sure we're matchin a directory, not a file extension\n const kssMatch = kssSource.filter((dir) => filepath.includes(`/${dir}`));\n\n if (kssMatch.length) {\n return kssMatch[0];\n }\n\n return false;\n}\n\n/**\n * Merge JSON files for css modules classnames in a provided directory\n *\n * @function mergeClassnameJSON\n * @param {string} directory - directory containing classname JSON files\n *\n * @return {object} classnamesMerged - merged classnames. contents of each JSON file is nested within\n * the returned object by filename. (e.g. article.json -> { article: {...json contents}})\n */\nexport function mergeClassnameJSON(directory) {\n let files;\n\n // If no config is provided, return immediately\n if (!directory) {\n return {};\n }\n\n // Try to read through classnames directory\n try {\n files = fs.readdirSync(directory);\n } catch (e) {\n console.warn(chalk.red(e));\n }\n\n // Merge classname json files\n const classNamesMerged = files.reduce((acc, file) => {\n const fileInfo = path.parse(file);\n let classNames = {};\n\n if ('.json' === fileInfo.ext) {\n try {\n const contents = fs.readFileSync(\n path.join(directory, file),\n 'utf8'\n );\n classNames = JSON.parse(contents);\n } catch (e) {\n console.warn(chalk.red(e));\n }\n }\n\n return Object.assign({}, acc, { [fileInfo.name]: classNames });\n }, {});\n\n return classNamesMerged;\n}\n\n/**\n * Remove the trailing slash from a provided directory\n *\n * @function removeTrailingSlash\n * @param {string} directory - directory path\n * @return {string} directory - directory path with trailing slash removed\n */\nexport function removeTrailingSlash(directory) {\n if ('/' === directory.slice(-1)) {\n return directory.slice(0, -1);\n }\n\n return directory;\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/utils.js","module.exports = require(\"chalk\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"chalk\"\n// module id = 2\n// module chunks = 0","module.exports = require(\"fs-extra\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"fs-extra\"\n// module id = 3\n// module chunks = 0","/** @module cli/parse-arguments */\n/* eslint-disable space-unary-ops */\n\nimport program from 'commander';\nimport path from 'path';\n\n// Requires\n/** @global */\n\n/**\n * Process huron CLI arguments\n *\n * @function parseArgs\n * @example node huron/dist/cli/huron-cli.js --config 'client/config/webpack.config.js' --production\n */\nfunction parseArgs() {\n const envArg = {};\n\n process.argv = process.argv.filter((arg) => {\n if (-1 !== arg.indexOf('--env')) {\n const envParts = arg\n .split('.')[1]\n .split('=');\n\n envArg[envParts[0]] = envParts[1] || true;\n return false;\n }\n\n return true;\n });\n\n program.version('1.0.1')\n .option(\n '-c, --huron-config [huronConfig]',\n '[huronConfig] for all huron options',\n path.resolve(__dirname, '../defaultConfig/huron.config.js')\n )\n .option(\n '-w, --webpack-config [webpackConfig]',\n '[webpackConfig] for all webpack options',\n path.resolve(__dirname, '../defaultConfig/webpack.config.js')\n )\n .option('-p, --production', 'compile assets once for production');\n\n program.env = envArg;\n\n // Only parse if we're not running tests\n if (\n ! process.env.npm_lifecycle_event ||\n 'test' !== process.env.npm_lifecycle_event\n ) {\n program.parse(process.argv);\n }\n}\n\nparseArgs();\n/* eslint-enable */\n\nexport default program;\n\n\n\n// WEBPACK FOOTER //\n// src/cli/parseArgs.js","module.exports = require(\"webpack\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"webpack\"\n// module id = 5\n// module chunks = 0","import { Map } from 'immutable';\n\nimport generateConfig from './generateConfig';\nimport { mergeClassnameJSON } from './utils';\n// Create initial data structure\n\n// Merge Huron default webpack config with user config\nconst config = generateConfig();\n\n// Make sure the kss option is represented as an array\nconfig.huron.kss = [].concat(config.huron.kss);\n\n/* eslint-disable */\n/**\n * Initial structure for immutable data store\n *\n * @global\n */\nconst defaultStore = Map({\n types: [\n 'template',\n 'data',\n 'description',\n 'section',\n 'prototype',\n 'sections-template',\n ],\n config: Map(config.huron),\n classNames: mergeClassnameJSON(config.huron.classNames),\n sections: Map({\n sectionsByPath: Map({}),\n sectionsByURI: Map({}),\n sorted: {},\n }),\n templates: Map({}),\n prototypes: Map({}),\n sectionTemplatePath: '',\n referenceDelimiter: '.',\n});\n/* eslint-enable */\n\nexport { defaultStore, config };\n\n\n\n// WEBPACK FOOTER //\n// src/cli/defaultStore.js","/** @module cli/template-handler */\nimport path from 'path';\nimport fs from 'fs-extra';\nimport chalk from 'chalk';\n\nimport * as utils from './utils';\n\n/**\n * Handle update of a template or data (json) file\n *\n * @function updateTemplate\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} section - contains KSS section data\n * @param {object} store - memory store\n * @return {object} updated memory store\n */\nexport function updateTemplate(filepath, section, store) {\n const file = path.parse(filepath);\n const pairPath = utils.getTemplateDataPair(file, section, store);\n const type = '.json' === file.ext ? 'data' : 'template';\n const newSection = section;\n const newStore = store;\n let content = false;\n\n try {\n content = fs.readFileSync(filepath, 'utf8');\n } catch (e) {\n console.log(chalk.red(`${filepath} does not exist`));\n }\n\n if (content) {\n const requirePath = utils.writeFile(\n newSection.referenceURI,\n type,\n filepath,\n content,\n newStore\n );\n newSection[`${type}Path`] = requirePath;\n\n if ('template' === type) {\n newSection.templateContent = content;\n\n // Rewrite section data with template content\n newSection.sectionPath = utils.writeSectionData(newStore, newSection);\n }\n\n return newStore\n .setIn(\n ['templates', requirePath],\n pairPath\n )\n .setIn(\n ['sections', 'sectionsByPath', newSection.kssPath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', newSection.referenceURI],\n newSection\n );\n }\n\n return newStore;\n}\n\n/**\n * Handle removal of a template or data (json) file\n *\n * @function deleteTemplate\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} section - contains KSS section data\n * @param {object} store - memory store\n * @return {object} updated memory store\n */\nexport function deleteTemplate(filepath, section, store) {\n const file = path.parse(filepath);\n const type = '.json' === file.ext ? 'data' : 'template';\n const newSection = section;\n const newStore = store;\n\n // Remove partner\n const requirePath = utils.removeFile(\n newSection.referenceURI,\n type,\n filepath,\n newStore\n );\n delete newSection[`${type}Path`];\n\n return newStore\n .deleteIn(['templates', requirePath])\n .setIn(\n ['sections', 'sectionsByPath', newSection.kssPath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', newSection.referenceURI],\n newSection\n );\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/handleTemplates.js","/** @module cli/require-templates */\nimport path from 'path';\nimport fs from 'fs-extra';\n\n// We need to prepend this to the browser script as a string but still want to transpile it,\n// hence loading it using `raw-loader` so we receive a string from webpack\n/* eslint-disable */\nimport hotTemplate from '!raw-loader!babel-loader!../../templates/hotTemplate';\n/* eslint-enable */\n\nconst cwd = process.cwd();\nconst huronScript = fs.readFileSync(\n path.join(__dirname, '../web/index.js'),\n 'utf8'\n);\n\n/**\n * Write code for requiring all generated huron assets\n *\n * @function requireTemplates\n * @param {object} store - memory store\n */\nexport const requireTemplates = function requireTemplates(store) {\n const huron = store.get('config');\n const outputPath = path.join(cwd, huron.get('root'), 'huron-assets');\n // These will be used to replace strings in the hotTemplate.\n // In order to accurately replace strings but still keep things parseable by eslint and babel,\n // each replaceable value should be referenced in `hotTemplate.js` under the `hotScope` object.\n // For example, if you need to replace a string with a value passed in from the CLI called `userVariable`,\n // you would reference that string in `hotTemplate.js` with `hotScope.userVariable`.\n const hotVariableScope = {\n sectionTemplatePath: `'${huron.get('sectionTemplate')}'`,\n requireRegex: new RegExp(`\\\\.html|\\\\.json|\\\\${\n huron.get('templates').extension\n }$`),\n requirePath: `'../${huron.get('output')}'`,\n };\n const hotTemplateTransformed = Object.keys(hotVariableScope)\n .reduce(\n (acc, curr) => acc.replace(\n new RegExp(`hotScope.${curr}`, 'g'),\n hotVariableScope[curr]\n ), hotTemplate\n );\n\n // Write the contents of this script.\n fs.outputFileSync(\n path.join(outputPath, 'index.js'),\n hotTemplateTransformed\n );\n fs.outputFileSync(\n path.join(outputPath, 'insertNodes.js'),\n huronScript\n );\n};\n\n/**\n * Output entire data store to a JS object and handle if any KSS data has changed\n *\n * @function writeStore\n * @param {object} store - memory store\n * @param {string} changed - filepath of changed KSS section, if applicable\n */\nexport const writeStore = function writeStore(store, newStore = false) {\n const updatedStore = newStore || store;\n const huron = updatedStore.get('config');\n const outputPath = path.join(cwd, huron.get('root'), 'huron-assets');\n\n // Write updated data store\n fs.outputFileSync(\n path.join(outputPath, 'huron-store.js'),\n `module.exports = ${JSON.stringify(updatedStore.toJSON())}`\n );\n};\n\n\n\n\n// WEBPACK FOOTER //\n// src/cli/requireTemplates.js","// Local imports\nimport chalk from 'chalk';\n\nimport {\n initFiles,\n updateFile,\n deleteFile,\n updateClassNames,\n} from './actions';\nimport { requireTemplates, writeStore } from './requireTemplates';\nimport { matchKssDir } from './utils';\nimport program from './parseArgs';\nimport startWebpack from './server';\nimport { defaultStore, config } from './defaultStore';\nimport gaze from './fileWatcher';\n\n/**\n * Initialize data store with files from gaze and original data structure\n *\n * @global\n */\nconst huron = defaultStore.get('config');\nlet store = initFiles(gaze.watched(), defaultStore);\n\nrequireTemplates(store);\nwriteStore(store);\n\n// If building for production, close gaze and exit process once initFiles is done.\nif (program.production) {\n gaze.close();\n process.exit();\n}\n\n/** @module cli/gaze */\ngaze.on('all', (event, filepath) => {\n store = updateClassNames(filepath, store);\n writeStore(store);\n});\n\n/**\n * Anonymous handler for Gaze 'changed' event indicating a file has changed\n *\n * @callback changed\n * @listens gaze:changed\n * @param {string} filepath - absolute path of changed file\n */\ngaze.on('changed', (filepath) => {\n if (matchKssDir(filepath, huron)) {\n store = updateFile(filepath, store);\n }\n\n console.log(chalk.green(`${filepath} updated!`));\n});\n\n/**\n * Anonymous handler for Gaze 'added' event indicating a file has been added to the watched directories\n *\n * @callback added\n * @listens gaze:added\n * @param {string} filepath - absolute path of changed file\n */\ngaze.on('added', (filepath) => {\n if (matchKssDir(filepath, huron)) {\n store = updateFile(filepath, store);\n writeStore(store);\n }\n\n console.log(chalk.blue(`${filepath} added!`));\n});\n\n/**\n * Anonymous handler for Gaze 'renamed' event indicating a file has been renamed\n *\n * @callback renamed\n * @listens gaze:renamed\n * @param {string} filepath - absolute path of changed file\n */\ngaze.on('renamed', (newPath, oldPath) => {\n if (matchKssDir(newPath, huron)) {\n store = deleteFile(oldPath, store);\n store = updateFile(newPath, store);\n writeStore(store);\n }\n\n console.log(chalk.blue(`${newPath} added!`));\n});\n\n/**\n * Anonymous handler for Gaze 'deleted' event indicating a file has been removed\n *\n * @callback deleted\n * @listens gaze:deleted\n * @param {string} filepath - absolute path of changed file\n */\ngaze.on('deleted', (filepath) => {\n if (matchKssDir(filepath, huron)) {\n store = deleteFile(filepath, store);\n writeStore(store);\n }\n\n console.log(chalk.red(`${filepath} deleted`));\n});\n\n// Start webpack or build for production\nstartWebpack(config);\n\n\n\n// WEBPACK FOOTER //\n// src/cli/index.js","export default (huron) => ({\n hot: true,\n quiet: false,\n noInfo: false,\n stats: {\n colors: true,\n hash: false,\n version: false,\n assets: false,\n chunks: false,\n modules: false,\n reasons: false,\n children: false,\n source: false,\n },\n contentBase: huron.root,\n overlay: true,\n publicPath: `http://localhost:${huron.port}/${huron.root}`,\n});\n\n\n\n// WEBPACK FOOTER //\n// config/devServer.config.js","/** @module cli/actions */\n\n// Imports\nimport path from 'path';\nimport chalk from 'chalk';\nimport isEqual from 'lodash/isEqual';\n\nimport {\n updateHTML,\n deleteHTML,\n updatePrototype,\n deletePrototype,\n} from './handleHTML';\nimport { updateTemplate, deleteTemplate } from './handleTemplates';\nimport { updateKSS, deleteKSS } from './handleKSS';\nimport * as utils from './utils';\n\n/**\n * Recursively loop through initial watched files list from Gaze.\n *\n * @param {object} data - object containing directory and file paths\n * @param {object} store - memory store\n * @return {object} newStore - map object of entire data store\n */\nexport function initFiles(data, store, depth = 0) {\n const type = Object.prototype.toString.call(data);\n const huron = store.get('config');\n let newStore = store;\n let info;\n let files;\n\n switch (type) {\n case '[object Object]':\n files = Object.keys(data);\n newStore = files.reduce(\n (prevStore, file) => initFiles(data[file], prevStore, depth),\n newStore\n );\n break;\n\n case '[object Array]':\n newStore = data.reduce(\n (prevStore, file) => initFiles(file, prevStore, depth),\n newStore\n );\n break;\n\n case '[object String]':\n info = path.parse(data);\n\n // Only call update if data is a filepath and it's within the KSS source directory\n if (info.ext && !data.includes(huron.get('classNames'))) {\n newStore = updateFile(data, store);\n }\n break;\n\n default:\n break;\n }\n\n return newStore;\n}\n\n/**\n * Logic for updating and writing file information based on file type (extension)\n *\n * @param {string} filepath - path to updated file. usually passed in from Gaze\n * @param {object} store - memory store\n * @return {object} store - map object of map object of entire data store\n */\nexport function updateFile(filepath, store) {\n const huron = store.get('config');\n const file = path.parse(filepath);\n let field;\n let section;\n\n if (filepath.includes(huron.get('sectionTemplate'))) {\n return utils.writeSectionTemplate(filepath, store);\n }\n\n switch (file.ext) {\n // Plain HTML template, external\n case '.html':\n section = utils.getSection(file.base, 'markup', store);\n\n if (section) {\n return updateHTML(filepath, section, store);\n } else if (\n file.dir.includes('prototypes') &&\n file.name.includes('prototype-')\n ) {\n return updatePrototype(filepath, store);\n }\n\n console.log(chalk.red(`Failed to write file: ${file.name}`));\n break;\n\n // Handlebars template, external\n case huron.get('templates').extension:\n case '.json':\n field = ('.json' === file.ext) ? 'data' : 'markup';\n section = utils.getSection(file.base, field, store);\n\n if (section) {\n return updateTemplate(filepath, section, store);\n }\n\n console.log( // eslint-disable-line no-console\n chalk.red(`Could not find associated KSS section for ${filepath}`)\n );\n break;\n\n // KSS documentation (default extension is `.css`)\n // Will also output a template if markup is inline\n // Note: inline markup does _not_ support handlebars currently\n case huron.get('kssExtension'):\n return updateKSS(filepath, store);\n\n // This should never happen if Gaze is working properly\n default:\n return store;\n }\n\n return store;\n}\n\n/**\n * Logic for deleting file information and files based on file type (extension)\n *\n * @param {string} filepath - path to updated file. usually passed in from Gaze\n * @param {object} store - memory store\n * @return {object} newStore - map object of map object of entire data store\n */\nexport function deleteFile(filepath, store) {\n const huron = store.get('config');\n const file = path.parse(filepath);\n let field = '';\n let section = null;\n let newStore = store;\n\n switch (file.ext) {\n // Plain HTML template, external\n case '.html':\n section = utils.getSection(file.base, 'markup', store);\n\n if (section) {\n newStore = deleteHTML(filepath, section, store);\n } else if (\n file.dir.includes('prototypes') &&\n file.name.includes('prototype-')\n ) {\n newStore = deletePrototype(filepath, store);\n }\n break;\n\n case huron.get('templates').extension:\n case '.json':\n field = ('.json' === file.ext) ? 'data' : 'markup';\n section = utils.getSection(file.base, field, store);\n\n if (section) {\n newStore = deleteTemplate(filepath, section, store);\n }\n break;\n\n case huron.get('kssExtension'):\n section = utils.getSection(filepath, false, store);\n\n if (section) {\n newStore = deleteKSS(filepath, section, store);\n }\n break;\n\n default:\n console.warn( // eslint-disable-line no-console\n chalk.red(`Could not delete: ${file.name}`)\n );\n break;\n }\n\n return newStore;\n}\n\n/**\n * Logic for updating localized classnames from CSS modules\n *\n * @param {string} filepath - path to updated file. usually passed in from Gaze\n * @param {object} store - memory store\n *\n * @return void\n */\nexport function updateClassNames(filepath, store) {\n const classNamesPath = store.getIn(['config', 'classNames']);\n\n if (filepath.includes(classNamesPath)) {\n const oldClassnames = store.get('classNames');\n const newClassnames = utils.mergeClassnameJSON(classNamesPath);\n\n if (!isEqual(oldClassnames, newClassnames)) {\n return store.set('classNames', newClassnames);\n }\n }\n\n return store;\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/actions.js","import { Gaze } from 'gaze';\nimport path from 'path';\n\nimport { removeTrailingSlash } from './utils';\nimport { defaultStore } from './defaultStore';\n\n/**\n * Huron configuration object\n *\n * @global\n */\nconst huron = defaultStore.get('config');\n\n/**\n * Available file extensions. Extensions should not include the leading '.'\n *\n * @global\n */\nexport const extensions = [\n huron.get('kssExtension'),\n huron.get('templates').extension,\n 'html',\n 'json',\n].map((extension) => extension.replace('.', ''));\n\n// Generate watch list for Gaze, start gaze\nexport const watchedFiles = [];\n\n// Watch section template\nwatchedFiles.push(path.resolve(huron.get('sectionTemplate')));\n\n// Watch cssmodules classname files (if they exist)\nif (huron.get('classNames')) {\n watchedFiles.push(\n `${path.resolve(huron.get('classNames'))}/*.json`\n );\n}\n\n// Watch all provided kss directories\nhuron.get('kss').forEach((dir) => {\n watchedFiles.push(\n `${removeTrailingSlash(dir)}/**/*.+(${extensions.join('|')})`\n );\n});\n\n/**\n * Gaze instance for watching all files, including KSS, html, hbs/template, and JSON\n *\n * @global\n */\nconst gaze = new Gaze(watchedFiles);\n\nexport default gaze;\n\n\n\n// WEBPACK FOOTER //\n// src/cli/fileWatcher.js","/** @module cli/generate-config */\nimport path from 'path';\nimport url from 'url';\nimport fs from 'fs-extra';\nimport webpack from 'webpack';\nimport HTMLWebpackPlugin from 'html-webpack-plugin';\n\nimport program from './parseArgs';\nimport requireExternal from './requireExternal';\nimport defaultWebpack from '../defaultConfig/webpack.config';\nimport defaultHuron from '../defaultConfig/huron.config';\n\nconst cwd = process.cwd();\n\n// Require configs passed in by user from CLI\nlet defaultConfig = false;\nconst localConfig = requireExternal(\n path.resolve(program.webpackConfig)\n);\nconst localHuron = requireExternal(\n path.resolve(program.huronConfig)\n);\n\n/**\n * Generate a mutant hybrid of the huron default webpack config and your local webpack config\n *\n * @function generateConfig\n * @param {object} config - local webpack config\n * @return {object} newConfig - updated data store\n */\nexport default function generateConfig() {\n let newConfig = localConfig;\n let newHuron = localHuron;\n\n // Execute config function, if provided\n if ('function' === typeof newConfig) {\n newConfig = newConfig(program.env);\n }\n\n // Execute huron config function, if provided\n if ('function' === typeof newHuron) {\n newHuron = newHuron(program.env);\n }\n\n // Merge huron defaults with user settings\n newHuron = Object.assign({}, defaultHuron, newHuron);\n // Use user huron config to modify webpack defaults\n defaultConfig = defaultWebpack(newHuron);\n\n // Set ouput options\n newConfig.output = Object.assign({}, defaultConfig.output, newConfig.output);\n newConfig.output.path = defaultConfig.output.path;\n newConfig.output.publicPath = defaultConfig.output.publicPath;\n\n // configure entries\n newConfig = configureEntries(newHuron, newConfig);\n\n // configure plugins\n newConfig = configurePlugins(newHuron, newConfig);\n\n // configure loaders\n newConfig = configureLoaders(newHuron, newConfig);\n\n // Add HTMLWebpackPlugin for each configured prototype\n newConfig = configurePrototypes(newHuron, newConfig);\n\n // Remove existing devServer settings\n delete newConfig.devServer;\n\n return {\n huron: newHuron,\n webpack: newConfig,\n };\n}\n\n/**\n * Configure and manage webpack entry points\n *\n * @param {object} huron - huron configuration object\n * @param {object} config - webpack configuration object\n * @return {object} newConfig - updated data store\n */\nfunction configureEntries(huron, config) {\n const entry = config.entry[huron.entry];\n const newConfig = config;\n\n newConfig.entry = {};\n if (!program.production) {\n newConfig.entry[huron.entry] = [\n `webpack-dev-server/client?http://localhost:${huron.port}`,\n 'webpack/hot/dev-server',\n path.join(cwd, huron.root, 'huron-assets/index'),\n ].concat(entry);\n } else {\n newConfig.entry[huron.entry] = [\n path.join(cwd, huron.root, 'huron-assets/index'),\n ].concat(entry);\n }\n\n return newConfig;\n}\n\n/**\n * Configure and manage webpack plugins\n *\n * @param {object} huron - huron configuration object\n * @param {object} config - webpack configuration object\n * @return {object} newConfig - updated data store\n */\nfunction configurePlugins(huron, config) {\n const newConfig = config;\n\n newConfig.plugins = config.plugins || [];\n\n if (!program.production) {\n if (newConfig.plugins && newConfig.plugins.length) {\n newConfig.plugins = newConfig.plugins.filter(\n (plugin) => 'HotModuleReplacementPlugin' !== plugin.constructor.name &&\n 'NamedModulesPlugin' !== plugin.constructor.name\n );\n }\n newConfig.plugins = newConfig.plugins\n .concat([\n new webpack.HotModuleReplacementPlugin(),\n new webpack.NamedModulesPlugin(),\n ]);\n }\n\n return newConfig;\n}\n\n/**\n * Configure and manage webpack loaders\n *\n * @param {object} huron - huron configuration object\n * @param {object} config - webpack configuration object\n * @return {object} newConfig - updated data store\n */\nfunction configureLoaders(huron, config) {\n // Manage loaders\n const templatesLoader = huron.templates.rule || {};\n const newConfig = config;\n\n // Make sure we're only using templates loader for files in huron root\n templatesLoader.include = [path.join(cwd, huron.root, huron.output)];\n\n // Normalize module and module.rules\n newConfig.module = newConfig.module || {};\n newConfig.module.rules = newConfig.module.rules ||\n newConfig.module.loaders ||\n [];\n\n // Add default loaders\n newConfig.module.rules = defaultConfig.module.rules\n .concat(\n newConfig.module.rules,\n templatesLoader\n );\n\n return newConfig;\n}\n\n/**\n * Create an HTML webpack plugin for each configured prototype\n *\n * @param {object} huron - huron configuration object\n * @param {object} config - webpack configuration object\n * @return {object} newConfig - updated data store\n */\nfunction configurePrototypes(huron, config) {\n const wrapperTemplate = fs.readFileSync(\n path.join(__dirname, '../../templates/prototypeTemplate.hbs'),\n 'utf8'\n );\n\n const defaultHTMLPluginOptions = {\n title: 'Huron',\n window: huron.window,\n js: [],\n css: [],\n filename: 'index.html',\n template: path.join(\n cwd,\n huron.root,\n 'huron-assets/prototypeTemplate.hbs'\n ),\n inject: false,\n chunks: [huron.entry],\n };\n const newConfig = config;\n\n // Write prototype template file for HTML webpack plugin\n fs.outputFileSync(\n path.join(cwd, huron.root, 'huron-assets/prototypeTemplate.hbs'),\n wrapperTemplate\n );\n\n huron.prototypes.forEach((prototype) => {\n const newPrototype = prototype;\n let opts = {};\n\n // Merge configured settings with default settings\n if ('string' === typeof prototype) {\n opts = Object.assign({}, defaultHTMLPluginOptions, {\n title: prototype,\n filename: `${prototype}.html`,\n });\n } else if (\n 'object' === typeof prototype &&\n {}.hasOwnProperty.call(prototype, 'title')\n ) {\n // Create filename based on configured title if not provided\n if (!prototype.filename) {\n newPrototype.filename = `${prototype.title}.html`;\n }\n\n // Move css assets for this prototype,\n // reset css option with new file paths\n if (prototype.css) {\n newPrototype.css = moveAdditionalAssets(prototype.css, 'css', huron);\n }\n\n // Move js assets for this prototype,\n // reset js option with new file paths\n if (prototype.js) {\n newPrototype.js = moveAdditionalAssets(prototype.js, 'js', huron);\n }\n\n opts = Object.assign({}, defaultHTMLPluginOptions, newPrototype);\n }\n\n // Move global css assets,\n // reset css option with new file paths\n if (huron.css.length) {\n opts.css = opts.css.concat(\n moveAdditionalAssets(huron.css, 'css', huron)\n );\n }\n\n // Move global js assets,\n // reset js option with new file paths\n if (huron.js.length) {\n opts.js = opts.js.concat(\n moveAdditionalAssets(huron.js, 'js', huron)\n );\n }\n\n // Push a new plugin for each configured prototype\n if (Object.keys(opts).length) {\n newConfig.plugins.push(\n new HTMLWebpackPlugin(opts)\n );\n }\n });\n\n return newConfig;\n}\n\n/**\n * Move relative (and local) js and css assets provided in huron options\n *\n * @param {array|string} assets - array of assets or single asset\n * @param {string} subdir - subdirectory in huron root from which to load additional asset\n * @param {object} huron - huron configuration object\n * @return {array} assetResults - paths to js and css assets\n */\nfunction moveAdditionalAssets(assets, subdir = '', huron) {\n const currentAssets = [].concat(assets);\n const assetResults = [];\n\n currentAssets.forEach((asset) => {\n const assetInfo = path.parse(asset);\n const assetURL = url.parse(asset);\n const sourcePath = path.join(cwd, asset);\n const outputPath = path.resolve(cwd, huron.root, subdir, assetInfo.base);\n const loadPath = program.production ?\n path.join(subdir, assetInfo.base) :\n path.join('/', subdir, assetInfo.base); // Use absolute path in development\n let contents = false;\n\n if (\n !path.isAbsolute(asset) &&\n !assetURL.protocol\n ) {\n try {\n contents = fs.readFileSync(sourcePath);\n } catch (e) {\n console.warn(`could not read ${sourcePath}`);\n }\n\n if (contents) {\n fs.outputFileSync(outputPath, contents);\n assetResults.push(loadPath);\n }\n } else {\n assetResults.push(asset);\n }\n });\n\n return assetResults;\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/generateConfig.js","/** @module cli/html-handler */\nimport path from 'path';\nimport fs from 'fs-extra';\n\nimport * as utils from './utils';\n\n/**\n * Handle update of an HMTL template\n *\n * @function updateHTML\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} section - contains KSS section data\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nexport function updateHTML(filepath, section, store) {\n const file = path.parse(filepath);\n const content = fs.readFileSync(filepath, 'utf8');\n const newSection = section;\n\n if (content) {\n newSection.templatePath = utils.writeFile(\n section.referenceURI,\n 'template',\n filepath,\n content,\n store\n );\n newSection.templateContent = content;\n\n // Rewrite section data with template content\n newSection.sectionPath = utils.writeSectionData(store, newSection);\n\n return store\n .setIn(\n ['sections', 'sectionsByPath', section.kssPath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', section.referenceURI],\n newSection\n );\n }\n\n console.log(`File ${file.base} could not be read`);\n return store;\n}\n\n/**\n * Handle removal of an HMTL template\n *\n * @function deleteHTML\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} section - contains KSS section data\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nexport function deleteHTML(filepath, section, store) {\n const newSection = section;\n\n utils.removeFile(\n newSection.referenceURI,\n 'template',\n filepath,\n store\n );\n\n delete newSection.templatePath;\n\n return store\n .setIn(\n ['sections', 'sectionsByPath', section.kssPath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', section.referenceURI],\n newSection\n );\n}\n\n/**\n * Handle update for a prototype file\n *\n * @function updatePrototype\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nexport function updatePrototype(filepath, store) {\n const file = path.parse(filepath);\n const content = fs.readFileSync(filepath, 'utf8');\n\n if (content) {\n const requirePath = utils.writeFile(\n file.name,\n 'prototype',\n filepath,\n content,\n store\n );\n\n return store.setIn(\n ['prototypes', file.name],\n requirePath\n );\n }\n\n console.log(`File ${file.base} could not be read`);\n return store;\n}\n\n/**\n * Handle removal of a prototype file\n *\n * @function deletePrototype\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nexport function deletePrototype(filepath, store) {\n const file = path.parse(filepath);\n const requirePath = utils.removeFile(\n file.name,\n 'prototype',\n filepath,\n store\n );\n\n return store.setIn(\n ['prototypes', file.name],\n requirePath\n );\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/handleHTML.js","/** @module cli/kss-handler */\n\nimport path from 'path';\nimport fs from 'fs-extra';\nimport { parse } from 'kss';\nimport chalk from 'chalk';\n\nimport * as utils from './utils';\nimport { updateTemplate, deleteTemplate } from './handleTemplates';\nimport { writeStore } from './requireTemplates';\n\n/**\n * Handle update of a KSS section\n *\n * @function updateKSS\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nexport function updateKSS(filepath, store) {\n const kssSource = fs.readFileSync(filepath, 'utf8');\n const huron = store.get('config');\n const oldSection = utils.getSection(filepath, false, store) || {};\n const file = path.parse(filepath);\n let newStore = store;\n\n if (kssSource) {\n const styleguide = parse(kssSource, huron.get('kssOptions'));\n\n if (styleguide.data.sections.length) {\n const section = utils.normalizeSectionData(\n styleguide.data.sections[0]\n );\n\n if (section.reference && section.referenceURI) {\n // Update or add section data\n newStore = updateSectionData(\n filepath,\n section,\n oldSection,\n newStore\n );\n\n // Remove old section data if reference URI has changed\n if (oldSection &&\n oldSection.referenceURI &&\n oldSection.referenceURI !== section.referenceURI\n ) {\n newStore = unsetSection(oldSection, file, newStore, false);\n }\n\n writeStore(newStore);\n console.log(\n chalk.green(\n `KSS source in ${filepath} changed or added`\n )\n );\n return newStore;\n }\n\n console.log(\n chalk.magenta(\n `KSS section in ${filepath} is missing a section reference`\n )\n );\n return newStore;\n }\n\n console.log(chalk.magenta(`No KSS found in ${filepath}`));\n return newStore;\n }\n\n if (oldSection) {\n newStore = deleteKSS(filepath, oldSection, newStore);\n }\n\n console.log(chalk.red(`${filepath} not found or empty`)); // eslint-disable-line no-console\n return newStore;\n}\n\n/**\n * Handle removal of a KSS section\n *\n * @function deleteKSS\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} section - KSS section data\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nexport function deleteKSS(filepath, section, store) {\n const file = path.parse(filepath);\n\n if (section.reference && section.referenceURI) {\n // Remove section data from memory store\n return unsetSection(section, file, store, true);\n }\n\n return store;\n}\n\n/**\n * Update the sections store with new data for a specific section\n *\n * @function updateSectionData\n * @param {object} section - contains updated section data\n * @param {string} kssPath - path to KSS section\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nfunction updateSectionData(kssPath, section, oldSection, store) {\n const sectionFileInfo = path.parse(kssPath);\n const dataFilepath = path.join(\n sectionFileInfo.dir,\n `${sectionFileInfo.name}.json`\n );\n const isInline = null !== section.markup.match(/<\\/[^>]*>/);\n const newSort = sortSection(\n store.getIn(['sections', 'sorted']),\n section.reference,\n store.get('referenceDelimiter')\n );\n const newSection = Object.assign({}, oldSection, section);\n let newStore = store;\n\n // Required for reference from templates and data\n newSection.kssPath = kssPath;\n\n if (isInline) {\n // Set section value if inlineTempalte() returned a path\n newStore = updateInlineTemplate(\n kssPath,\n oldSection,\n newSection,\n newStore\n );\n } else {\n // Remove inline template, if it exists\n utils.removeFile(\n newSection.referenceURI,\n 'template',\n kssPath,\n store\n );\n // Update markup and data fields\n newStore = updateTemplateFields(\n sectionFileInfo,\n oldSection,\n newSection,\n newStore\n );\n }\n\n // Output section description\n newStore = updateDescription(\n kssPath,\n oldSection,\n newSection,\n newStore\n );\n\n // Output section data to a JSON file\n newSection.sectionPath = utils.writeSectionData(\n newStore,\n newSection,\n dataFilepath\n );\n\n // Update section sorting\n return newStore\n .setIn(\n ['sections', 'sorted'],\n newSort\n )\n .setIn(\n ['sections', 'sectionsByPath', kssPath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', section.referenceURI],\n newSection\n );\n}\n\n/**\n * Handle detection and output of inline templates, which is markup written\n * in the KSS documentation itself as opposed to an external file\n *\n * @function updateInlineTemplate\n * @param {string} oldSection - previous iteration of KSS data, if updated\n * @param {object} section - KSS section data\n * @return {object} updated data store with new template path info\n */\nfunction updateInlineTemplate(filepath, oldSection, section, store) {\n const newSection = section;\n const newStore = store;\n\n // If we have inline markup\n if (fieldShouldOutput(oldSection, section, 'markup')) {\n newSection.templatePath = utils.writeFile(\n section.referenceURI,\n 'template',\n filepath,\n section.markup,\n store\n );\n newSection.templateContent = section.markup;\n\n return newStore\n .setIn(\n ['sections', 'sectionsByPath', filepath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', section.referenceURI],\n newSection\n );\n }\n\n return newStore;\n}\n\n/**\n * Handle output of section description\n *\n * @function updateDescription\n * @param {string} oldSection - previous iteration of KSS data, if updated\n * @param {object} section - KSS section data\n * @return {object} updated data store with new descripton path info\n */\nfunction updateDescription(filepath, oldSection, section, store) {\n const newSection = section;\n const newStore = store;\n\n // If we don't have previous KSS or the KSS has been updated\n if (fieldShouldOutput(oldSection, section, 'description')) {\n // Write new description\n newSection.descriptionPath = utils.writeFile(\n section.referenceURI,\n 'description',\n filepath,\n section.description,\n store\n );\n\n return newStore\n .setIn(\n ['sections', 'sectionsByPath', filepath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', section.referenceURI],\n newSection\n );\n }\n\n return newStore;\n}\n\n/**\n * Handle Data and Markup fields\n *\n * @function updateTemplateFields\n * @param {string} file - File data for KSS file from path.parse()\n * @param {object} oldSection - outdated KSS data\n * @param {object} section - KSS section data\n * @param {object} store - memory store\n * @return {object} KSS section data with updated asset paths\n */\nfunction updateTemplateFields(file, oldSection, section, store) {\n const kssPath = path.format(file);\n const newSection = section;\n let filepath = '';\n let oldFilepath = '';\n let newStore = store;\n\n ['data', 'markup'].forEach((field) => {\n if (newSection[field]) {\n if (oldSection[field]) {\n oldFilepath = path.join(file.dir, oldSection[field]);\n newStore = deleteTemplate(\n oldFilepath,\n oldSection,\n newStore\n );\n }\n\n filepath = path.join(file.dir, newSection[field]);\n newStore = updateTemplate(\n filepath,\n newSection,\n newStore\n );\n } else {\n delete newSection[field];\n newStore = newStore\n .setIn(\n ['sections', 'sectionsByPath', kssPath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', newSection.referenceURI],\n newSection\n );\n }\n });\n\n return newStore;\n}\n\n/**\n * Remove a section from the memory store\n *\n * @function unsetSection\n * @param {object} section - contains updated section data\n * @param {string} file - file object from path.parse()\n * @param {object} store - memory store\n * @param {bool} removed - has the file been removed or just the section information changed?\n * @return {object} updated data store with new descripton path info\n */\nfunction unsetSection(section, file, store, removed) {\n const sorted = store.getIn(['sections', 'sorted']);\n const kssPath = path.format(file);\n const dataFilepath = path.join(file.dir, `${file.name}.json`);\n const isInline = section.markup &&\n null !== section.markup.match(/<\\/[^>]*>/);\n const newSort = unsortSection(\n sorted,\n section.reference,\n store.get('referenceDelimiter')\n );\n let newStore = store;\n\n // Remove old section data\n utils.removeFile(\n section.referenceURI,\n 'section',\n dataFilepath,\n newStore\n );\n\n // Remove associated inline template\n if (isInline) {\n utils.removeFile(section.referenceURI, 'template', kssPath, newStore);\n }\n\n // Remove description template\n utils.removeFile(section.referenceURI, 'description', kssPath, newStore);\n\n // Remove data from sectionsByPath if file has been removed\n if (removed) {\n newStore = newStore.deleteIn(['sections', 'sectionsByPath', kssPath]);\n }\n\n return newStore\n .deleteIn(['sections', 'sectionsByURI', section.referenceURI])\n .setIn(['sections', 'sorted'], newSort);\n}\n\n/**\n * Sort sections and subsections\n *\n * @function sortSection\n * @param {object} sorted - currently sorted sections\n * @param {string} reference - reference URI of section to sort\n * @return {object} updated data store with new descripton path info\n */\nfunction sortSection(sorted, reference, delimiter) {\n const parts = reference.split(delimiter);\n const newSort = sorted[parts[0]] || {};\n const newSorted = sorted;\n\n if (1 < parts.length) {\n const newParts = parts.filter((part, idx) => 0 !== idx);\n newSorted[parts[0]] = sortSection(\n newSort,\n newParts.join(delimiter),\n delimiter\n );\n } else {\n newSorted[parts[0]] = newSort;\n }\n\n return newSorted;\n}\n\n/**\n * Remove a section from the sorted sections\n *\n * @function unsortSection\n * @param {object} sorted - currently sorted sections\n * @param {string} reference - reference URI of section to sort\n * @return {object} updated data store with new descripton path info\n */\nfunction unsortSection(sorted, reference, delimiter) {\n const parts = reference.split(delimiter);\n const subsections = Object.keys(sorted[parts[0]]);\n const newSorted = sorted;\n\n if (subsections.length) {\n if (1 < parts.length) {\n const newParts = parts.filter((part, idx) => 0 !== idx);\n newSorted[parts[0]] = unsortSection(\n newSorted[parts[0]],\n newParts.join(delimiter),\n delimiter\n );\n }\n } else {\n delete newSorted[parts[0]];\n }\n\n return newSorted;\n}\n\n/**\n * Compare a KSS field between old and new KSS data to see if we need to output\n * a new module for that field\n *\n * @function fieldShouldOutput\n * @param {object} oldSection - currently sorted sections\n * @param {object} newSection - reference URI of section to sort\n * @param {string} field - KSS field to check\n * @return {bool} output a new module for the KSS field\n */\nfunction fieldShouldOutput(oldSection, newSection, field) {\n return (oldSection &&\n (oldSection[field] !== newSection[field] ||\n oldSection.referenceURI !== newSection.referenceURI)\n ) ||\n !oldSection;\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/handleKSS.js","// Necessary to remove require statement from Webpack processing preserve it in output\n/* eslint-disable import/no-dynamic-require, global-require */\nexport default function requireExternal(requirePath) {\n return require(requirePath);\n}\n/* eslint-enable */\n\n\n\n// WEBPACK FOOTER //\n// src/cli/requireExternal.js","/** @module cli/webpack-server */\nimport webpack from 'webpack';\nimport WebpackDevServer from 'webpack-dev-server';\nimport chalk from 'chalk';\nimport open from 'opn';\n\nimport createDevServerConfig from '../../config/devServer.config';\nimport program from './parseArgs';\nimport { removeTrailingSlash } from './utils';\n\n/**\n * Spin up webpack-dev-server or, if production flag is set, run webpack a single time\n *\n * @function startWebpack\n * @param {object} config - webpack configuration, preprocessed by {@link module:cli/generate-config generateConfig}\n * @see {@link module:cli/generate-config generateConfig}\n */\nexport default function startWebpack(config) {\n const huron = config.huron;\n const webpackConfig = config.webpack;\n const compiler = webpack(webpackConfig);\n\n if (program.progress) {\n compiler.apply(\n new webpack.ProgressPlugin(\n (percentage, msg) => {\n console.log(`${(percentage * 100)}% `, msg);\n }\n )\n );\n }\n\n if (program.production) {\n compiler.run((err, stats) => {\n const info = stats.toJson();\n\n if (err) {\n console.log(err);\n }\n\n if (stats.hasErrors()) {\n console.error(\n chalk.red(\n 'Webpack encountered errors during compile: ',\n info.errors\n )\n );\n }\n\n if (stats.hasWarnings()) {\n console.error(\n chalk.yellow(\n 'Webpack encountered warnings during compile: ', info.warnings\n )\n );\n }\n });\n } else {\n const server = new WebpackDevServer(compiler, createDevServerConfig(huron));\n const prototypeName = huron.prototypes[0].title || huron.prototypes[0];\n\n server.listen(\n huron.port,\n 'localhost',\n (err) => {\n if (err) {\n return console.log(err);\n }\n\n console.log(`Listening at http://localhost:${huron.port}/`);\n open(`http://localhost:${huron.port}/${\n removeTrailingSlash(huron.root)\n }/${prototypeName}.html`);\n return true;\n }\n );\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/server.js","import path from 'path';\n\nexport default {\n css: [],\n entry: 'huron',\n js: [],\n kss: 'css/',\n kssExtension: '.css',\n kssOptions: {\n multiline: true,\n markdown: true,\n custom: ['data'],\n },\n output: 'partials',\n port: 8080,\n prototypes: ['index'],\n root: 'dist/',\n sectionTemplate: path.join(__dirname, '../../templates/section.hbs'),\n classNames: false,\n templates: {\n rule: {\n test: /\\.(hbs|handlebars)$/,\n use: 'handlebars-loader',\n },\n extension: '.hbs',\n },\n window: {},\n};\n\n\n\n// WEBPACK FOOTER //\n// src/defaultConfig/huron.config.js","import webpack from 'webpack';\nimport path from 'path';\n\nimport program from '../cli/parseArgs';\n\nexport default (huron) => {\n const cwd = process.cwd();\n\n return {\n entry: {},\n output: {\n path: path.join(cwd, huron.root),\n publicPath: program.production ? '' :\n `http://localhost:${huron.port}/${huron.root}`,\n filename: '[name].js',\n chunkFilename: '[name].chunk.min.js',\n },\n plugins: [\n new webpack.HotModuleReplacementPlugin(),\n new webpack.NamedModulesPlugin(),\n ],\n resolve: {\n modulesDirectories: [\n path.resolve(__dirname, '../src/js'),\n ],\n },\n resolveLoader: {\n modulesDirectories: [\n 'web_loaders',\n 'web_modules',\n 'node_loaders',\n 'node_modules',\n path.resolve(__dirname, '../node_modules'),\n ],\n },\n module: {\n rules: [\n {\n test: /\\.html$/,\n include: [path.join(cwd, huron.root, huron.output)],\n use: 'html-loader',\n },\n {\n test: /\\.(hbs|handlebars)$/,\n include: [path.join(cwd, huron.root, 'huron-assets')],\n use: {\n loader: 'handlebars-loader',\n options: {\n helperDirs: [path.join(\n __dirname,\n '../../',\n 'templates/handlebarsHelpers'\n )],\n },\n },\n },\n ],\n },\n };\n};\n\n\n\n// WEBPACK FOOTER //\n// src/defaultConfig/webpack.config.js","module.exports = \"'use strict';\\n\\nvar _huronStore = require('./huron-store');\\n\\nvar _huronStore2 = _interopRequireDefault(_huronStore);\\n\\nvar _insertNodes = require('./insertNodes');\\n\\nvar _insertNodes2 = _interopRequireDefault(_insertNodes);\\n\\nvar _section = require('./section.hbs');\\n\\nvar _section2 = _interopRequireDefault(_section);\\n\\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\\n\\n/* eslint-enable */\\n\\nconst assets = require.context(hotScope.requirePath, true, hotScope.requireRegex); /* globals hotScope */\\n\\n// NOTE: This is not a normal JS file! It is pulled in by the CLI as a string\\n// and prepended to the browser script after replacing anything referenced via `hotScope[variable]`\\n// with CLI arguments or config properties passed in by the user.\\n\\n/* eslint-disable */\\n\\nconst modules = {};\\n\\nmodules[hotScope.sectionTemplatePath] = _section2.default;\\n\\nassets.keys().forEach(key => {\\n modules[key] = assets(key);\\n});\\n\\nconst insert = new _insertNodes2.default(modules, _huronStore2.default);\\n\\nif (module.hot) {\\n // Hot Module Replacement for huron components (json, hbs, html)\\n module.hot.accept(assets.id, () => {\\n const newAssets = require.context(hotScope.requirePath, true, hotScope.requireRegex);\\n const newModules = newAssets.keys().map(key => [key, newAssets(key)]).filter(newModule => modules[newModule[0]] !== newModule[1]);\\n\\n updateStore(require('./huron-store.js')); // eslint-disable-line global-require, import/no-unresolved\\n newModules.forEach(module => {\\n modules[module[0]] = module[1];\\n hotReplace(module[0], module[1], modules);\\n });\\n });\\n\\n // Hot Module Replacement for sections template\\n module.hot.accept('./section.hbs', () => {\\n const newSectionTemplate = require('./section.hbs'); // eslint-disable-line global-require, import/no-unresolved\\n\\n modules[hotScope.sectionTemplatePath] = newSectionTemplate;\\n hotReplace('./huron-assets/section.hbs', newSectionTemplate, modules);\\n });\\n\\n // Hot Module Replacement for data store\\n module.hot.accept('./huron-store.js', () => {\\n updateStore(require('./huron-store.js')); // eslint-disable-line global-require, import/no-unresolved\\n });\\n}\\n\\nfunction hotReplace(key, module, newModules) {\\n insert.modules = newModules;\\n if (key === _huronStore2.default.sectionTemplatePath) {\\n insert.cycleSections();\\n } else {\\n insert.inserted = [];\\n insert.loadModule(key, module, false);\\n }\\n}\\n\\nfunction updateStore(newStore) {\\n insert.store = newStore;\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/raw-loader!./~/babel-loader/lib!./templates/hotTemplate.js\n// module id = 20\n// module chunks = 0","module.exports = require(\"commander\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"commander\"\n// module id = 21\n// module chunks = 0","module.exports = require(\"gaze\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"gaze\"\n// module id = 22\n// module chunks = 0","module.exports = require(\"html-webpack-plugin\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"html-webpack-plugin\"\n// module id = 23\n// module chunks = 0","module.exports = require(\"immutable\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"immutable\"\n// module id = 24\n// module chunks = 0","module.exports = require(\"kss\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"kss\"\n// module id = 25\n// module chunks = 0","module.exports = require(\"lodash/isEqual\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"lodash/isEqual\"\n// module id = 26\n// module chunks = 0","module.exports = require(\"opn\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"opn\"\n// module id = 27\n// module chunks = 0","module.exports = require(\"url\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"url\"\n// module id = 28\n// module chunks = 0","module.exports = require(\"webpack-dev-server\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"webpack-dev-server\"\n// module id = 29\n// module chunks = 0"],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;A;;;;AChEA;;;;;;;;;;;;ACcA;AAkBA;AAqCA;AAqCA;AAcA;AAkBA;AAyBA;AA4CA;AAyCA;AAyBA;AAyBA;AAqBA;AA6CA;AACA;AA5WA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;;;AACA;AACA;AACA;;;;;;;AAPA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AAGA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AAGA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;;AAFA;AAKA;AACA;AACA;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AClXA;;;;;;ACAA;;;;;;;;;;;;;ACGA;AACA;;;AAAA;AACA;;;;;AACA;AACA;AACA;AACA;;;;;;AATA;AACA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAYA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACzDA;;;;;;;;;;;;;;ACAA;AACA;AACA;AACA;;;AAAA;AACA;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAKA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AAnBA;AAqBA;AACA;AACA;AAAA;;;;;;;;;;;;ACzBA;AA0DA;AACA;AA1EA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;AADA;AACA;;;;;AACA;;;;;;;;;AAPA;AAgBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAUA;;;;;;;;;;;;;;AClGA;AACA;;;AAAA;AACA;;;AAIA;AACA;;;;;AAAA;AACA;AACA;AACA;AAPA;AACA;AACA;AANA;AACA;AAUA;AACA;AAIA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AALA;AAOA;AACA;AAOA;AACA;AAIA;AAIA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;;;;;;;;;ACxEA;AACA;;;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;AAAA;AACA;;;;;AACA;;;;;AAhBA;AAqBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACxGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AATA;AAWA;AACA;AACA;AAjBA;;;;;;;;;;;;ACwBA;AA8CA;AA+DA;AA0DA;AACA;AA7LA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AADA;AACA;;;;;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA1BA;AACA;AA4BA;AACA;AACA;AACA;;;;;;;AA/DA;AACA;AACA;AAoEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAxCA;AACA;AA0CA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AArCA;AACA;AAuCA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;AC5MA;AACA;AAAA;AACA;;;AACA;AACA;AAAA;AACA;;;AACA;;;;;AAKA;AACA;AACA;;;;;AAKA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;;;;;AAKA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AA9BA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;;;AACA;AACA;AACA;AAdA;AAeA;AACA;AAGA;AACA;AAGA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAKA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAZA;AAcA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7RA;AA0CA;AA+BA;AA+BA;AACA;AAvHA;AACA;;;AAAA;AACA;;;AACA;AACA;AADA;AACA;;;;;AACA;;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAhDA;AAyDA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AASA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AAMA;AAIA;;;;;;;;;;;;ACjHA;AAsEA;AACA;AAxFA;AACA;;;AAAA;AACA;;;AAAA;AACA;AAAA;AACA;;;AACA;AACA;AADA;AACA;AAAA;AACA;AAAA;AACA;;;;;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAMA;AACA;AAIA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAhFA;AACA;AAwFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AASA;AACA;AACA;AAIA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AAMA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAKA;AACA;AAaA;AACA;AACA;;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AASA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAKA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAUA;AACA;AAKA;;;;;;;;;;;AC5aA;AAFA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACYA;AACA;AAjBA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;;;;;;;;;;;;;AC7EA;AACA;;;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AALA;AAOA;AAxBA;;;;;;;;;;;;;ACFA;AACA;;;AAAA;AACA;;;AACA;AACA;;;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AALA;AAOA;AAIA;AACA;AADA;AAKA;AACA;AADA;AASA;AACA;AAEA;AACA;AACA;AAHA;AAMA;AACA;AACA;AACA;AACA;AACA;AADA;AAFA;AAHA;AAPA;AA3BA;AAmDA;;;;;;AC3DA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;;;;;A","sourceRoot":""} \ No newline at end of file +{"version":3,"file":"index.js","sources":["webpack:///webpack/bootstrap d325e4bb1751af827cca","webpack:///external \"path\"","webpack:///src/cli/utils.js","webpack:///external \"chalk\"","webpack:///external \"fs-extra\"","webpack:///src/cli/parseArgs.js","webpack:///external \"webpack\"","webpack:///src/cli/defaultStore.js","webpack:///src/cli/handleTemplates.js","webpack:///src/cli/requireTemplates.js","webpack:///src/cli/index.js","webpack:///config/devServer.config.js","webpack:///src/cli/actions.js","webpack:///src/cli/fileWatcher.js","webpack:///src/cli/generateConfig.js","webpack:///src/cli/handleHTML.js","webpack:///src/cli/handleKSS.js","webpack:///src/cli/requireExternal.js","webpack:///src/cli/server.js","webpack:///src/defaultConfig/huron.config.js","webpack:///src/defaultConfig/webpack.config.js","webpack:///./templates/hotTemplate.js","webpack:///external \"commander\"","webpack:///external \"gaze\"","webpack:///external \"html-webpack-plugin\"","webpack:///external \"immutable\"","webpack:///external \"kss\"","webpack:///external \"lodash/isEqual\"","webpack:///external \"opn\"","webpack:///external \"url\"","webpack:///external \"webpack-dev-server\""],"sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"../\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 30);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap d325e4bb1751af827cca","module.exports = require(\"path\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"path\"\n// module id = 0\n// module chunks = 0","/** @module cli/utilities */\nimport path from 'path';\nimport fs from 'fs-extra';\nimport chalk from 'chalk';\n\nconst cwd = process.cwd(); // Current working directory\n\n/**\n * Ensure predictable data structure for KSS section data\n *\n * @function normalizeSectionData\n * @param {object} section - section data\n * @return {object} section data\n */\nexport function normalizeSectionData(section) {\n const data = section.data || section;\n\n if (!data.referenceURI || '' === data.referenceURI) {\n data.referenceURI = section.referenceURI();\n }\n\n return data;\n}\n\n/**\n * Ensure predictable data structure for KSS section data\n *\n * @function writeSectionData\n * @param {object} store - data store\n * @param {object} section - section data\n * @param {string} sectionPath - output destination for section data file\n */\nexport function writeSectionData(store, section, sectionPath = false) {\n let outputPath = sectionPath;\n let sectionFileInfo;\n\n if (!outputPath && {}.hasOwnProperty.call(section, 'kssPath')) {\n sectionFileInfo = path.parse(section.kssPath);\n outputPath = path.join(\n sectionFileInfo.dir,\n `${sectionFileInfo.name}.json`\n );\n }\n\n // Output section data\n if (outputPath) {\n return writeFile(\n section.referenceURI,\n 'section',\n outputPath,\n JSON.stringify(section),\n store\n );\n }\n\n console.warn( // eslint-disable-line no-console\n chalk.red(`Failed to write section data for ${section.referenceURI}`)\n );\n return false;\n}\n\n/**\n * Find .json from a template file or vice versa\n *\n * @function getTemplateDataPair\n * @param {object} file - file object from path.parse()\n * @param {object} section - KSS section data\n * @return {string} relative path to module JSON file\n */\nexport function getTemplateDataPair(file, section, store) {\n const huron = store.get('config');\n const kssDir = matchKssDir(file.dir, huron);\n\n if (kssDir) {\n const componentPath = path.relative(\n path.resolve(cwd, kssDir),\n file.dir\n );\n const partnerType = '.json' === file.ext ? 'template' : 'data';\n const partnerExt = '.json' === file.ext ?\n huron.get('templates').extension :\n '.json';\n\n const pairPath = path.join(\n componentPath,\n generateFilename(\n section.referenceURI,\n partnerType,\n partnerExt,\n store\n )\n );\n\n return `./${pairPath}`;\n }\n\n return false;\n}\n\n/**\n * Normalize a section title for use as a filename\n *\n * @function normalizeHeader\n * @param {string} header - section header extracted from KSS documentation\n * @return {string} modified header, lowercase and words separated by dash\n */\nexport function normalizeHeader(header) {\n return header\n .toLowerCase()\n .replace(/\\s?\\W\\s?/g, '-');\n}\n\n/**\n * Wrap html in required template tags\n *\n * @function wrapMarkup\n * @param {string} content - html or template markup\n * @param {string} templateId - id of template (should be section reference)\n * @return {string} modified HTML\n */\nexport function wrapMarkup(content, templateId) {\n return `\n\n\\n`;\n}\n\n/**\n * Generate a filename based on referenceURI, type and file object\n *\n * @function generateFilename\n * @param {string} id - The name of the file (with extension).\n * @param {string} type - the type of file output\n * @param {object} ext - file extension\n * @param {store} store - data store\n * @return {string} Path to output file, relative to ouput dir (can be use in require statements)\n */\nexport function generateFilename(id, type, ext, store) {\n // Type of file and its corresponding extension(s)\n const types = store.get('types');\n const outputExt = '.scss' !== ext ? ext : '.html';\n\n /* eslint-disable */\n if (-1 === types.indexOf(type)) {\n console.log(`Huron data ${type} does not exist`);\n return false;\n }\n /* eslint-enable */\n\n return `${id}-${type}${outputExt}`;\n}\n\n/**\n * Copy an HTML file into the huron output directory.\n *\n * @function writeFile\n * @param {string} id - The name of the file (with extension).\n * @param {string} content - The content of the file to write.\n * @param {string} type - the type of file output\n * @param {object} store - The data store\n * @return {string} Path to output file, relative to ouput dir (can be use in require statements)\n */\nexport function writeFile(id, type, filepath, content, store) {\n const huron = store.get('config');\n const file = path.parse(filepath);\n const filename = generateFilename(id, type, file.ext, store);\n const kssDir = matchKssDir(filepath, huron);\n\n if (kssDir) {\n const componentPath = path.relative(\n path.resolve(cwd, kssDir),\n file.dir\n );\n const outputRelative = path.join(\n huron.get('output'),\n componentPath,\n `${filename}`\n );\n const outputPath = path.resolve(cwd, huron.get('root'), outputRelative);\n let newContent = content;\n\n if ('data' !== type && 'section' !== type) {\n newContent = wrapMarkup(content, id);\n }\n\n try {\n fs.outputFileSync(outputPath, newContent);\n console.log(chalk.green(`Writing ${outputRelative}`)); // eslint-disable-line no-console\n } catch (e) {\n console.log(chalk.red(`Failed to write ${outputRelative}`)); // eslint-disable-line no-console\n }\n\n return `./${outputRelative.replace(`${huron.get('output')}/`, '')}`;\n }\n\n return false;\n}\n\n/**\n * Delete a file in the huron output directory\n *\n * @function removeFile\n * @param {string} filename - The name of the file (with extension).\n * @param {object} store - The data store\n * @return {string} Path to output file, relative to ouput dir (can be use in require statements)\n */\nexport function removeFile(id, type, filepath, store) {\n const huron = store.get('config');\n const file = path.parse(filepath);\n const filename = generateFilename(id, type, file.ext, store);\n const kssDir = matchKssDir(filepath, huron);\n\n if (kssDir) {\n const componentPath = path.relative(\n path.resolve(cwd, kssDir),\n file.dir\n );\n const outputRelative = path.join(\n huron.get('output'),\n componentPath,\n `${filename}`\n );\n const outputPath = path.resolve(cwd, huron.get('root'), outputRelative);\n\n try {\n fs.removeSync(outputPath);\n console.log(chalk.green(`Removing ${outputRelative}`)); // eslint-disable-line no-console\n } catch (e) {\n console.log( // eslint-disable-line no-console\n chalk.red(`${outputRelative} does not exist or cannot be deleted`)\n );\n }\n\n return `./${outputRelative.replace(`${huron.get('output')}/`, '')}`;\n }\n\n return false;\n}\n\n/**\n * Write a template for sections\n *\n * @function writeSectionTemplate\n * @param {string} filepath - the original template file\n * @param {object} store - data store\n * @return {object} updated store\n */\nexport function writeSectionTemplate(filepath, store) {\n const huron = store.get('config');\n const sectionTemplate = wrapMarkup(fs.readFileSync(filepath, 'utf8'));\n const componentPath = './huron-assets/section.hbs';\n const output = path.join(\n cwd,\n huron.get('root'),\n componentPath\n );\n\n // Move huron script and section template into huron root\n fs.outputFileSync(output, sectionTemplate);\n console.log(chalk.green(`writing section template to ${output}`)); // eslint-disable-line no-console\n\n return store.set('sectionTemplatePath', componentPath);\n}\n\n/**\n * Request for section data based on section reference\n *\n * @function writeSectionTemplate\n * @param {string} search - key on which to match section\n * @param {field} string - field in which to look to determine section\n * @param {obj} store - sections memory store\n */\nexport function getSection(search, field, store) {\n const sectionValues = store\n .getIn(['sections', 'sectionsByPath'])\n .valueSeq();\n let selectedSection = false;\n\n if (field) {\n selectedSection = sectionValues\n .filter((value) => value[field] === search)\n .get(0);\n } else {\n selectedSection = store.getIn(['sections', 'sectionsByPath', search]);\n }\n\n return selectedSection;\n}\n\n/**\n * Find which configured KSS directory a filepath exists in\n *\n * @function matchKssDir\n * @param {string} filepath - filepath to search for\n * @param {object} huron - huron configuration\n * @return {string} kssMatch - relative path to KSS directory\n */\nexport function matchKssDir(filepath, huron) {\n const kssSource = huron.get('kss');\n // Include forward slash in our test to make sure we're matchin a directory, not a file extension\n const kssMatch = kssSource.filter((dir) => filepath.includes(`/${dir}`));\n\n if (kssMatch.length) {\n return kssMatch[0];\n }\n\n return false;\n}\n\n/**\n * Merge JSON files for css modules classnames in a provided directory\n *\n * @function mergeClassnameJSON\n * @param {string} directory - directory containing classname JSON files\n *\n * @return {object} classnamesMerged - merged classnames. contents of each JSON file is nested within\n * the returned object by filename. (e.g. article.json -> { article: {...json contents}})\n */\nexport function mergeClassnameJSON(directory) {\n let files;\n\n // If no config is provided, return immediately\n if (!directory) {\n return {};\n }\n\n // Try to read through classnames directory\n try {\n files = fs.readdirSync(directory);\n } catch (e) {\n console.warn(chalk.red(e));\n }\n\n // Merge classname json files\n const classNamesMerged = files.reduce((acc, file) => {\n const fileInfo = path.parse(file);\n let classNames = {};\n\n if ('.json' === fileInfo.ext) {\n try {\n const contents = fs.readFileSync(\n path.join(directory, file),\n 'utf8'\n );\n classNames = JSON.parse(contents);\n } catch (e) {\n console.warn(chalk.red(e));\n }\n }\n\n return Object.assign({}, acc, { [fileInfo.name]: classNames });\n }, {});\n\n return classNamesMerged;\n}\n\n/**\n * Remove the trailing slash from a provided directory\n *\n * @function removeTrailingSlash\n * @param {string} directory - directory path\n * @return {string} directory - directory path with trailing slash removed\n */\nexport function removeTrailingSlash(directory) {\n if ('/' === directory.slice(-1)) {\n return directory.slice(0, -1);\n }\n\n return directory;\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/utils.js","module.exports = require(\"chalk\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"chalk\"\n// module id = 2\n// module chunks = 0","module.exports = require(\"fs-extra\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"fs-extra\"\n// module id = 3\n// module chunks = 0","/** @module cli/parse-arguments */\n/* eslint-disable space-unary-ops */\n\nimport program from 'commander';\nimport path from 'path';\n\n// Requires\n/** @global */\n\n/**\n * Process huron CLI arguments\n *\n * @function parseArgs\n * @example node huron/dist/cli/huron-cli.js --config 'client/config/webpack.config.js' --production\n */\nfunction parseArgs() {\n const envArg = {};\n\n process.argv = process.argv.filter((arg) => {\n if (-1 !== arg.indexOf('--env')) {\n const envParts = arg\n .split('.')[1]\n .split('=');\n\n envArg[envParts[0]] = envParts[1] || true;\n return false;\n }\n\n return true;\n });\n\n program.version('1.0.1')\n .option(\n '-c, --huron-config [huronConfig]',\n '[huronConfig] for all huron options',\n path.resolve(__dirname, '../defaultConfig/huron.config.js')\n )\n .option(\n '-w, --webpack-config [webpackConfig]',\n '[webpackConfig] for all webpack options',\n path.resolve(__dirname, '../defaultConfig/webpack.config.js')\n )\n .option('-p, --production', 'compile assets once for production');\n\n program.env = envArg;\n\n // Only parse if we're not running tests\n if (\n ! process.env.npm_lifecycle_event ||\n 'test' !== process.env.npm_lifecycle_event\n ) {\n program.parse(process.argv);\n }\n}\n\nparseArgs();\n/* eslint-enable */\n\nexport default program;\n\n\n\n// WEBPACK FOOTER //\n// src/cli/parseArgs.js","module.exports = require(\"webpack\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"webpack\"\n// module id = 5\n// module chunks = 0","import { Map } from 'immutable';\n\nimport generateConfig from './generateConfig';\nimport { mergeClassnameJSON } from './utils';\n// Create initial data structure\n\n// Merge Huron default webpack config with user config\nconst config = generateConfig();\n\n// Make sure the kss option is represented as an array\nconfig.huron.kss = [].concat(config.huron.kss);\n\n/* eslint-disable */\n/**\n * Initial structure for immutable data store\n *\n * @global\n */\nconst defaultStore = Map({\n types: [\n 'template',\n 'data',\n 'description',\n 'section',\n 'prototype',\n 'sections-template',\n ],\n config: Map(config.huron),\n classNames: mergeClassnameJSON(config.huron.classNames),\n sections: Map({\n sectionsByPath: Map({}),\n sectionsByURI: Map({}),\n sorted: {},\n }),\n templates: Map({}),\n prototypes: Map({}),\n sectionTemplatePath: '',\n referenceDelimiter: '.',\n});\n/* eslint-enable */\n\nexport { defaultStore, config };\n\n\n\n// WEBPACK FOOTER //\n// src/cli/defaultStore.js","/** @module cli/template-handler */\nimport path from 'path';\nimport fs from 'fs-extra';\nimport chalk from 'chalk';\n\nimport * as utils from './utils';\n\n/**\n * Handle update of a template or data (json) file\n *\n * @function updateTemplate\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} section - contains KSS section data\n * @param {object} store - memory store\n * @return {object} updated memory store\n */\nexport function updateTemplate(filepath, section, store) {\n const file = path.parse(filepath);\n const pairPath = utils.getTemplateDataPair(file, section, store);\n const type = '.json' === file.ext ? 'data' : 'template';\n const newSection = section;\n const newStore = store;\n let content = false;\n\n try {\n content = fs.readFileSync(filepath, 'utf8');\n } catch (e) {\n console.log(chalk.red(`${filepath} does not exist`));\n }\n\n if (content) {\n const requirePath = utils.writeFile(\n newSection.referenceURI,\n type,\n filepath,\n content,\n newStore\n );\n newSection[`${type}Path`] = requirePath;\n\n if ('template' === type) {\n newSection.templateContent = content;\n\n // Rewrite section data with template content\n newSection.sectionPath = utils.writeSectionData(newStore, newSection);\n }\n\n return newStore\n .setIn(\n ['templates', requirePath],\n pairPath\n )\n .setIn(\n ['sections', 'sectionsByPath', newSection.kssPath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', newSection.referenceURI],\n newSection\n );\n }\n\n return newStore;\n}\n\n/**\n * Handle removal of a template or data (json) file\n *\n * @function deleteTemplate\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} section - contains KSS section data\n * @param {object} store - memory store\n * @return {object} updated memory store\n */\nexport function deleteTemplate(filepath, section, store) {\n const file = path.parse(filepath);\n const type = '.json' === file.ext ? 'data' : 'template';\n const newSection = section;\n const newStore = store;\n\n // Remove partner\n const requirePath = utils.removeFile(\n newSection.referenceURI,\n type,\n filepath,\n newStore\n );\n delete newSection[`${type}Path`];\n\n return newStore\n .deleteIn(['templates', requirePath])\n .setIn(\n ['sections', 'sectionsByPath', newSection.kssPath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', newSection.referenceURI],\n newSection\n );\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/handleTemplates.js","/** @module cli/require-templates */\nimport path from 'path';\nimport fs from 'fs-extra';\n\n// We need to prepend this to the browser script as a string but still want to transpile it,\n// hence loading it using `raw-loader` so we receive a string from webpack\n/* eslint-disable */\nimport hotTemplate from '!raw-loader!babel-loader!../../templates/hotTemplate';\n/* eslint-enable */\n\nconst cwd = process.cwd();\nconst huronScript = fs.readFileSync(\n path.join(__dirname, '../web/index.js'),\n 'utf8'\n);\n\n/**\n * Write code for requiring all generated huron assets\n *\n * @function requireTemplates\n * @param {object} store - memory store\n */\nexport const requireTemplates = function requireTemplates(store) {\n const huron = store.get('config');\n const outputPath = path.join(cwd, huron.get('root'), 'huron-assets');\n // These will be used to replace strings in the hotTemplate.\n // In order to accurately replace strings but still keep things parseable by eslint and babel,\n // each replaceable value should be referenced in `hotTemplate.js` under the `hotScope` object.\n // For example, if you need to replace a string with a value passed in from the CLI called `userVariable`,\n // you would reference that string in `hotTemplate.js` with `hotScope.userVariable`.\n const hotVariableScope = {\n sectionTemplatePath: `'${huron.get('sectionTemplate')}'`,\n requireRegex: new RegExp(`\\\\.html|\\\\.json|\\\\${\n huron.get('templates').extension\n }$`),\n requirePath: `'../${huron.get('output')}'`,\n };\n const hotTemplateTransformed = Object.keys(hotVariableScope)\n .reduce(\n (acc, curr) => acc.replace(\n new RegExp(`hotScope.${curr}`, 'g'),\n hotVariableScope[curr]\n ), hotTemplate\n );\n\n // Write the contents of this script.\n fs.outputFileSync(\n path.join(outputPath, 'index.js'),\n hotTemplateTransformed\n );\n fs.outputFileSync(\n path.join(outputPath, 'insertNodes.js'),\n huronScript\n );\n};\n\n/**\n * Output entire data store to a JS object and handle if any KSS data has changed\n *\n * @function writeStore\n * @param {object} store - memory store\n * @param {string} changed - filepath of changed KSS section, if applicable\n */\nexport const writeStore = function writeStore(store, newStore = false) {\n const updatedStore = newStore || store;\n const huron = updatedStore.get('config');\n const outputPath = path.join(cwd, huron.get('root'), 'huron-assets');\n\n // Write updated data store\n fs.outputFileSync(\n path.join(outputPath, 'huron-store.js'),\n `module.exports = ${JSON.stringify(updatedStore.toJSON())}`\n );\n};\n\n\n\n\n// WEBPACK FOOTER //\n// src/cli/requireTemplates.js","// Local imports\nimport chalk from 'chalk';\n\nimport {\n initFiles,\n updateFile,\n deleteFile,\n updateClassNames,\n} from './actions';\nimport { requireTemplates, writeStore } from './requireTemplates';\nimport { matchKssDir } from './utils';\nimport program from './parseArgs';\nimport startWebpack from './server';\nimport { defaultStore, config } from './defaultStore';\nimport gaze from './fileWatcher';\n\n/**\n * Initialize data store with files from gaze and original data structure\n *\n * @global\n */\nconst huron = defaultStore.get('config');\nlet store = initFiles(gaze.watched(), defaultStore);\n\nrequireTemplates(store);\nwriteStore(store);\n\n// If building for production, close gaze and exit process once initFiles is done.\nif (program.production) {\n gaze.close();\n}\n\n/** @module cli/gaze */\ngaze.on('all', (event, filepath) => {\n store = updateClassNames(filepath, store);\n writeStore(store);\n});\n\n/**\n * Anonymous handler for Gaze 'changed' event indicating a file has changed\n *\n * @callback changed\n * @listens gaze:changed\n * @param {string} filepath - absolute path of changed file\n */\ngaze.on('changed', (filepath) => {\n if (matchKssDir(filepath, huron)) {\n store = updateFile(filepath, store);\n }\n\n console.log(chalk.green(`${filepath} updated!`));\n});\n\n/**\n * Anonymous handler for Gaze 'added' event indicating a file has been added to the watched directories\n *\n * @callback added\n * @listens gaze:added\n * @param {string} filepath - absolute path of changed file\n */\ngaze.on('added', (filepath) => {\n if (matchKssDir(filepath, huron)) {\n store = updateFile(filepath, store);\n writeStore(store);\n }\n\n console.log(chalk.blue(`${filepath} added!`));\n});\n\n/**\n * Anonymous handler for Gaze 'renamed' event indicating a file has been renamed\n *\n * @callback renamed\n * @listens gaze:renamed\n * @param {string} filepath - absolute path of changed file\n */\ngaze.on('renamed', (newPath, oldPath) => {\n if (matchKssDir(newPath, huron)) {\n store = deleteFile(oldPath, store);\n store = updateFile(newPath, store);\n writeStore(store);\n }\n\n console.log(chalk.blue(`${newPath} added!`));\n});\n\n/**\n * Anonymous handler for Gaze 'deleted' event indicating a file has been removed\n *\n * @callback deleted\n * @listens gaze:deleted\n * @param {string} filepath - absolute path of changed file\n */\ngaze.on('deleted', (filepath) => {\n if (matchKssDir(filepath, huron)) {\n store = deleteFile(filepath, store);\n writeStore(store);\n }\n\n console.log(chalk.red(`${filepath} deleted`));\n});\n\n// Start webpack or build for production\nstartWebpack(config);\n\n\n\n// WEBPACK FOOTER //\n// src/cli/index.js","export default (huron) => ({\n hot: true,\n quiet: false,\n noInfo: false,\n stats: {\n colors: true,\n hash: false,\n version: false,\n assets: false,\n chunks: false,\n modules: false,\n reasons: false,\n children: false,\n source: false,\n },\n contentBase: huron.root,\n overlay: true,\n publicPath: `http://localhost:${huron.port}/${huron.root}`,\n});\n\n\n\n// WEBPACK FOOTER //\n// config/devServer.config.js","/** @module cli/actions */\n\n// Imports\nimport path from 'path';\nimport chalk from 'chalk';\nimport isEqual from 'lodash/isEqual';\n\nimport {\n updateHTML,\n deleteHTML,\n updatePrototype,\n deletePrototype,\n} from './handleHTML';\nimport { updateTemplate, deleteTemplate } from './handleTemplates';\nimport { updateKSS, deleteKSS } from './handleKSS';\nimport * as utils from './utils';\n\n/**\n * Recursively loop through initial watched files list from Gaze.\n *\n * @param {object} data - object containing directory and file paths\n * @param {object} store - memory store\n * @return {object} newStore - map object of entire data store\n */\nexport function initFiles(data, store, depth = 0) {\n const type = Object.prototype.toString.call(data);\n const huron = store.get('config');\n let newStore = store;\n let info;\n let files;\n\n switch (type) {\n case '[object Object]':\n files = Object.keys(data);\n newStore = files.reduce(\n (prevStore, file) => initFiles(data[file], prevStore, depth),\n newStore\n );\n break;\n\n case '[object Array]':\n newStore = data.reduce(\n (prevStore, file) => initFiles(file, prevStore, depth),\n newStore\n );\n break;\n\n case '[object String]':\n info = path.parse(data);\n\n // Only call update if data is a filepath and it's within the KSS source directory\n if (info.ext && !data.includes(huron.get('classNames'))) {\n newStore = updateFile(data, store);\n }\n break;\n\n default:\n break;\n }\n\n return newStore;\n}\n\n/**\n * Logic for updating and writing file information based on file type (extension)\n *\n * @param {string} filepath - path to updated file. usually passed in from Gaze\n * @param {object} store - memory store\n * @return {object} store - map object of map object of entire data store\n */\nexport function updateFile(filepath, store) {\n const huron = store.get('config');\n const file = path.parse(filepath);\n let field;\n let section;\n\n if (filepath.includes(huron.get('sectionTemplate'))) {\n return utils.writeSectionTemplate(filepath, store);\n }\n\n switch (file.ext) {\n // Plain HTML template, external\n case '.html':\n section = utils.getSection(file.base, 'markup', store);\n\n if (section) {\n return updateHTML(filepath, section, store);\n } else if (\n file.dir.includes('prototypes') &&\n file.name.includes('prototype-')\n ) {\n return updatePrototype(filepath, store);\n }\n\n console.log(chalk.red(`Failed to write file: ${file.name}`));\n break;\n\n // Handlebars template, external\n case huron.get('templates').extension:\n case '.json':\n field = ('.json' === file.ext) ? 'data' : 'markup';\n section = utils.getSection(file.base, field, store);\n\n if (section) {\n return updateTemplate(filepath, section, store);\n }\n\n console.log( // eslint-disable-line no-console\n chalk.red(`Could not find associated KSS section for ${filepath}`)\n );\n break;\n\n // KSS documentation (default extension is `.css`)\n // Will also output a template if markup is inline\n // Note: inline markup does _not_ support handlebars currently\n case huron.get('kssExtension'):\n return updateKSS(filepath, store);\n\n // This should never happen if Gaze is working properly\n default:\n return store;\n }\n\n return store;\n}\n\n/**\n * Logic for deleting file information and files based on file type (extension)\n *\n * @param {string} filepath - path to updated file. usually passed in from Gaze\n * @param {object} store - memory store\n * @return {object} newStore - map object of map object of entire data store\n */\nexport function deleteFile(filepath, store) {\n const huron = store.get('config');\n const file = path.parse(filepath);\n let field = '';\n let section = null;\n let newStore = store;\n\n switch (file.ext) {\n // Plain HTML template, external\n case '.html':\n section = utils.getSection(file.base, 'markup', store);\n\n if (section) {\n newStore = deleteHTML(filepath, section, store);\n } else if (\n file.dir.includes('prototypes') &&\n file.name.includes('prototype-')\n ) {\n newStore = deletePrototype(filepath, store);\n }\n break;\n\n case huron.get('templates').extension:\n case '.json':\n field = ('.json' === file.ext) ? 'data' : 'markup';\n section = utils.getSection(file.base, field, store);\n\n if (section) {\n newStore = deleteTemplate(filepath, section, store);\n }\n break;\n\n case huron.get('kssExtension'):\n section = utils.getSection(filepath, false, store);\n\n if (section) {\n newStore = deleteKSS(filepath, section, store);\n }\n break;\n\n default:\n console.warn( // eslint-disable-line no-console\n chalk.red(`Could not delete: ${file.name}`)\n );\n break;\n }\n\n return newStore;\n}\n\n/**\n * Logic for updating localized classnames from CSS modules\n *\n * @param {string} filepath - path to updated file. usually passed in from Gaze\n * @param {object} store - memory store\n *\n * @return void\n */\nexport function updateClassNames(filepath, store) {\n const classNamesPath = store.getIn(['config', 'classNames']);\n\n if (filepath.includes(classNamesPath)) {\n const oldClassnames = store.get('classNames');\n const newClassnames = utils.mergeClassnameJSON(classNamesPath);\n\n if (!isEqual(oldClassnames, newClassnames)) {\n return store.set('classNames', newClassnames);\n }\n }\n\n return store;\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/actions.js","import { Gaze } from 'gaze';\nimport path from 'path';\n\nimport { removeTrailingSlash } from './utils';\nimport { defaultStore } from './defaultStore';\n\n/**\n * Huron configuration object\n *\n * @global\n */\nconst huron = defaultStore.get('config');\n\n/**\n * Available file extensions. Extensions should not include the leading '.'\n *\n * @global\n */\nexport const extensions = [\n huron.get('kssExtension'),\n huron.get('templates').extension,\n 'html',\n 'json',\n].map((extension) => extension.replace('.', ''));\n\n// Generate watch list for Gaze, start gaze\nexport const watchedFiles = [];\n\n// Watch section template\nwatchedFiles.push(path.resolve(huron.get('sectionTemplate')));\n\n// Watch cssmodules classname files (if they exist)\nif (huron.get('classNames')) {\n watchedFiles.push(\n `${path.resolve(huron.get('classNames'))}/*.json`\n );\n}\n\n// Watch all provided kss directories\nhuron.get('kss').forEach((dir) => {\n watchedFiles.push(\n `${removeTrailingSlash(dir)}/**/*.+(${extensions.join('|')})`\n );\n});\n\n/**\n * Gaze instance for watching all files, including KSS, html, hbs/template, and JSON\n *\n * @global\n */\nconst gaze = new Gaze(watchedFiles);\n\nexport default gaze;\n\n\n\n// WEBPACK FOOTER //\n// src/cli/fileWatcher.js","/** @module cli/generate-config */\nimport path from 'path';\nimport url from 'url';\nimport fs from 'fs-extra';\nimport webpack from 'webpack';\nimport HTMLWebpackPlugin from 'html-webpack-plugin';\n\nimport program from './parseArgs';\nimport requireExternal from './requireExternal';\nimport defaultWebpack from '../defaultConfig/webpack.config';\nimport defaultHuron from '../defaultConfig/huron.config';\n\nconst cwd = process.cwd();\n\n// Require configs passed in by user from CLI\nlet defaultConfig = false;\nconst localConfig = requireExternal(\n path.resolve(program.webpackConfig)\n);\nconst localHuron = requireExternal(\n path.resolve(program.huronConfig)\n);\n\n/**\n * Generate a mutant hybrid of the huron default webpack config and your local webpack config\n *\n * @function generateConfig\n * @param {object} config - local webpack config\n * @return {object} newConfig - updated data store\n */\nexport default function generateConfig() {\n let newConfig = localConfig;\n let newHuron = localHuron;\n\n // Execute config function, if provided\n if ('function' === typeof newConfig) {\n newConfig = newConfig(program.env);\n }\n\n // Execute huron config function, if provided\n if ('function' === typeof newHuron) {\n newHuron = newHuron(program.env);\n }\n\n // Merge huron defaults with user settings\n newHuron = Object.assign({}, defaultHuron, newHuron);\n // Use user huron config to modify webpack defaults\n defaultConfig = defaultWebpack(newHuron);\n\n // Set ouput options\n newConfig.output = Object.assign({}, defaultConfig.output, newConfig.output);\n newConfig.output.path = defaultConfig.output.path;\n newConfig.output.publicPath = defaultConfig.output.publicPath;\n\n // configure entries\n newConfig = configureEntries(newHuron, newConfig);\n\n // configure plugins\n newConfig = configurePlugins(newHuron, newConfig);\n\n // configure loaders\n newConfig = configureLoaders(newHuron, newConfig);\n\n // Add HTMLWebpackPlugin for each configured prototype\n newConfig = configurePrototypes(newHuron, newConfig);\n\n // Remove existing devServer settings\n delete newConfig.devServer;\n\n return {\n huron: newHuron,\n webpack: newConfig,\n };\n}\n\n/**\n * Configure and manage webpack entry points\n *\n * @param {object} huron - huron configuration object\n * @param {object} config - webpack configuration object\n * @return {object} newConfig - updated data store\n */\nfunction configureEntries(huron, config) {\n const entry = config.entry[huron.entry];\n const newConfig = config;\n\n newConfig.entry = {};\n if (!program.production) {\n newConfig.entry[huron.entry] = [\n `webpack-dev-server/client?http://localhost:${huron.port}`,\n 'webpack/hot/dev-server',\n path.join(cwd, huron.root, 'huron-assets/index'),\n ].concat(entry);\n } else {\n newConfig.entry[huron.entry] = [\n path.join(cwd, huron.root, 'huron-assets/index'),\n ].concat(entry);\n }\n\n return newConfig;\n}\n\n/**\n * Configure and manage webpack plugins\n *\n * @param {object} huron - huron configuration object\n * @param {object} config - webpack configuration object\n * @return {object} newConfig - updated data store\n */\nfunction configurePlugins(huron, config) {\n const newConfig = config;\n\n newConfig.plugins = config.plugins || [];\n\n if (!program.production) {\n if (newConfig.plugins && newConfig.plugins.length) {\n newConfig.plugins = newConfig.plugins.filter(\n (plugin) => 'HotModuleReplacementPlugin' !== plugin.constructor.name &&\n 'NamedModulesPlugin' !== plugin.constructor.name\n );\n }\n newConfig.plugins = newConfig.plugins\n .concat([\n new webpack.HotModuleReplacementPlugin(),\n new webpack.NamedModulesPlugin(),\n ]);\n }\n\n return newConfig;\n}\n\n/**\n * Configure and manage webpack loaders\n *\n * @param {object} huron - huron configuration object\n * @param {object} config - webpack configuration object\n * @return {object} newConfig - updated data store\n */\nfunction configureLoaders(huron, config) {\n // Manage loaders\n const templatesLoader = huron.templates.rule || {};\n const newConfig = config;\n\n // Make sure we're only using templates loader for files in huron root\n templatesLoader.include = [path.join(cwd, huron.root, huron.output)];\n\n // Normalize module and module.rules\n newConfig.module = newConfig.module || {};\n newConfig.module.rules = newConfig.module.rules ||\n newConfig.module.loaders ||\n [];\n\n // Add default loaders\n newConfig.module.rules = defaultConfig.module.rules\n .concat(\n newConfig.module.rules,\n templatesLoader\n );\n\n return newConfig;\n}\n\n/**\n * Create an HTML webpack plugin for each configured prototype\n *\n * @param {object} huron - huron configuration object\n * @param {object} config - webpack configuration object\n * @return {object} newConfig - updated data store\n */\nfunction configurePrototypes(huron, config) {\n const wrapperTemplate = fs.readFileSync(\n path.join(__dirname, '../../templates/prototypeTemplate.hbs'),\n 'utf8'\n );\n\n const defaultHTMLPluginOptions = {\n title: 'Huron',\n window: huron.window,\n js: [],\n css: [],\n filename: 'index.html',\n template: path.join(\n cwd,\n huron.root,\n 'huron-assets/prototypeTemplate.hbs'\n ),\n inject: false,\n chunks: [huron.entry],\n };\n const newConfig = config;\n\n // Write prototype template file for HTML webpack plugin\n fs.outputFileSync(\n path.join(cwd, huron.root, 'huron-assets/prototypeTemplate.hbs'),\n wrapperTemplate\n );\n\n huron.prototypes.forEach((prototype) => {\n const newPrototype = prototype;\n let opts = {};\n\n // Merge configured settings with default settings\n if ('string' === typeof prototype) {\n opts = Object.assign({}, defaultHTMLPluginOptions, {\n title: prototype,\n filename: `${prototype}.html`,\n });\n } else if (\n 'object' === typeof prototype &&\n {}.hasOwnProperty.call(prototype, 'title')\n ) {\n // Create filename based on configured title if not provided\n if (!prototype.filename) {\n newPrototype.filename = `${prototype.title}.html`;\n }\n\n // Move css assets for this prototype,\n // reset css option with new file paths\n if (prototype.css) {\n newPrototype.css = moveAdditionalAssets(prototype.css, 'css', huron);\n }\n\n // Move js assets for this prototype,\n // reset js option with new file paths\n if (prototype.js) {\n newPrototype.js = moveAdditionalAssets(prototype.js, 'js', huron);\n }\n\n opts = Object.assign({}, defaultHTMLPluginOptions, newPrototype);\n }\n\n // Move global css assets,\n // reset css option with new file paths\n if (huron.css.length) {\n opts.css = opts.css.concat(\n moveAdditionalAssets(huron.css, 'css', huron)\n );\n }\n\n // Move global js assets,\n // reset js option with new file paths\n if (huron.js.length) {\n opts.js = opts.js.concat(\n moveAdditionalAssets(huron.js, 'js', huron)\n );\n }\n\n // Push a new plugin for each configured prototype\n if (Object.keys(opts).length) {\n newConfig.plugins.push(\n new HTMLWebpackPlugin(opts)\n );\n }\n });\n\n return newConfig;\n}\n\n/**\n * Move relative (and local) js and css assets provided in huron options\n *\n * @param {array|string} assets - array of assets or single asset\n * @param {string} subdir - subdirectory in huron root from which to load additional asset\n * @param {object} huron - huron configuration object\n * @return {array} assetResults - paths to js and css assets\n */\nfunction moveAdditionalAssets(assets, subdir = '', huron) {\n const currentAssets = [].concat(assets);\n const assetResults = [];\n\n currentAssets.forEach((asset) => {\n const assetInfo = path.parse(asset);\n const assetURL = url.parse(asset);\n const sourcePath = path.join(cwd, asset);\n const outputPath = path.resolve(cwd, huron.root, subdir, assetInfo.base);\n const loadPath = program.production ?\n path.join(subdir, assetInfo.base) :\n path.join('/', subdir, assetInfo.base); // Use absolute path in development\n let contents = false;\n\n if (\n !path.isAbsolute(asset) &&\n !assetURL.protocol\n ) {\n try {\n contents = fs.readFileSync(sourcePath);\n } catch (e) {\n console.warn(`could not read ${sourcePath}`);\n }\n\n if (contents) {\n fs.outputFileSync(outputPath, contents);\n assetResults.push(loadPath);\n }\n } else {\n assetResults.push(asset);\n }\n });\n\n return assetResults;\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/generateConfig.js","/** @module cli/html-handler */\nimport path from 'path';\nimport fs from 'fs-extra';\n\nimport * as utils from './utils';\n\n/**\n * Handle update of an HMTL template\n *\n * @function updateHTML\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} section - contains KSS section data\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nexport function updateHTML(filepath, section, store) {\n const file = path.parse(filepath);\n const content = fs.readFileSync(filepath, 'utf8');\n const newSection = section;\n\n if (content) {\n newSection.templatePath = utils.writeFile(\n section.referenceURI,\n 'template',\n filepath,\n content,\n store\n );\n newSection.templateContent = content;\n\n // Rewrite section data with template content\n newSection.sectionPath = utils.writeSectionData(store, newSection);\n\n return store\n .setIn(\n ['sections', 'sectionsByPath', section.kssPath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', section.referenceURI],\n newSection\n );\n }\n\n console.log(`File ${file.base} could not be read`);\n return store;\n}\n\n/**\n * Handle removal of an HMTL template\n *\n * @function deleteHTML\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} section - contains KSS section data\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nexport function deleteHTML(filepath, section, store) {\n const newSection = section;\n\n utils.removeFile(\n newSection.referenceURI,\n 'template',\n filepath,\n store\n );\n\n delete newSection.templatePath;\n\n return store\n .setIn(\n ['sections', 'sectionsByPath', section.kssPath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', section.referenceURI],\n newSection\n );\n}\n\n/**\n * Handle update for a prototype file\n *\n * @function updatePrototype\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nexport function updatePrototype(filepath, store) {\n const file = path.parse(filepath);\n const content = fs.readFileSync(filepath, 'utf8');\n\n if (content) {\n const requirePath = utils.writeFile(\n file.name,\n 'prototype',\n filepath,\n content,\n store\n );\n\n return store.setIn(\n ['prototypes', file.name],\n requirePath\n );\n }\n\n console.log(`File ${file.base} could not be read`);\n return store;\n}\n\n/**\n * Handle removal of a prototype file\n *\n * @function deletePrototype\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nexport function deletePrototype(filepath, store) {\n const file = path.parse(filepath);\n const requirePath = utils.removeFile(\n file.name,\n 'prototype',\n filepath,\n store\n );\n\n return store.setIn(\n ['prototypes', file.name],\n requirePath\n );\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/handleHTML.js","/** @module cli/kss-handler */\n\nimport path from 'path';\nimport fs from 'fs-extra';\nimport { parse } from 'kss';\nimport chalk from 'chalk';\n\nimport * as utils from './utils';\nimport { updateTemplate, deleteTemplate } from './handleTemplates';\nimport { writeStore } from './requireTemplates';\n\n/**\n * Handle update of a KSS section\n *\n * @function updateKSS\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nexport function updateKSS(filepath, store) {\n const kssSource = fs.readFileSync(filepath, 'utf8');\n const huron = store.get('config');\n const oldSection = utils.getSection(filepath, false, store) || {};\n const file = path.parse(filepath);\n let newStore = store;\n\n if (kssSource) {\n const styleguide = parse(kssSource, huron.get('kssOptions'));\n\n if (styleguide.data.sections.length) {\n const section = utils.normalizeSectionData(\n styleguide.data.sections[0]\n );\n\n if (section.reference && section.referenceURI) {\n // Update or add section data\n newStore = updateSectionData(\n filepath,\n section,\n oldSection,\n newStore\n );\n\n // Remove old section data if reference URI has changed\n if (oldSection &&\n oldSection.referenceURI &&\n oldSection.referenceURI !== section.referenceURI\n ) {\n newStore = unsetSection(oldSection, file, newStore, false);\n }\n\n writeStore(newStore);\n console.log(\n chalk.green(\n `KSS source in ${filepath} changed or added`\n )\n );\n return newStore;\n }\n\n console.log(\n chalk.magenta(\n `KSS section in ${filepath} is missing a section reference`\n )\n );\n return newStore;\n }\n\n console.log(chalk.magenta(`No KSS found in ${filepath}`));\n return newStore;\n }\n\n if (oldSection) {\n newStore = deleteKSS(filepath, oldSection, newStore);\n }\n\n console.log(chalk.red(`${filepath} not found or empty`)); // eslint-disable-line no-console\n return newStore;\n}\n\n/**\n * Handle removal of a KSS section\n *\n * @function deleteKSS\n * @param {string} filepath - filepath of changed file (comes from gaze)\n * @param {object} section - KSS section data\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nexport function deleteKSS(filepath, section, store) {\n const file = path.parse(filepath);\n\n if (section.reference && section.referenceURI) {\n // Remove section data from memory store\n return unsetSection(section, file, store, true);\n }\n\n return store;\n}\n\n/**\n * Update the sections store with new data for a specific section\n *\n * @function updateSectionData\n * @param {object} section - contains updated section data\n * @param {string} kssPath - path to KSS section\n * @param {object} store - memory store\n * @return {object} updated data store\n */\nfunction updateSectionData(kssPath, section, oldSection, store) {\n const sectionFileInfo = path.parse(kssPath);\n const dataFilepath = path.join(\n sectionFileInfo.dir,\n `${sectionFileInfo.name}.json`\n );\n const isInline = null !== section.markup.match(/<\\/[^>]*>/);\n const newSort = sortSection(\n store.getIn(['sections', 'sorted']),\n section.reference,\n store.get('referenceDelimiter')\n );\n const newSection = Object.assign({}, oldSection, section);\n let newStore = store;\n\n // Required for reference from templates and data\n newSection.kssPath = kssPath;\n\n if (isInline) {\n // Set section value if inlineTempalte() returned a path\n newStore = updateInlineTemplate(\n kssPath,\n oldSection,\n newSection,\n newStore\n );\n } else {\n // Remove inline template, if it exists\n utils.removeFile(\n newSection.referenceURI,\n 'template',\n kssPath,\n store\n );\n // Update markup and data fields\n newStore = updateTemplateFields(\n sectionFileInfo,\n oldSection,\n newSection,\n newStore\n );\n }\n\n // Output section description\n newStore = updateDescription(\n kssPath,\n oldSection,\n newSection,\n newStore\n );\n\n // Output section data to a JSON file\n newSection.sectionPath = utils.writeSectionData(\n newStore,\n newSection,\n dataFilepath\n );\n\n // Update section sorting\n return newStore\n .setIn(\n ['sections', 'sorted'],\n newSort\n )\n .setIn(\n ['sections', 'sectionsByPath', kssPath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', section.referenceURI],\n newSection\n );\n}\n\n/**\n * Handle detection and output of inline templates, which is markup written\n * in the KSS documentation itself as opposed to an external file\n *\n * @function updateInlineTemplate\n * @param {string} oldSection - previous iteration of KSS data, if updated\n * @param {object} section - KSS section data\n * @return {object} updated data store with new template path info\n */\nfunction updateInlineTemplate(filepath, oldSection, section, store) {\n const newSection = section;\n const newStore = store;\n\n // If we have inline markup\n if (fieldShouldOutput(oldSection, section, 'markup')) {\n newSection.templatePath = utils.writeFile(\n section.referenceURI,\n 'template',\n filepath,\n section.markup,\n store\n );\n newSection.templateContent = section.markup;\n\n return newStore\n .setIn(\n ['sections', 'sectionsByPath', filepath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', section.referenceURI],\n newSection\n );\n }\n\n return newStore;\n}\n\n/**\n * Handle output of section description\n *\n * @function updateDescription\n * @param {string} oldSection - previous iteration of KSS data, if updated\n * @param {object} section - KSS section data\n * @return {object} updated data store with new descripton path info\n */\nfunction updateDescription(filepath, oldSection, section, store) {\n const newSection = section;\n const newStore = store;\n\n // If we don't have previous KSS or the KSS has been updated\n if (fieldShouldOutput(oldSection, section, 'description')) {\n // Write new description\n newSection.descriptionPath = utils.writeFile(\n section.referenceURI,\n 'description',\n filepath,\n section.description,\n store\n );\n\n return newStore\n .setIn(\n ['sections', 'sectionsByPath', filepath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', section.referenceURI],\n newSection\n );\n }\n\n return newStore;\n}\n\n/**\n * Handle Data and Markup fields\n *\n * @function updateTemplateFields\n * @param {string} file - File data for KSS file from path.parse()\n * @param {object} oldSection - outdated KSS data\n * @param {object} section - KSS section data\n * @param {object} store - memory store\n * @return {object} KSS section data with updated asset paths\n */\nfunction updateTemplateFields(file, oldSection, section, store) {\n const kssPath = path.format(file);\n const newSection = section;\n let filepath = '';\n let oldFilepath = '';\n let newStore = store;\n\n ['data', 'markup'].forEach((field) => {\n if (newSection[field]) {\n if (oldSection[field]) {\n oldFilepath = path.join(file.dir, oldSection[field]);\n newStore = deleteTemplate(\n oldFilepath,\n oldSection,\n newStore\n );\n }\n\n filepath = path.join(file.dir, newSection[field]);\n newStore = updateTemplate(\n filepath,\n newSection,\n newStore\n );\n } else {\n delete newSection[field];\n newStore = newStore\n .setIn(\n ['sections', 'sectionsByPath', kssPath],\n newSection\n )\n .setIn(\n ['sections', 'sectionsByURI', newSection.referenceURI],\n newSection\n );\n }\n });\n\n return newStore;\n}\n\n/**\n * Remove a section from the memory store\n *\n * @function unsetSection\n * @param {object} section - contains updated section data\n * @param {string} file - file object from path.parse()\n * @param {object} store - memory store\n * @param {bool} removed - has the file been removed or just the section information changed?\n * @return {object} updated data store with new descripton path info\n */\nfunction unsetSection(section, file, store, removed) {\n const sorted = store.getIn(['sections', 'sorted']);\n const kssPath = path.format(file);\n const dataFilepath = path.join(file.dir, `${file.name}.json`);\n const isInline = section.markup &&\n null !== section.markup.match(/<\\/[^>]*>/);\n const newSort = unsortSection(\n sorted,\n section.reference,\n store.get('referenceDelimiter')\n );\n let newStore = store;\n\n // Remove old section data\n utils.removeFile(\n section.referenceURI,\n 'section',\n dataFilepath,\n newStore\n );\n\n // Remove associated inline template\n if (isInline) {\n utils.removeFile(section.referenceURI, 'template', kssPath, newStore);\n }\n\n // Remove description template\n utils.removeFile(section.referenceURI, 'description', kssPath, newStore);\n\n // Remove data from sectionsByPath if file has been removed\n if (removed) {\n newStore = newStore.deleteIn(['sections', 'sectionsByPath', kssPath]);\n }\n\n return newStore\n .deleteIn(['sections', 'sectionsByURI', section.referenceURI])\n .setIn(['sections', 'sorted'], newSort);\n}\n\n/**\n * Sort sections and subsections\n *\n * @function sortSection\n * @param {object} sorted - currently sorted sections\n * @param {string} reference - reference URI of section to sort\n * @return {object} updated data store with new descripton path info\n */\nfunction sortSection(sorted, reference, delimiter) {\n const parts = reference.split(delimiter);\n const newSort = sorted[parts[0]] || {};\n const newSorted = sorted;\n\n if (1 < parts.length) {\n const newParts = parts.filter((part, idx) => 0 !== idx);\n newSorted[parts[0]] = sortSection(\n newSort,\n newParts.join(delimiter),\n delimiter\n );\n } else {\n newSorted[parts[0]] = newSort;\n }\n\n return newSorted;\n}\n\n/**\n * Remove a section from the sorted sections\n *\n * @function unsortSection\n * @param {object} sorted - currently sorted sections\n * @param {string} reference - reference URI of section to sort\n * @return {object} updated data store with new descripton path info\n */\nfunction unsortSection(sorted, reference, delimiter) {\n const parts = reference.split(delimiter);\n const subsections = Object.keys(sorted[parts[0]]);\n const newSorted = sorted;\n\n if (subsections.length) {\n if (1 < parts.length) {\n const newParts = parts.filter((part, idx) => 0 !== idx);\n newSorted[parts[0]] = unsortSection(\n newSorted[parts[0]],\n newParts.join(delimiter),\n delimiter\n );\n }\n } else {\n delete newSorted[parts[0]];\n }\n\n return newSorted;\n}\n\n/**\n * Compare a KSS field between old and new KSS data to see if we need to output\n * a new module for that field\n *\n * @function fieldShouldOutput\n * @param {object} oldSection - currently sorted sections\n * @param {object} newSection - reference URI of section to sort\n * @param {string} field - KSS field to check\n * @return {bool} output a new module for the KSS field\n */\nfunction fieldShouldOutput(oldSection, newSection, field) {\n return (oldSection &&\n (oldSection[field] !== newSection[field] ||\n oldSection.referenceURI !== newSection.referenceURI)\n ) ||\n !oldSection;\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/handleKSS.js","// Necessary to remove require statement from Webpack processing preserve it in output\n/* eslint-disable import/no-dynamic-require, global-require */\nexport default function requireExternal(requirePath) {\n return require(requirePath);\n}\n/* eslint-enable */\n\n\n\n// WEBPACK FOOTER //\n// src/cli/requireExternal.js","/** @module cli/webpack-server */\nimport webpack from 'webpack';\nimport WebpackDevServer from 'webpack-dev-server';\nimport chalk from 'chalk';\nimport open from 'opn';\n\nimport createDevServerConfig from '../../config/devServer.config';\nimport program from './parseArgs';\nimport { removeTrailingSlash } from './utils';\n\n/**\n * Spin up webpack-dev-server or, if production flag is set, run webpack a single time\n *\n * @function startWebpack\n * @param {object} config - webpack configuration, preprocessed by {@link module:cli/generate-config generateConfig}\n * @see {@link module:cli/generate-config generateConfig}\n */\nexport default function startWebpack(config) {\n const huron = config.huron;\n const webpackConfig = config.webpack;\n const compiler = webpack(webpackConfig);\n\n if (program.progress) {\n compiler.apply(\n new webpack.ProgressPlugin(\n (percentage, msg) => {\n console.log(`${(percentage * 100)}% `, msg);\n }\n )\n );\n }\n\n if (program.production) {\n compiler.run((err, stats) => {\n const info = stats.toJson();\n\n if (err) {\n console.log(err);\n }\n\n if (stats.hasErrors()) {\n console.error(\n chalk.red(\n 'Webpack encountered errors during compile: ',\n info.errors\n )\n );\n }\n\n if (stats.hasWarnings()) {\n console.error(\n chalk.yellow(\n 'Webpack encountered warnings during compile: ', info.warnings\n )\n );\n }\n });\n } else {\n const server = new WebpackDevServer(compiler, createDevServerConfig(huron));\n const prototypeName = huron.prototypes[0].title || huron.prototypes[0];\n\n server.listen(\n huron.port,\n 'localhost',\n (err) => {\n if (err) {\n return console.log(err);\n }\n\n console.log(`Listening at http://localhost:${huron.port}/`);\n open(`http://localhost:${huron.port}/${\n removeTrailingSlash(huron.root)\n }/${prototypeName}.html`);\n return true;\n }\n );\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// src/cli/server.js","import path from 'path';\n\nexport default {\n css: [],\n entry: 'huron',\n js: [],\n kss: 'css/',\n kssExtension: '.css',\n kssOptions: {\n multiline: true,\n markdown: true,\n custom: ['data'],\n },\n output: 'partials',\n port: 8080,\n prototypes: ['index'],\n root: 'dist/',\n sectionTemplate: path.join(__dirname, '../../templates/section.hbs'),\n classNames: false,\n templates: {\n rule: {\n test: /\\.(hbs|handlebars)$/,\n use: 'handlebars-loader',\n },\n extension: '.hbs',\n },\n window: {},\n};\n\n\n\n// WEBPACK FOOTER //\n// src/defaultConfig/huron.config.js","import webpack from 'webpack';\nimport path from 'path';\n\nimport program from '../cli/parseArgs';\n\nexport default (huron) => {\n const cwd = process.cwd();\n\n return {\n entry: {},\n output: {\n path: path.join(cwd, huron.root),\n publicPath: program.production ? '' :\n `http://localhost:${huron.port}/${huron.root}`,\n filename: '[name].js',\n chunkFilename: '[name].chunk.min.js',\n },\n plugins: [\n new webpack.HotModuleReplacementPlugin(),\n new webpack.NamedModulesPlugin(),\n ],\n resolve: {\n modulesDirectories: [\n path.resolve(__dirname, '../src/js'),\n ],\n },\n resolveLoader: {\n modulesDirectories: [\n 'web_loaders',\n 'web_modules',\n 'node_loaders',\n 'node_modules',\n path.resolve(__dirname, '../node_modules'),\n ],\n },\n module: {\n rules: [\n {\n test: /\\.html$/,\n include: [path.join(cwd, huron.root, huron.output)],\n use: 'html-loader',\n },\n {\n test: /\\.(hbs|handlebars)$/,\n include: [path.join(cwd, huron.root, 'huron-assets')],\n use: {\n loader: 'handlebars-loader',\n options: {\n helperDirs: [path.join(\n __dirname,\n '../../',\n 'templates/handlebarsHelpers'\n )],\n },\n },\n },\n ],\n },\n };\n};\n\n\n\n// WEBPACK FOOTER //\n// src/defaultConfig/webpack.config.js","module.exports = \"'use strict';\\n\\nvar _huronStore = require('./huron-store');\\n\\nvar _huronStore2 = _interopRequireDefault(_huronStore);\\n\\nvar _insertNodes = require('./insertNodes');\\n\\nvar _insertNodes2 = _interopRequireDefault(_insertNodes);\\n\\nvar _section = require('./section.hbs');\\n\\nvar _section2 = _interopRequireDefault(_section);\\n\\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\\n\\n/* eslint-enable */\\n\\nconst assets = require.context(hotScope.requirePath, true, hotScope.requireRegex); /* globals hotScope */\\n\\n// NOTE: This is not a normal JS file! It is pulled in by the CLI as a string\\n// and prepended to the browser script after replacing anything referenced via `hotScope[variable]`\\n// with CLI arguments or config properties passed in by the user.\\n\\n/* eslint-disable */\\n\\nconst modules = {};\\n\\nmodules[hotScope.sectionTemplatePath] = _section2.default;\\n\\nassets.keys().forEach(key => {\\n modules[key] = assets(key);\\n});\\n\\nconst insert = new _insertNodes2.default(modules, _huronStore2.default);\\n\\nif (module.hot) {\\n // Hot Module Replacement for huron components (json, hbs, html)\\n module.hot.accept(assets.id, () => {\\n const newAssets = require.context(hotScope.requirePath, true, hotScope.requireRegex);\\n const newModules = newAssets.keys().map(key => [key, newAssets(key)]).filter(newModule => modules[newModule[0]] !== newModule[1]);\\n\\n updateStore(require('./huron-store.js')); // eslint-disable-line global-require, import/no-unresolved\\n newModules.forEach(module => {\\n modules[module[0]] = module[1];\\n hotReplace(module[0], module[1], modules);\\n });\\n });\\n\\n // Hot Module Replacement for sections template\\n module.hot.accept('./section.hbs', () => {\\n const newSectionTemplate = require('./section.hbs'); // eslint-disable-line global-require, import/no-unresolved\\n\\n modules[hotScope.sectionTemplatePath] = newSectionTemplate;\\n hotReplace('./huron-assets/section.hbs', newSectionTemplate, modules);\\n });\\n\\n // Hot Module Replacement for data store\\n module.hot.accept('./huron-store.js', () => {\\n updateStore(require('./huron-store.js')); // eslint-disable-line global-require, import/no-unresolved\\n });\\n}\\n\\nfunction hotReplace(key, module, newModules) {\\n insert.modules = newModules;\\n if (key === _huronStore2.default.sectionTemplatePath) {\\n insert.cycleSections();\\n } else {\\n insert.inserted = [];\\n insert.loadModule(key, module, false);\\n }\\n}\\n\\nfunction updateStore(newStore) {\\n insert.store = newStore;\\n}\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/raw-loader!./~/babel-loader/lib!./templates/hotTemplate.js\n// module id = 20\n// module chunks = 0","module.exports = require(\"commander\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"commander\"\n// module id = 21\n// module chunks = 0","module.exports = require(\"gaze\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"gaze\"\n// module id = 22\n// module chunks = 0","module.exports = require(\"html-webpack-plugin\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"html-webpack-plugin\"\n// module id = 23\n// module chunks = 0","module.exports = require(\"immutable\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"immutable\"\n// module id = 24\n// module chunks = 0","module.exports = require(\"kss\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"kss\"\n// module id = 25\n// module chunks = 0","module.exports = require(\"lodash/isEqual\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"lodash/isEqual\"\n// module id = 26\n// module chunks = 0","module.exports = require(\"opn\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"opn\"\n// module id = 27\n// module chunks = 0","module.exports = require(\"url\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"url\"\n// module id = 28\n// module chunks = 0","module.exports = require(\"webpack-dev-server\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"webpack-dev-server\"\n// module id = 29\n// module chunks = 0"],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;A;;;;AChEA;;;;;;;;;;;;ACcA;AAkBA;AAqCA;AAqCA;AAcA;AAkBA;AAyBA;AA4CA;AAyCA;AAyBA;AAyBA;AAqBA;AA6CA;AACA;AA5WA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;;;AACA;AACA;AACA;;;;;;;AAPA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AAGA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AAGA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;;AAFA;AAKA;AACA;AACA;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AClXA;;;;;;ACAA;;;;;;;;;;;;;ACGA;AACA;;;AAAA;AACA;;;;;AACA;AACA;AACA;AACA;;;;;;AATA;AACA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAYA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACzDA;;;;;;;;;;;;;;ACAA;AACA;AACA;AACA;;;AAAA;AACA;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAKA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AAnBA;AAqBA;AACA;AACA;AAAA;;;;;;;;;;;;ACzBA;AA0DA;AACA;AA1EA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;AADA;AACA;;;;;AACA;;;;;;;;;AAPA;AAgBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAUA;;;;;;;;;;;;;;AClGA;AACA;;;AAAA;AACA;;;AAIA;AACA;;;;;AAAA;AACA;AACA;AACA;AAPA;AACA;AACA;AANA;AACA;AAUA;AACA;AAIA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AALA;AAOA;AACA;AAOA;AACA;AAIA;AAIA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;;;;;;;;;ACxEA;AACA;;;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;AAAA;AACA;;;;;AACA;;;;;AAhBA;AAqBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACvGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AATA;AAWA;AACA;AACA;AAjBA;;;;;;;;;;;;ACwBA;AA8CA;AA+DA;AA0DA;AACA;AA7LA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AADA;AACA;;;;;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA1BA;AACA;AA4BA;AACA;AACA;AACA;;;;;;;AA/DA;AACA;AACA;AAoEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAxCA;AACA;AA0CA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AArCA;AACA;AAuCA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;AC5MA;AACA;AAAA;AACA;;;AACA;AACA;AAAA;AACA;;;AACA;;;;;AAKA;AACA;AACA;;;;;AAKA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;;;;;AAKA;AACA;AACA;;;;;;;;;;;;ACtBA;AACA;AA9BA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;;;AACA;AACA;AACA;AAdA;AAeA;AACA;AAGA;AACA;AAGA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAKA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAZA;AAcA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AC7RA;AA0CA;AA+BA;AA+BA;AACA;AAvHA;AACA;;;AAAA;AACA;;;AACA;AACA;AADA;AACA;;;;;AACA;;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAhDA;AAyDA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AASA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AAMA;AAIA;;;;;;;;;;;;ACjHA;AAsEA;AACA;AAxFA;AACA;;;AAAA;AACA;;;AAAA;AACA;AAAA;AACA;;;AACA;AACA;AADA;AACA;AAAA;AACA;AAAA;AACA;;;;;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAMA;AACA;AAIA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAhFA;AACA;AAwFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AASA;AACA;AACA;AAIA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AAMA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAKA;AACA;AAaA;AACA;AACA;;;;;;;;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AASA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAKA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAUA;AACA;AACA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAUA;AACA;AAKA;;;;;;;;;;;AC5aA;AAFA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACYA;AACA;AAjBA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;AACA;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;;;;;;;;;;;;;AC7EA;AACA;;;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AALA;AAOA;AAxBA;;;;;;;;;;;;;ACFA;AACA;;;AAAA;AACA;;;AACA;AACA;;;;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AALA;AAOA;AAIA;AACA;AADA;AAKA;AACA;AADA;AASA;AACA;AAEA;AACA;AACA;AAHA;AAMA;AACA;AACA;AACA;AACA;AACA;AADA;AAFA;AAHA;AAPA;AA3BA;AAmDA;;;;;;AC3DA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;ACAA;;;;;;;;;;A","sourceRoot":""} \ No newline at end of file diff --git a/package.json b/package.json index 0a27db7..6322eeb 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "huron", "description": "An in-browser prototyping tool built on top of webpack and kss-node", "author": "Alley Interactive", - "version": "2.3.0", + "version": "2.3.1", "license": "GPL-2.0", "repository": { "type": "git", diff --git a/src/cli/index.js b/src/cli/index.js index 247142c..597bdd7 100644 --- a/src/cli/index.js +++ b/src/cli/index.js @@ -28,7 +28,6 @@ writeStore(store); // If building for production, close gaze and exit process once initFiles is done. if (program.production) { gaze.close(); - process.exit(); } /** @module cli/gaze */