[
  {
    "path": ".babelrc",
    "content": "{\n    \"presets\": [\"env\"],\n    \"plugins\": [\"babel-plugin-add-module-exports\"]\n}"
  },
  {
    "path": ".eslintrc",
    "content": "{\n    \"parser\": \"babel-eslint\",\n    \"env\": {\n        \"browser\": true,\n        \"commonjs\": true,\n        \"es6\": true,\n        \"node\": true\n    },\n    \"rules\": {\n        \"no-const-assign\": \"warn\",\n        \"no-this-before-super\": \"warn\",\n        \"no-unreachable\": \"warn\",\n        \"no-unused-vars\": \"warn\",\n        \"constructor-super\": \"warn\",\n        \"valid-typeof\": \"warn\",\n        \"quotes\": [2, \"single\", { \"allowTemplateLiterals\": true }]\n    }\n}\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "## Expected Behavior\n\n\n## Actual Behavior\n\n\n## Steps to Reproduce the Problem\n\n1.\n1.\n1.\n\n## Specifications\n\n- Version:\n- Platform:\n- Browser:\n- Environment/Url: "
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "Fixes Issue # (Delete if not applicable)\n\n## Proposed Changes\n\n-\n-\n-\n\n## Add a GIF that demonstrates how this Pull Request makes you feel (optional)\n![alt text](Path to image) "
  },
  {
    "path": ".gitignore",
    "content": "# Common\nnode_modules\n.DS_Store\n.sass-cache\n*.log\n*.scssc\nnpm-debug.*\n.env\n\n# Compiled assets\npattern-library/assets/css\n\n# Ignore 'sandbox'. This is where you can play around with features etc\nsandbox/\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nWhen contributing to this repository, please first discuss the change you wish to make via issue,\nemail, or any other method with the owners of this repository before making a change. \n\nPlease note we have a code of conduct, please follow it in all your interactions with the project.\n\n## Pull Request Process\n\n1. Ensure any install or build dependencies are removed before the end of the layer when doing a \n   build.\n2. Ensure your work is thoroughly tested, to the best of your abilities\n2. You may merge the Pull Request in once you have the sign-off from a maintainer\n\n## Code of Conduct\n\n### Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, gender identity and expression, level of experience,\nnationality, personal appearance, race, religion, or sexual identity and\norientation.\n\n### Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n- Using welcoming and inclusive language\n- Being respectful of differing viewpoints and experiences\n- Gracefully accepting constructive criticism\n- Focusing on what is best for the community\n- Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n- The use of sexualized language or imagery and unwelcome sexual attention or\nadvances\n- Trolling, insulting/derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n- Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n### Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n### Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n### Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at andy@hankchizljaw.io. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n### Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/"
  },
  {
    "path": "LICENSE.txt",
    "content": "MIT License\n\nCopyright (c) 2018 hankchizljaw.io and other contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "assets/js/boilerform.js",
    "content": "import Validation from './modules/validation';\n\n// Import Sass so that webpack picks it up\nrequire('../scss/boilerform.scss');\n\n(function() {\n\n    // Look for child and root forms \n    const boilerforms = [...document.querySelectorAll('.boilerform form, form.boilerform')];\n    \n    if(boilerforms.length) {\n\n        // Add a validator to each form instance\n        boilerforms.map(item => {\n            let validationInstance = new Validation(item);\n\n            validationInstance.init();\n        });  \n    }\n}());\n"
  },
  {
    "path": "assets/js/modules/validation.js",
    "content": "export default class Validation {\n\n    /**\n     * Load up an instance of Validation\n     * @param {HTMLFormElement} baseForm \n     */\n    constructor(baseForm) {\n        this.baseForm = baseForm;\n\n        // Load child input elements\n        this.inputElems = [...baseForm.querySelectorAll('input, textarea, select')];\n    }\n\n    /**\n     * Public init method\n     */\n    init() {\n        let self = this;\n\n        self.bind();\n    }\n\n    /**\n     * Bind events to input elements\n     */\n    bind() {\n        let self = this;\n\n        // Add an invalid listener that \n        self.inputElems.map(item => {\n            item.addEventListener('invalid', () => {\n                self.processValidity(item);\n                self.checkSiblings(item);\n            }, false);\n        });\n    }\n\n    /**\n     * Toggle the visual state of an item based on the based state key\n     * @param {HTMLElement} item \n     * @param {String} state \n     */\n    process(item, state = 'invalid') {\n\n        switch(state) {\n            case 'invalid':\n                item.classList.add('is-error');\n                break;\n            default: \n                item.classList.remove('is-error');\n                break;\n        }\n    }\n\n    /**\n     * Filter sibling elements and run them through the validity checker\n     *\n     * @param {HTMLFormElement} exludedField\n     */\n    checkSiblings(exludedField) {\n        let self = this;\n\n        self.inputElems\n            .filter(item => item !== exludedField)\n            .map(item => self.processValidity(item));\n    }\n\n    /**\n     * Run some checks to determine if the passed item is valid or not\n     * @param {HTMLElement} item \n     */\n    processValidity(item) {\n        let self = this;\n\n        // If an item is valid, run the processor and bail\n        if(item.validity.valid) {\n            self.process(item, 'valid');\n            return;\n        }\n\n        // If we're here, it's invalid\n        self.process(item, 'invalid');\n    }\n};\n"
  },
  {
    "path": "assets/scss/_config.scss",
    "content": "// Colors\n$colors: (\n    base: (\n        text: #141414,\n        border: #cccccc \n    ),\n    button: (\n        background: #666666,\n        background--hover: #888888,\n        text: #ffffff\n    ),\n    check: (\n        decor: #eeeeee,\n        decor--active: #aaaaaa,\n        decor__inner: #888888\n    ),\n    field: (\n        background: #ffffff\n    ),\n    state: (\n        error: #cf0b00\n    )\n);\n\n// Metrics\n$button-padding: 11px 25px 10px 25px;\n$check-field-decor-size: 20px;\n$check-field-flow: 10px;\n$check-field-label-padding: 3px 0 0 10px;\n$input-field-vertical-padding: 10px;\n$input-field-horizontal-padding: 15px;\n$input-field-padding: #{ $input-field-vertical-padding + 1 } $input-field-horizontal-padding $input-field-vertical-padding $input-field-horizontal-padding;\n$multiline-min-height: 80px;\n\n// Decorative\n$border-radius: 2px;\n\n// Typography \n$base-font-family: sans-serif;\n$base-font-size: 16px;\n$input-field-font-size: 1rem;"
  },
  {
    "path": "assets/scss/_functions.scss",
    "content": "/*------------------------------------*\\\n    COLOR\n\n    Pass in a group name and a key\n    to get a value. \n\n    E.G color(field, background) will return\n    the background item in the field group.\n\n    Colors are defined in $colors in _config.scss\n\\*------------------------------------*/\n@function color($group, $color) {\n    @return map-get(map-get($colors, $group), $color);\n}"
  },
  {
    "path": "assets/scss/_helpers.scss",
    "content": "// All input fields share these styles. Also includes select menus\n%c-field-shared-inputs {\n    background: color(field, background);\n    border: 1px solid color(base, border);\n    padding: $input-field-padding;\n    border-radius: $border-radius;\n    font-size: $input-field-font-size;\n}\n\n// Visually hide an element, but allow a screen-reader to see it\n%visually-hidden {\n    display: block;\n    height: 1px;\n    width: 1px;\n    overflow: hidden;\n    clip: rect(1px 1px 1px 1px);\n    clip: rect(1px, 1px, 1px, 1px);\n    clip-path: inset(1px);\n    white-space: nowrap;\n    position: absolute;\n}\n"
  },
  {
    "path": "assets/scss/_reset.scss",
    "content": "@include namespace(true) {\n    \n    // Set base pixel size for REM units to work off\n    font-size: $base-font-size;\n    \n    // Set the base color \n    color: color(base, text);\n\n    // Set base border color\n    border-color: color(base, border);\n\n    // Box sizing border-box FTW\n    &,\n    & * {\n        box-sizing: border-box;\n    }\n    \n    // All field elements\n    [class*=\"-field\"] {\n        margin: 0;\n        display: inline-block;\n        vertical-align: middle;\n        white-space: normal;\n        line-height: 1.1;\n        font-family: $base-font-family;\n    }\n\n    // All decorative elements \n    [class*=\"decor\"] {\n        line-height: 0;\n    }\n\n    // Turn off the recent search in WebKit.\n    ::-webkit-search-decoration {\n        display: none;\n    }\n\n    // Normalise form field line-height in WebKit\n    input::-webkit-input-placeholder,\n    textarea::-webkit-input-placeholder,\n    select::-webkit-input-placeholder {\n        line-height: normal;\n    }\n\n    // Make a search box appear like a text box\n    input[type=\"search\"] {\n        -webkit-appearance: textfield;\n    }\n}"
  },
  {
    "path": "assets/scss/boilerform.scss",
    "content": "// Pull config \n@import \"config\";\n\n// Mixins\n@import \"mixins/namespace\";\n\n// Functions\n@import \"functions\";\n\n// Helpers\n@import \"helpers\";\n\n// Resets \n@import \"reset\";\n\n// Components\n@import \"components/c-button\";\n@import \"components/c-check-field\";\n@import \"components/c-input-field\";\n@import \"components/c-label\";\n@import \"components/c-select-field\";\n\n// Layouts\n@import \"layouts/l-form\";\n\n// Shared styles\n@include namespace(true) {\n\n    // Override border color for errors\n    .is-error {\n        &,\n        [class*=\"menu\"],\n        [class*=\"check\"] {\n            border-color: color(state, error);\n            \n            // Remove default focus and replace with a heavy shadow if invalid\n            &:focus {\n                outline: none;\n                box-shadow: 0 0 0 2px color(state, error);\n            }\n        }\n    }\n}"
  },
  {
    "path": "assets/scss/components/_c-button.scss",
    "content": "/*------------------------------------*\\\n    BUTTON COMPONENT\n\n    Base button styles and reset\n\\*------------------------------------*/\n$namespace: \".c-button\";\n\n#{ $namespace } {\n\n    @include namespace() {\n        \n        display: inline-block;\n        border: none;\n        padding: 0;\n        margin: 0;\n        text-decoration: none;\n        background: color(button, background);\n        color: color(button, text);\n        padding: $button-padding;\n        font-family: $base-font-family;\n        font-size: 1rem;\n        border-radius: $border-radius;\n        cursor: pointer;\n        text-align: center;\n        -webkit-appearance: none;\n        -moz-appearance: none;\n\n        &:hover,\n        &:focus {\n            background: color(button, background--hover);\n        }\n    }\n}"
  },
  {
    "path": "assets/scss/components/_c-check-field.scss",
    "content": "/*------------------------------------*\\\n    CHECK FIELD COMPONENT\n\n    Radio buttons and checkboxes\n\\*------------------------------------*/\n$namespace: \".c-check-field\";\n\n#{ $namespace } {\n\n    @include namespace() {\n        display: flex;\n        flex-direction: row;\n        align-items: flex-start;\n\n        // Visually hide the input\n        &__input {\n            @extend %visually-hidden;\n        }\n\n        &__decor {\n            display: block;\n            width: $check-field-decor-size;\n            height: $check-field-decor-size;\n            flex-shrink: 0;\n            background: color(check, decor);\n            border: 1px solid color(base, border);\n            border-radius: $border-radius;\n            position: relative;\n            cursor: pointer;\n\n            &:after {\n                content: \"\";\n                speak: none;\n                display: block;\n                opacity: 0;\n                width: 70%;\n                height: 70%;\n                position: absolute;\n                top: 15%;\n                left: 15%;\n                background: color(check, decor__inner);\n                border-radius: #{ $border-radius / 2 };\n            }\n        }\n\n        &__label {\n            padding: $check-field-label-padding;\n            cursor: pointer;\n        }\n\n        // Radio modifier\n        &--radio #{ $namespace }__decor {\n            &,\n            &:after {\n                border-radius: 50%;\n            }\n        }\n\n        // Checked state\n        &__input:checked ~ [class*=\"decor\"] {\n            &:after {\n                opacity: 1;\n            }\n        }\n\n        // Focused state\n        &__input:focus ~ [class*=\"decor\"] {\n            outline: 1px dotted #212121;\n            outline: 5px auto -webkit-focus-ring-color;\n        }\n\n        // Flow between instances\n        & + #{ $namespace } {\n            padding-top: $check-field-flow;\n        }\n    }\n}\n"
  },
  {
    "path": "assets/scss/components/_c-input-field.scss",
    "content": "/*------------------------------------*\\\n    INPUT FIELD COMPONENT\n\n    All input based form field elements\n\\*------------------------------------*/\n$namespace: \".c-input-field\";\n\n#{ $namespace } {\n\n    @include namespace() {\n\n        @extend %c-field-shared-inputs;\n\n        // Reduce right-hand padding for number inputs\n        &[type=\"number\"] {\n            padding-right: #{ $input-field-padding / 2 };\n        }\n\n        // Multiline fields like <textarea> etc\n        &--multiline {\n            vertical-align: top;\n            overflow: auto;\n            width: 100%;\n\n            &:not([rows]) {\n                min-height: $multiline-min-height;\n            }\n        }\n    }\n}"
  },
  {
    "path": "assets/scss/components/_c-label.scss",
    "content": "/*------------------------------------*\\\n    LABEL COMPONENT\n\n    A simple form label\n\\*------------------------------------*/\n$namespace: \".c-label\";\n\n#{ $namespace } {\n    \n    @include namespace() {\n        display: inline;\n        font-family: $base-font-family;\n        font-weight: 700;\n        font-size: 0.88rem;\n\n        // Only add a pointer cursor if there's a for attribute\n        &[for] {\n            cursor: pointer;\n        }\n\n        // Create a line break\n        &:after {\n            content: \"\\A\";\n            white-space: pre;\n        }\n\n        // Add space between a label and a field\n        & + [class*=\"field\"] {\n            margin-top: 2px;\n        }\n    }\n}"
  },
  {
    "path": "assets/scss/components/_c-select-field.scss",
    "content": "/*------------------------------------*\\\n    SELECT FIELD\n\n    Option driven fields such as \n    <select> menus\n\\*------------------------------------*/\n$namespace: \".c-select-field\";\n\n#{ $namespace } {\n    \n    @include namespace() {\n        \n        display: inline-block;\n        position: relative;\n\n        &__menu {\n            @extend %c-field-shared-inputs;\n\n            -webkit-appearance: none;\n            -moz-appearance: none;\n            padding-right: #{ $input-field-horizontal-padding * 3 };\n\n            // Undo Firefox focus ring \n            &:-moz-focusring {\n                color: transparent;\n                text-shadow: 0 0 0 color(base, text);\n            }\n\n            // Remove arrow in IE\n            &::-ms-expand {\n                display: none;\n            }\n        }\n\n        &__decor {\n            position: absolute;\n            top: 50%;\n            right: $input-field-horizontal-padding;\n            pointer-events: none;\n        }\n    }\n}"
  },
  {
    "path": "assets/scss/layouts/_l-form.scss",
    "content": "/*------------------------------------*\\\n    FORM LAYOUT\n\n    The main form layout that gives\n    you rythm, alignment and flow\n\\*------------------------------------*/\n$namespace: \".l-form\";\n\n#{ $namespace } {\n\n    @include namespace() {\n\n    }\n}"
  },
  {
    "path": "assets/scss/mixins/_namespace.scss",
    "content": "/*------------------------------------*\\\n    NAMESPACE\n\n    This mixin encapsulates CSS within \n    a namespace to prevent outside\n    conflicts as much as possible.\n\\*------------------------------------*/\n@mixin namespace($isRoot: false) {\n\n    @if ($isRoot == true) {\n        .boilerform {\n            @content;\n        }\n    }\n    @else {\n        .boilerform & {\n            @content;\n        }\n    }\n}"
  },
  {
    "path": "astrum-config.json",
    "content": "{\n    \"path\": \"pattern-library\"\n}"
  },
  {
    "path": "dist/css/boilerform.css",
    "content": "/*------------------------------------*    NAMESPACE\n\n    This mixin encapsulates CSS within \n    a namespace to prevent outside\n    conflicts as much as possible.\n\\*------------------------------------*/\n/*------------------------------------*    COLOR\n\n    Pass in a group name and a key\n    to get a value. \n\n    E.G color(field, background) will return\n    the background item in the field group.\n\n    Colors are defined in $colors in _config.scss\n\\*------------------------------------*/\n.boilerform .c-input-field, .boilerform .c-select-field__menu {\n  background: #ffffff;\n  border: 1px solid #cccccc;\n  padding: 11px 15px 10px 15px;\n  border-radius: 2px;\n  font-size: 1rem; }\n\n.boilerform .c-check-field__input {\n  display: block;\n  height: 1px;\n  width: 1px;\n  overflow: hidden;\n  clip: rect(1px 1px 1px 1px);\n  clip: rect(1px, 1px, 1px, 1px);\n  clip-path: inset(1px);\n  white-space: nowrap;\n  position: absolute; }\n\n.boilerform {\n  font-size: 16px;\n  color: #141414;\n  border-color: #cccccc; }\n  .boilerform,\n  .boilerform * {\n    box-sizing: border-box; }\n  .boilerform [class*=\"-field\"] {\n    margin: 0;\n    display: inline-block;\n    vertical-align: middle;\n    white-space: normal;\n    line-height: 1.1;\n    font-family: sans-serif; }\n  .boilerform [class*=\"decor\"] {\n    line-height: 0; }\n  .boilerform ::-webkit-search-decoration {\n    display: none; }\n  .boilerform input::-webkit-input-placeholder,\n  .boilerform textarea::-webkit-input-placeholder,\n  .boilerform select::-webkit-input-placeholder {\n    line-height: normal; }\n  .boilerform input[type=\"search\"] {\n    -webkit-appearance: textfield; }\n\n/*------------------------------------*    BUTTON COMPONENT\n\n    Base button styles and reset\n\\*------------------------------------*/\n.boilerform .c-button {\n  display: inline-block;\n  border: none;\n  padding: 0;\n  margin: 0;\n  text-decoration: none;\n  background: #666666;\n  color: #ffffff;\n  padding: 11px 25px 10px 25px;\n  font-family: sans-serif;\n  font-size: 1rem;\n  border-radius: 2px;\n  cursor: pointer;\n  text-align: center;\n  -webkit-appearance: none;\n  -moz-appearance: none; }\n  .boilerform .c-button:hover, .boilerform .c-button:focus {\n    background: #888888; }\n\n/*------------------------------------*    CHECK FIELD COMPONENT\n\n    Radio buttons and checkboxes\n\\*------------------------------------*/\n.boilerform .c-check-field {\n  display: flex;\n  flex-direction: row;\n  align-items: flex-start; }\n  .boilerform .c-check-field__decor {\n    display: block;\n    width: 20px;\n    height: 20px;\n    flex-shrink: 0;\n    background: #eeeeee;\n    border: 1px solid #cccccc;\n    border-radius: 2px;\n    position: relative;\n    cursor: pointer; }\n    .boilerform .c-check-field__decor:after {\n      content: \"\";\n      speak: none;\n      display: block;\n      opacity: 0;\n      width: 70%;\n      height: 70%;\n      position: absolute;\n      top: 15%;\n      left: 15%;\n      background: #888888;\n      border-radius: 1px; }\n  .boilerform .c-check-field__label {\n    padding: 3px 0 0 10px;\n    cursor: pointer; }\n  .boilerform .c-check-field--radio .c-check-field__decor, .boilerform .c-check-field--radio .c-check-field__decor:after {\n    border-radius: 50%; }\n  .boilerform .c-check-field__input:checked ~ [class*=\"decor\"]:after {\n    opacity: 1; }\n  .boilerform .c-check-field__input:focus ~ [class*=\"decor\"] {\n    outline: 1px dotted #212121;\n    outline: 5px auto -webkit-focus-ring-color; }\n  .boilerform .c-check-field + .c-check-field {\n    padding-top: 10px; }\n\n/*------------------------------------*    INPUT FIELD COMPONENT\n\n    All input based form field elements\n\\*------------------------------------*/\n.boilerform .c-input-field[type=\"number\"] {\n  padding-right: 11px 15px 10px 15px / 2; }\n\n.boilerform .c-input-field--multiline {\n  vertical-align: top;\n  overflow: auto;\n  width: 100%; }\n  .boilerform .c-input-field--multiline:not([rows]) {\n    min-height: 80px; }\n\n/*------------------------------------*    LABEL COMPONENT\n\n    A simple form label\n\\*------------------------------------*/\n.boilerform .c-label {\n  display: inline;\n  font-family: sans-serif;\n  font-weight: 700;\n  font-size: 0.88rem; }\n  .boilerform .c-label[for] {\n    cursor: pointer; }\n  .boilerform .c-label:after {\n    content: \"\\A\";\n    white-space: pre; }\n  .boilerform .c-label + [class*=\"field\"] {\n    margin-top: 2px; }\n\n/*------------------------------------*    SELECT FIELD\n\n    Option driven fields such as \n    <select> menus\n\\*------------------------------------*/\n.boilerform .c-select-field {\n  display: inline-block;\n  position: relative; }\n  .boilerform .c-select-field__menu {\n    -webkit-appearance: none;\n    -moz-appearance: none;\n    padding-right: 45px; }\n    .boilerform .c-select-field__menu:-moz-focusring {\n      color: transparent;\n      text-shadow: 0 0 0 #141414; }\n    .boilerform .c-select-field__menu::-ms-expand {\n      display: none; }\n  .boilerform .c-select-field__decor {\n    position: absolute;\n    top: 50%;\n    right: 15px;\n    pointer-events: none; }\n\n/*------------------------------------*    FORM LAYOUT\n\n    The main form layout that gives\n    you rythm, alignment and flow\n\\*------------------------------------*/\n.boilerform .is-error,\n.boilerform .is-error [class*=\"menu\"],\n.boilerform .is-error [class*=\"check\"] {\n  border-color: #cf0b00; }\n  .boilerform .is-error:focus,\n  .boilerform .is-error [class*=\"menu\"]:focus,\n  .boilerform .is-error [class*=\"check\"]:focus {\n    outline: none;\n    box-shadow: 0 0 0 2px #cf0b00; }\n\n/*# sourceMappingURL=boilerform.css.map*/"
  },
  {
    "path": "dist/js/boilerform.js",
    "content": "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"boilerform\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"boilerform\"] = factory();\n\telse\n\t\troot[\"boilerform\"] = factory();\n})(typeof self !== 'undefined' ? self : this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \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// 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 = 0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _validation = __webpack_require__(1);\n\nvar _validation2 = _interopRequireDefault(_validation);\n\nvar _boilerform = __webpack_require__(2);\n\nvar _boilerform2 = _interopRequireDefault(_boilerform);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\n// Import Sass so that webpack picks it up\n\n\n(function () {\n\n    // Look for child and root forms \n    var boilerforms = [].concat(_toConsumableArray(document.querySelector('.boilerform form, form.boilerform')));\n\n    if (boilerforms.length) {\n\n        // Add a validator to each form instance\n        boilerforms.map(function (item) {\n            var validationInstance = new _validation2.default(item);\n\n            validationInstance.init();\n        });\n    }\n})();\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar Validation = function () {\n\n    /**\n     * Load up an instance of Validation\n     * @param {HTMLFormElement} baseForm \n     */\n    function Validation(baseForm) {\n        _classCallCheck(this, Validation);\n\n        this.baseForm = baseForm;\n\n        // Load child input elements\n        this.inputElems = [].concat(_toConsumableArray(baseForm.querySelectorAll('input, textarea, select')));\n    }\n\n    /**\n     * Public init method\n     */\n\n\n    _createClass(Validation, [{\n        key: 'init',\n        value: function init() {\n            var self = this;\n\n            self.bind();\n            self.setCustomValidationMessages();\n        }\n\n        /**\n         * Bind events to input elements\n         */\n\n    }, {\n        key: 'bind',\n        value: function bind() {\n            var self = this;\n\n            // Add an invalid listener that \n            self.inputElems.map(function (item) {\n                item.addEventListener('invalid', function (evt) {\n                    self.processValidity(item);\n                }, false);\n            });\n        }\n\n        /**\n         * Run through each item and check they have a `data-validation-message` attribute.\n         * If so, set a custom validation message with that value\n         */\n\n    }, {\n        key: 'setCustomValidationMessages',\n        value: function setCustomValidationMessages() {\n            var self = this;\n\n            self.inputElems.map(function (item) {\n                self.setCustomValidationMessage(item);\n            });\n        }\n\n        /**\n         * Set a custom validation message if item needs it\n         * @param {HTMLElement} item \n         */\n\n    }, {\n        key: 'setCustomValidationMessage',\n        value: function setCustomValidationMessage(item) {\n            var self = this;\n\n            if (item.hasAttribute('data-validation-message')) {\n                item.setCustomValidity(item.getAttribute('data-validation-message'));\n            }\n        }\n\n        /**\n         * Toggle the visual state of an item based on the based state key\n         * @param {HTMLElement} item \n         * @param {String} state \n         */\n\n    }, {\n        key: 'process',\n        value: function process(item) {\n            var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'invalid';\n\n            var self = this;\n\n            switch (state) {\n                case 'invalid':\n                    item.classList.add('is-error');\n                    self.setCustomValidationMessage(item);\n                    break;\n                default:\n                    item.classList.remove('is-error');\n                    break;\n            }\n        }\n\n        /**\n         * Run some checks to determine if the passed item is valid or not\n         * @param {HTMLElement} item \n         */\n\n    }, {\n        key: 'processValidity',\n        value: function processValidity(item) {\n            var self = this;\n\n            // If an item is valid, run the processor and bail\n            if (item.validity.valid) {\n                self.process(item, 'valid');\n                self.checkSiblings(item);\n                return;\n            }\n\n            // Before we determine it as invalid, check to see if there's a custom error\n            if (item.validity.customError) {\n\n                // Now let's check against some states\n                if (!item.validity.badInput && !item.validity.patternMismatch && !item.validity.rangeOverflow && !item.validity.rangeUnderflow && !item.validity.stepMismatch && !item.validity.tooLong && !item.validity.tooShort && !item.validity.typeMismatch && !item.validity.valueMissing) {\n\n                    // It's valid, so process accordingly\n                    item.setCustomValidity('');\n                    self.process(item, 'valid');\n\n                    self.checkSiblings(item);\n                    return;\n                }\n            }\n\n            // If we're here, it's invalid\n            self.process(item, 'invalid');\n            self.checkSiblings(item);\n        }\n\n        /**\n         * Check an item's siblings validty state\n         * @param {HTMLElement} item \n         */\n\n    }, {\n        key: 'checkSiblings',\n        value: function checkSiblings(item) {\n            var self = this;\n\n            // Find siblings that aren't this item and that are required\n            var inputElems = self.inputElems.filter(function (elem) {\n                return elem != item && elem.hasAttribute('required');\n            });\n\n            if (inputElems.length) {\n\n                // Run each item through the processor\n                inputElems.map(function (item) {\n                    self.processValidity(item);\n                });\n            }\n        }\n    }]);\n\n    return Validation;\n}();\n\nexports.default = Validation;\n;\nmodule.exports = exports['default'];\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ })\n/******/ ]);\n});\n//# sourceMappingURL=boilerform.js.map"
  },
  {
    "path": "dist/markup/button/default/markup.html",
    "content": "<button class=\"c-button\">A button</button>"
  },
  {
    "path": "dist/markup/check-field/checkbox/markup.html",
    "content": "<div class=\"c-check-field\">\n    <input type=\"checkbox\" name=\"checkbox-field\" id=\"checkbox-field\" class=\"c-check-field__input\" />\n    <label for=\"checkbox-field\" class=\"c-check-field__decor\" aria-hidden=\"true\" role=\"presentation\"></label>\n    <label for=\"checkbox-field\" class=\"c-check-field__label\">A checkbox field</label>\n</div>"
  },
  {
    "path": "dist/markup/check-field/error-state/markup.html",
    "content": "<div class=\"[ c-check-field ] [ is-error ]\">\n    <input type=\"checkbox\" name=\"checkbox-error-field\" id=\"checkbox-error-field\" class=\"c-check-field__input\" />\n    <label for=\"checkbox-error-field\" class=\"c-check-field__decor\" aria-hidden=\"true\" role=\"presentation\"></label>\n    <label for=\"checkbox-error-field\" class=\"c-check-field__label\">A checkbox field</label>\n</div>\n<div class=\"[ c-check-field c-check-field--radio ] [ is-error ]\">\n    <input type=\"radio\" name=\"radio-error-field\" id=\"radio-error-field\" class=\"c-check-field__input\" />\n    <label for=\"radio-error-field\" class=\"c-check-field__decor\" aria-hidden=\"true\" role=\"presentation\"></label>\n    <label for=\"radio-error-field\" class=\"c-check-field__label\">A radio button</label>\n</div>\n"
  },
  {
    "path": "dist/markup/check-field/radio/markup.html",
    "content": "<div class=\"c-check-field c-check-field--radio\">\n    <input type=\"radio\" name=\"checkbox-field\" id=\"checkbox-radio-field-1\" class=\"c-check-field__input\" />\n    <label for=\"checkbox-radio-field-1\" class=\"c-check-field__decor\" aria-hidden=\"true\" role=\"presentation\"></label>\n    <label for=\"checkbox-radio-field-1\" class=\"c-check-field__label\">A radio button</label>\n</div>\n<div class=\"c-check-field c-check-field--radio\">\n    <input type=\"radio\" name=\"checkbox-field\" id=\"checkbox-radio-field-2\" class=\"c-check-field__input\" />\n    <label for=\"checkbox-radio-field-2\" class=\"c-check-field__decor\" aria-hidden=\"true\" role=\"presentation\"></label>\n    <label for=\"checkbox-radio-field-2\" class=\"c-check-field__label\">Another radio button</label>\n</div>"
  },
  {
    "path": "dist/markup/input-field/email/markup.html",
    "content": "<input type=\"email\" name=\"\" id=\"\" autocapitalize=\"none\" autocorrect=\"off\" class=\"c-input-field\" value=\"user@email.com\" />"
  },
  {
    "path": "dist/markup/input-field/error-state/markup.html",
    "content": "<input type=\"text\" name=\"\" id=\"\" class=\"[ c-input-field ] [ is-error ]\" value=\"Generic text\" />"
  },
  {
    "path": "dist/markup/input-field/number/markup.html",
    "content": "<input type=\"number\" name=\"\" id=\"\" min=\"1\" max=\"999\" step=\"1\" class=\"c-input-field\" value=\"123\" />"
  },
  {
    "path": "dist/markup/input-field/search/markup.html",
    "content": "<input type=\"search\" name=\"\" id=\"\" autocorrect=\"off\" class=\"c-input-field\" value=\"Some search terms\" />"
  },
  {
    "path": "dist/markup/input-field/tel/markup.html",
    "content": "<input type=\"tel\" name=\"\" id=\"\" class=\"c-input-field\" value=\"01234 567 890\" />"
  },
  {
    "path": "dist/markup/input-field/text/markup.html",
    "content": "<input type=\"text\" name=\"\" id=\"\" class=\"c-input-field\" value=\"Generic text\" />"
  },
  {
    "path": "dist/markup/input-field/text-area/markup.html",
    "content": "<textarea name=\"\" id=\"\" class=\"c-input-field c-input-field--multiline\">Some multiline text</textarea>"
  },
  {
    "path": "dist/markup/label/default/markup.html",
    "content": "<label for=\"\" class=\"c-label\">A label for a field</label>\n<input class=\"c-input-field\" value=\"fdsfds\" />"
  },
  {
    "path": "dist/markup/select-field/error-state/markup.html",
    "content": "<div class=\"[ c-select-field ] [ is-error ]\">\n    <select name=\"\" id=\"\" class=\"c-select-field__menu\">\n        <option>Select an item</option>\n        <option value=\"1\">Item 1</option>\n        <option value=\"2\">Item 2</option>\n        <option value=\"3\">Item 3</option>\n        <option value=\"4\">Item 5</option>\n    </select>\n    <span class=\"c-select-field__decor\" aria-hidden=\"true\" role=\"presentation\">&dtrif;</span>\n</div>"
  },
  {
    "path": "dist/markup/select-field/select-menu/markup.html",
    "content": "<div class=\"c-select-field\">\n    <select name=\"\" id=\"\" class=\"c-select-field__menu\">\n        <option>Select an item</option>\n        <option value=\"1\">Item 1</option>\n        <option value=\"2\">Item 2</option>\n        <option value=\"3\">Item 3</option>\n        <option value=\"4\">Item 5</option>\n    </select>\n    <span class=\"c-select-field__decor\" aria-hidden=\"true\" role=\"presentation\">&dtrif;</span>\n</div>"
  },
  {
    "path": "generator/dist.js",
    "content": "var findRemoveSync = require('find-remove');\nvar fs = require('fs');\nvar ncp  = require('ncp');\nvar path = require('path');\nvar rimraf = require('rimraf');\n\n// Delete the markup dist dir\nrimraf(path.join(__dirname, '../dist/markup'), function() {\n\n    // Copy the components from the pattern lib\n    ncp(path.join(__dirname, '../pattern-library/components'), path.join(__dirname, '../dist/markup'), function(error) {\n        \n        if(error) return console.log(error);\n\n        // Remove all markdown files\n        findRemoveSync(path.join(__dirname, '../dist/markup'), { extensions: '.md' });\n    });\n});"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"boilerform\",\n  \"version\": \"1.1.1\",\n  \"description\": \"A little collection of common form elements that have base markup and CSS set up for you.\",\n  \"scripts\": {\n    \"sass:dist-min\": \"uglifycss dist/css/boilerform.css > dist/css/boilerform.min.css\",\n    \"watch\": \"webpack --watch\",\n    \"build\": \"NODE_ENV=production webpack && npm run sass:dist-min && node generator/dist.js && echo Done 👍🏼\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/hankchizljaw/boilerform.git\"\n  },\n  \"author\": \"hankchizljaw\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/hankchizljaw/boilerform/issues\"\n  },\n  \"homepage\": \"https://github.com/hankchizljaw/boilerform#readme\",\n  \"devDependencies\": {\n    \"babel-core\": \"^6.26.0\",\n    \"babel-loader\": \"^7.1.2\",\n    \"babel-plugin-add-module-exports\": \"^0.2.1\",\n    \"babel-preset-env\": \"^1.6.1\",\n    \"css-loader\": \"^0.28.7\",\n    \"dotenv\": \"^5.0.1\",\n    \"extract-text-webpack-plugin\": \"^3.0.2\",\n    \"find-remove\": \"^1.2.0\",\n    \"ncp\": \"^2.0.0\",\n    \"node-sass\": \"^4.7.2\",\n    \"rimraf\": \"^2.6.2\",\n    \"sass-loader\": \"^6.0.6\",\n    \"uglifycss\": \"0.0.27\",\n    \"webpack\": \"^3.10.0\"\n  }\n}\n"
  },
  {
    "path": "pattern-library/LICENSE.txt",
    "content": "Copyright (c) Astrum by No Divide Studio Ltd (http://nodividestudio.com)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "pattern-library/app/css/styles.css",
    "content": "/**\n * Base styles\n * ----------------------------------------//\n */\n.ndpl-body {\n    background-color: #FFF;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    margin: 0;\n    padding: 0;\n}\n[class^=\"ndpl-\"], [class*=\" ndpl-\"] {\n    box-sizing: border-box;\n}\n.ndpl-disable-scrolling {\n    overflow: hidden;\n}\n.ndpl-body.nav-open {\n    overflow-y: hidden;\n}\n\n.ndpl-loading__title,\n.ndpl-error,\n.ndpl-info,\n.ndpl-header,\n.ndpl-sidebar,\n.ndpl-intro,\n.ndpl-library__title,\n.ndpl-group__description,\n.ndpl-component__title,\n.ndpl-component__description,\n.ndpl-component__label,\n.ndpl-component__code-toggle,\n.ndpl-component__color,\n.ndpl-page,\n.ndpl-nav__title,\n.ndpl-sidebar__title {\n    font-family: 'Open Sans', 'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif;\n}\n\n/* Heading type sizes */\n.ndpl-library__title {\n    font-size: 27px;\n    font-weight: 400;\n    line-height: 36px;\n}\n.ndpl-component__title {\n    font-size: 18px;\n    font-weight: 300;\n    line-height: 32px;\n}\n\n/* Body type size */\n.ndpl-page,\n.ndpl-intro,\n.ndpl-group__description,\n.ndpl-component__description {\n    font-size: 12px;\n    font-weight: 300;\n    line-height: 24px;\n}\n\n/* Page sizes */\n.ndpl-page h1 { margin-bottom: 24px; }\n.ndpl-page h2,\n.ndpl-page h3,\n.ndpl-page h4,\n.ndpl-page h5,\n.ndpl-page h6 { margin: 24px 0 12px; }\n.ndpl-page h2:first-child,\n.ndpl-page h3:first-child,\n.ndpl-page h4:first-child,\n.ndpl-page h5:first-child,\n.ndpl-page h6:first-child { margin-top: 0; }\n.ndpl-page h1 { font-size: 26px; font-weight: 400; line-height: 36px; }\n.ndpl-page h2 { font-size: 21px; font-weight: 300; line-height: 36px; }\n.ndpl-page h3 { font-size: 18px; font-weight: 300; line-height: 32px; }\n.ndpl-page h4 { font-size: 16px; font-weight: 300; line-height: 27px; }\n.ndpl-page h5 { font-size: 14px; font-weight: 300; line-height: 24px; }\n.ndpl-page h6 { font-size: 14px; font-weight: 400; line-height: 24px; }\n.ndpl-page code,\n.ndpl-component__description code,\n.ndpl-group__description code {\n    display: inline-block;\n    color: #BABEC7;\n    border: 1px solid #E1E1E1;\n    border-radius: 3px;\n    line-height: 18px;\n    padding: 0 3px;\n}\n.ndpl-page a,\n.ndpl-page a[href] {\n    text-decoration: none;\n}\n.ndpl-page a:hover,\n.ndpl-page a[href]:hover {\n    text-decoration: underline;\n}\n.ndpl-page p {\n    margin-bottom: 24px;\n}\n\n@media only screen and (min-width: 60em) {\n\n    .ndpl-page h1 { margin-bottom: 48px; }\n    .ndpl-page h2,\n    .ndpl-page h3,\n    .ndpl-page h4,\n    .ndpl-page h5,\n    .ndpl-page h6 { margin: 48px 0 24px; }\n\n    /* Heading type sizes */\n    .ndpl-library__title {\n        font-size: 36px;\n        line-height: 36px;\n    }\n    .ndpl-component__title {\n        font-size: 21px;\n        line-height: 32px;\n    }\n\n    /* Body type size */\n    .ndpl-page,\n    .ndpl-intro,\n    .ndpl-group__description,\n    .ndpl-component__description {\n        font-size: 14px;\n        line-height: 21px;\n    }\n\n    /* Page sizes */\n    .ndpl-page h1 { font-size: 36px; line-height: 36px; }\n    .ndpl-page h2 { font-size: 28px; line-height: 36px; }\n    .ndpl-page h3 { font-size: 21px; line-height: 32px; }\n    .ndpl-page h4 { font-size: 18px; line-height: 27px; }\n    .ndpl-page h5 { font-size: 16px; line-height: 24px; }\n    .ndpl-page h6 { font-size: 16px; line-height: 24px; }\n}\n\n/**\n * #303637 - Heading color\n * #616367 - Body color\n * #B0B1B3 - Dimmed color\n *\n * Theme colors\n * ----------------------------------------//\n */\n.ndpl-c-background               { background-color: #FFF; }    /* Background color */\n.ndpl-c-border                   { border-color: #E0E6ED; }     /* Border color */\n.ndpl-c-highlight                { background-color: #F9FAFC; } /* Highlight background */\n.ndpl-c-brand-c                  { color: #FEA1AC; }            /* Brand color */\n.ndpl-c-brand-bg                 { background-color: #FEA1AC; } /* Brand background color */\n.ndpl-c-brand-b                  { border-color: #FEA1AC; }     /* Brand border color */\n.ndpl-c-brand-a:hover            { color: #FEA1AC; }            /* Brand anchor on hover */\n.ndpl-c-brand-ca a,\n.ndpl-c-brand-ca a[href],\n.ndpl-c-brand-ca a[href]:focus,\n.ndpl-c-brand-ca a:focus,\n.ndpl-c-brand-ca a[href]:active,\n.ndpl-c-brand-ca a:active,\n.ndpl-c-brand-ca a[href]:visited,\n.ndpl-c-brand-ca a:visited        { color: #303637; }            /* Brand child anchors */\n.ndpl-c-brand-ca a[href]:hover,\n.ndpl-c-brand-ca a:hover          { color: #FEA1AC; }            /* Brand child anchors on hover */\n.ndpl-c-brand-cai a,\n.ndpl-c-brand-cai a[href],\n.ndpl-c-brand-cai a[href]:focus,\n.ndpl-c-brand-cai a:focus,\n.ndpl-c-brand-cai a[href]:active,\n.ndpl-c-brand-cai a:active,\n.ndpl-c-brand-cai a[href]:visited,\n.ndpl-c-brand-cai a:visited        { color: #FEA1AC; }            /* Brand child anchors */\n.ndpl-c-brand-cai a[href]:hover,\n.ndpl-c-brand-cai a:hover          { color: #303637 !important; }            /* Brand child anchors on hover */\n\n/**\n * Helpers\n * ----------------------------------------//\n */\n/* No state change for anchors */\n.ndpl-nsc,\n.ndpl-nsc:focus,\n.ndpl-nsc[href]:focus,\n.ndpl-nsc:hover,\n.ndpl-nsc[href]:hover,\n.ndpl-nsc:active,\n.ndpl-nsc[href]:active,\n.ndpl-nsc:visited,\n.ndpl-nsc[href]:visited {\n    color: #303637 !important;\n    text-decoration: none;\n}\n\n.ndpl-cf:after {\n    content: \"\";\n    display: block;\n    clear: both;\n}\n\n.ndpl-dark-text {\n    color: #616367 !important;\n}\n.ndpl-light-text {\n    color: #FFF !important;\n}\n.ndpl-apply-border {\n    border: 1px solid #E0E6ED;\n}\n.ndpl-apply-border + .ndpl-apply-border {\n    border-top: none;\n}\n\n/**\n * Loading\n * ----------------------------------------//\n */\n.ndpl-loading__title {\n    color: #303637;\n    font-weight: 300;\n    margin: 0 24px 24px;\n    opacity: 0;\n    transition: opacity .5s ease;\n}\n.wf-opensans-n4-active .ndpl-loading__title {\n    opacity: 1;\n}\n\n.ndpl-container {\n    opacity: 0;\n    transition: opacity .5s ease .5s;\n}\n.ndpl-container.loaded {\n    opacity: 1;\n}\n.ndpl-container.resizing {\n    visibility: hidden;\n}\n\n.ndpl-loading {\n    left: -9999px;\n    opacity: 0;\n    padding: 96px 0;\n    position: fixed;\n    text-align: center;\n    transition: opacity .5s ease;\n    width: 100%;\n}\n.ndpl-loading.in-progress {\n    left: 0;\n    opacity: 1;\n}\n.ndpl-loading__title {\n    font-size: 27px;\n    padding-top: 24px;\n}\n\n@media only screen and (min-width: 60em) {\n\n    .ndpl-loading__title {\n        font-size: 36px;\n        padding-top: 24px;\n    }\n}\n\n/**\n * Errors\n * ----------------------------------------//\n */\n.ndpl-error,\n.ndpl-info {\n    border-radius: 6px;\n    color: #FFF;\n    display: inline-block;\n    list-style: none;\n    margin: 0 12px;\n    padding: 24px;\n    font-size: 14px;\n}\n.ndpl-error {\n    background-color: #f97d7d;\n}\n.ndpl-info {\n    background-color: #7da9f9;\n}\n.ndpl-error code,\n.ndpl-info code {\n    padding: 0 3px;\n}\n.ndpl-error code { background-color: #e07070; }\n.ndpl-info code  { background-color: #7098e0; }\n\n.ndpl-error .ndpl-pre,\n.ndpl-info .ndpl-pre {\n    margin-bottom: 0;\n}\n\n@media only screen and (min-width: 60em) {\n\n    .ndpl-error,\n    .ndpl-info {\n        margin: 0;\n    }\n}\n\n/**\n * Folding cube animation\n * Created by Tobias Ahlin\n * http://tobiasahlin.com/spinkit/\n * ----------------------------------------//\n */\n.ndpl-folding-cube {\n    margin: 20px auto;\n    width: 40px;\n    height: 40px;\n    position: relative;\n    -webkit-transform: rotateZ(45deg);\n    transform: rotateZ(45deg);\n}\n\n.ndpl-folding-cube .ndpl-cube {\n    float: left;\n    width: 50%;\n    height: 50%;\n    position: relative;\n    -webkit-transform: scale(1.1);\n    -ms-transform: scale(1.1);\n    transform: scale(1.1);\n}\n.ndpl-folding-cube .ndpl-cube:before {\n    content: '';\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    background-color: #303637;\n    -webkit-animation: ndpl-foldCubeAngle 2.4s infinite linear both;\n    animation: ndpl-foldCubeAngle 2.4s infinite linear both;\n    -webkit-transform-origin: 100% 100%;\n    -ms-transform-origin: 100% 100%;\n    transform-origin: 100% 100%;\n}\n.ndpl-folding-cube .ndpl-cube2 {\n    -webkit-transform: scale(1.1) rotateZ(90deg);\n    transform: scale(1.1) rotateZ(90deg);\n}\n.ndpl-folding-cube .ndpl-cube3 {\n    -webkit-transform: scale(1.1) rotateZ(180deg);\n    transform: scale(1.1) rotateZ(180deg);\n}\n.ndpl-folding-cube .ndpl-cube4 {\n    -webkit-transform: scale(1.1) rotateZ(270deg);\n    transform: scale(1.1) rotateZ(270deg);\n}\n.ndpl-folding-cube .ndpl-cube2:before {\n    -webkit-animation-delay: 0.3s;\n    animation-delay: 0.3s;\n}\n.ndpl-folding-cube .ndpl-cube3:before {\n    -webkit-animation-delay: 0.6s;\n    animation-delay: 0.6s;\n}\n.ndpl-folding-cube .ndpl-cube4:before {\n    -webkit-animation-delay: 0.9s;\n    animation-delay: 0.9s;\n}\n@-webkit-keyframes ndpl-foldCubeAngle {\n    0%, 10% {\n        -webkit-transform: perspective(140px) rotateX(-180deg);\n        transform: perspective(140px) rotateX(-180deg);\n        opacity: 0;\n    } 25%, 75% {\n          -webkit-transform: perspective(140px) rotateX(0deg);\n          transform: perspective(140px) rotateX(0deg);\n          opacity: 1;\n      } 90%, 100% {\n            -webkit-transform: perspective(140px) rotateY(180deg);\n            transform: perspective(140px) rotateY(180deg);\n            opacity: 0;\n        }\n}\n\n@keyframes ndpl-foldCubeAngle {\n    0%, 10% {\n        -webkit-transform: perspective(140px) rotateX(-180deg);\n        transform: perspective(140px) rotateX(-180deg);\n        opacity: 0;\n    } 25%, 75% {\n          -webkit-transform: perspective(140px) rotateX(0deg);\n          transform: perspective(140px) rotateX(0deg);\n          opacity: 1;\n      } 90%, 100% {\n            -webkit-transform: perspective(140px) rotateY(180deg);\n            transform: perspective(140px) rotateY(180deg);\n            opacity: 0;\n        }\n}\n\n/**\n * Header\n * ----------------------------------------//\n */\n.ndpl-header {\n    background-color: #FFF;\n    border-bottom: 1px solid #DDD;\n    box-shadow: 0 0 1px rgba(0,0,0,0.1);\n    margin:0 0 36px;\n    padding: 12px;\n    position: fixed;\n    top: 0;\n    width: 100%;\n    z-index: 9998;\n}\n.ndpl-header:after {\n    display: none;\n}\n.ndpl-header__logo {\n    float: left;\n    height: 28px;\n    margin: 0 6px 0 0;\n}\n.ndpl-header__title {\n    color: #303637;\n    font-size: 18px;\n    font-weight: 700;\n    line-height: 28px;\n    float: left;\n    margin: 0;\n}\n.ndpl-header__title a {\n    display: none;\n}\n.ndpl-header__title a,\n.ndpl-header__title a:hover {\n    text-decoration: none !important;\n}\n.ndpl-header__title small {\n    font-size: 60%;\n    font-weight: 300;\n    margin-left: 6px;\n}\n\n@media only screen and (min-width: 60em) {\n\n    .ndpl-header {\n        display: none;\n    }\n\n    .ndpl-header__title a {\n        display: block;\n    }\n}\n\n/**\n * Sidebar\n * ----------------------------------------//\n */\n.ndpl-sidebar {\n    background-color: #FFF;\n    bottom: 0;\n    box-shadow: 1px 0 2px rgba(0,0,0,0.2);\n    height: 100%;\n    left: -100%;\n    overflow-y: auto;\n    overflow-x: hidden;\n    padding: 103px 0 24px;\n    position: fixed;\n    right: 0;\n    top: 0;\n    width: 100%;\n    z-index: 9997;\n}\n.ndpl-mobile .ndpl-sidebar {\n    transition: left .5s ease;\n}\n.ndpl-sidebar.open {\n    left: 0;\n}\n.ndpl-sidebar__header {\n    display: none;\n}\n.ndpl-sidebar__logo {\n    float: left;\n    margin: 0 0 24px 0;\n    height: 50px;\n}\n\n@media only screen and (min-width: 60em) {\n\n    .ndpl-sidebar {\n        background-color: #FFF;\n        bottom: 0;\n        display: block;\n        left: -264px;\n        padding: 0;\n        position: fixed;\n        top: 0;\n        width: 264px;\n    }\n    .loaded .ndpl-sidebar {\n        left: 0;\n    }\n\n    /**\n     * Sidebar - Header\n     * ----------------------------------------//\n     */\n    .ndpl-sidebar__header {\n        display: block;\n        padding: 24px 24px 36px;\n    }\n    .ndpl-sidebar__title {\n        color: #303637;\n        clear: left;\n        display: block;\n        font-size: 18px;\n        line-height: 24px;\n        font-weight: 700;\n        margin: 0;\n    }\n    .ndpl-sidebar__title a {\n        text-decoration: none;\n    }\n    .ndpl-sidebar__title a:hover {\n        color: #FEA1AC;\n    }\n    .ndpl-sidebar__title small {\n        display: block;\n        font-size: 16px;\n        font-weight: 400;\n    }\n}\n\n/**\n * Copyright info\n * ----------------------------------------//\n */\n.ndpl-copyright {\n    display: block;\n    padding: 0 24px 24px;\n}\n.ndpl-copyright p {\n    color: #B0B1B3;\n    font-size: 12px;\n    font-weight: 300;\n    line-height: 21px;\n}\n.ndpl-copyright p:last-of-type {\n    margin: 0;\n}\n.ndpl-copyright a {\n    text-decoration: none;\n}\n\n/**\n * Navigation - Title\n * ----------------------------------------//\n */\n.ndpl-nav__title {\n    color: #303637;\n    font-size: 12px;\n    font-weight: 700;\n    letter-spacing: 1px;\n    margin: 0 0 21px;\n    padding: 0 24px;\n    text-transform: uppercase;\n}\n\n/**\n * Navigation - Structure\n * ----------------------------------------//\n */\n.ndpl-nav__items {\n    border-top: 1px solid transparent;\n    font-size: 14px;\n    font-weight: 400;\n    line-height: 24px;\n    list-style: none;\n    margin: 0 0 72px;\n    padding: 0;\n}\n.ndpl-nav__item {\n    position: relative;\n}\n.ndpl-nav__item.active .ndpl-nav__group {\n    font-weight: 700;\n}\n\n.ndpl-nav__child-items {\n    display: none;\n    font-size: 14px;\n    list-style: none;\n    min-height: 0;\n    padding: 0;\n    margin: 0;\n}\n.active .ndpl-nav__child-items {\n    display: block;\n}\n.ndpl-nav__child-item {\n    border-bottom: 1px solid transparent;\n    border-radius: 4px;\n}\n\n/**\n * Navigation - Page\n * ----------------------------------------//\n */\n.ndpl-nav__page {\n    border-bottom: 1px solid #E0E6ED;\n    border-left: 6px solid transparent;\n    cursor: pointer;\n    display: block;\n    font-weight: 400;\n    padding: 6px 24px 6px 18px;\n    position: relative;\n    text-decoration: none;\n}\n.ndpl-nav__page.active,\n.ndpl-nav__page:hover {\n    border-left-color: #FEA1AC;\n}\n\n\n/**\n * Navigation - Group\n * ----------------------------------------//\n */\n.ndpl-nav__group {\n    border-bottom: 1px solid #E0E6ED;\n    display: block;\n    font-weight: 400;\n    padding: 6px 24px;\n    position: relative;\n    text-decoration: none;\n}\n.ndpl-nav__group:after {\n    background: transparent url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5IiBoZWlnaHQ9IjE1IiB2aWV3Qm94PSIwIDAgOSAxNSI+CiAgPGRlZnM+CiAgICA8c3R5bGU+CiAgICAgIC5jbH MtMSB7CiAgICAgICAgZmlsbDogIzIzMWYyMDsKICAgICAgICBmaWxsLXJ1bGU6IGV2ZW5vZGQ7CiAgICAgIH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIDxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTQ2MC40NDgsNDkxLjAwOUw0NjgsNDk4LjVsLTcuNTQ4LDcuNDkyTDQ1OSw1MDQuNTU3bDYuMS02LjA1NS02LjEtNi4wNTdaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDU5IC00OTEpIi8+Cjwvc3ZnPgo=\") center no-repeat;\n    background-size: 100% auto;\n    content: \"\";\n    display: block;\n    height: 8px;\n    margin-top: -4px;\n    position: absolute;\n    right: 24px;\n    top: 50%;\n    transform: rotate(90deg);\n    transition: transform .25s ease;\n    width: 5px;\n}\n.active .ndpl-nav__group:after {\n    transform: rotate(-90deg);\n}\n\n/**\n * Navigation - Component\n * ----------------------------------------//\n */\n.ndpl-nav__component {\n    border-left: 6px solid transparent;\n    color: #616367 !important;\n    display: block;\n    font-size: 14px;\n    font-weight: 300;\n    padding: 6px 24px 6px 30px;\n    text-decoration: none;\n}\n.ndpl-nav__component.active,\n.ndpl-nav__component:hover {\n    border-left-color: #FEA1AC;\n}\n.ndpl-nav__arrow {\n    margin: -4px 0 0;\n    opacity: 0.25;\n    position: absolute;\n    right: 12px;\n    top: 18px;\n    width: 16px;\n}\n.active .ndpl-nav__arrow {\n    transform: rotate(180deg);\n}\n\n/*\n * Navigation\n * ----------------------------------------//\n */\n.ndpl-nav-handle {\n    display: block;\n    cursor: pointer;\n    height: 27px;\n    overflow: hidden;\n    position: fixed;\n    right: 0;\n    transform: rotate(0deg);\n    transition: .5s ease-in-out;\n    top: 15px;\n    width: 48px;\n    z-index: 9999;\n}\n.ndpl-nav-handle.open {\n    position: fixed;\n}\n.ndpl-nav-handle__container {\n    padding: 12px 0 0;\n}\n.ndpl-nav-handle span {\n    background-color: #303637;\n    display: block;\n    height: 3px;\n    opacity: 1;\n    position: absolute;\n    right: 12px;\n    transform: rotate(0deg);\n    transition: .25s ease-in-out;\n    width: 27px;\n}\n.ndpl-nav-handle span:nth-child(1) {\n    top: 0px;\n}\n.ndpl-nav-handle span:nth-child(2) {\n    top: 9px;\n}\n.ndpl-nav-handle span:nth-child(3) {\n    top: 18px;\n}\n.ndpl-nav-handle.open span:nth-child(1) {\n    top: 11px;\n    transform: rotate(-45deg);\n}\n.ndpl-nav-handle.open span:nth-child(2) {\n    opacity: 0;\n    right: -60px;\n}\n.ndpl-nav-handle.open span:nth-child(3) {\n    top: 11px;\n    transform: rotate(45deg);\n}\n\n@media only screen and (min-width: 60em) {\n\n    .ndpl-nav-handle {\n        display: none;\n    }\n}\n\n/**\n * Content containers\n * ----------------------------------------//\n */\n.ndpl-page,\n.ndpl-library {\n    padding-top: 79px;\n}\n.ndpl-page {\n    color: #616367;\n    padding-left: 12px;\n    padding-right: 12px;\n}\n.ndpl-page h1,\n.ndpl-page h2,\n.ndpl-page h3,\n.ndpl-page h4,\n.ndpl-page h5,\n.ndpl-page h6 {\n    color: #303637;\n}\n.ndpl-preloaded {\n    left: -9999px;\n    position: absolute;\n    top: -9999px;\n}\n\n@media only screen and (min-width: 35em) {\n    .ndpl-page {\n        max-width: 580px;\n        margin: 0 auto;\n    }\n}\n\n@media only screen and (min-width: 60em) {\n    .ndpl-page,\n    .ndpl-library {\n        margin: 0 auto;\n        padding: 56px 0;\n    }\n    .ndpl-page h1:first-child,\n    .ndpl-page h2:first-child,\n    .ndpl-page h3:first-child,\n    .ndpl-page h4:first-child,\n    .ndpl-page h5:first-child,\n    .ndpl-page h6:first-child,\n    .ndpl-library h1:first-child,\n    .ndpl-library h2:first-child,\n    .ndpl-library h3:first-child,\n    .ndpl-library h4:first-child,\n    .ndpl-library h5:first-child,\n    .ndpl-library h6:first-child {\n        margin-top: 0;\n    }\n    .ndpl-content {\n        padding: 36px 48px 36px 312px;\n    }\n}\n\n/**\n * Component Group\n * ----------------------------------------//\n */\n.ndpl-library__group {\n    overflow: auto;\n    zoom: 1;\n}\n.ndpl-library__title {\n    color: #303637;\n    padding-left: 12px;\n    padding-right: 12px;\n    margin-bottom: 24px;\n}\n\n@media only screen and (min-width: 60em) {\n\n    .ndpl-library__title {\n        padding-left: 0;\n        padding-right: 0;\n        margin-bottom: 24px;\n    }\n}\n\n/**\n * Group\n * ----------------------------------------//\n */\n.ndpl-group__description {\n    color: #616367;\n    margin-bottom: 48px;\n    padding: 0 12px;\n}\n\n@media only screen and (min-width: 60em) {\n\n    .ndpl-group__description {\n        padding: 0;\n    }\n}\n\n/**\n * Component\n * ----------------------------------------//\n */\n.ndpl-component {\n    clear: both;\n    margin-bottom: 60px;\n}\n.ndpl-component__title,\n.ndpl-component__description {\n    color: #616367;\n    padding: 0 12px;\n}\n.ndpl-component__title {\n    margin-bottom: 12px;\n}\n.ndpl-component__description {\n    padding-bottom: 24px;\n}\n\n@media only screen and (min-width: 60em) {\n\n    .ndpl-component__title,\n    .ndpl-component__description {\n        padding: 0;\n    }\n}\n\n/**\n * Component - Half Width\n * ----------------------------------------//\n */\n@media only screen and (min-width: 60em) {\n\n    .ndpl-components {\n        display: -ms-flexbox;\n        display: -webkit-flex;\n        display: flex;\n\n        -ms-flex-direction: row;\n        -webkit-flex-direction: row;\n        flex-direction: row;\n\n        -ms-flex-wrap: wrap;\n        -webkit-flex-wrap: wrap;\n        flex-wrap: wrap;\n\n        margin-left: -36px;\n    }\n\n    .ndpl-component {\n        padding-left: 36px;\n    }\n\n    .ndpl-component--half {\n        -ms-flex-grow: 2;\n        -webkit-flex-grow: 2;\n        flex-grow: 2;\n\n        max-width: 50%;\n        width: 50%;\n    }\n\n    .ndpl-component--full {\n        -ms-flex-grow: 1;\n        -webkit-flex-grow: 1;\n        flex-grow: 1;\n        width: 100%;\n    }\n}\n\n/**\n * Component - Colours\n * ----------------------------------------//\n */\n.ndpl-component__colors {\n    padding: 0 12px;\n}\n.ndpl-component__color-container {\n    float: left;\n    margin-top: 24px;\n    width: 100%;\n}\n.ndpl-component__color-container:first-of-type {\n    margin-top: 0;\n}\n.ndpl-component__color-container:nth-child(even) {\n    margin-right: 0;\n}\n.ndpl-component__color {\n    float: left;\n    line-height: 1;\n    padding: 24px 0;\n    text-align: center;\n    width: 50%;\n}\n.ndpl-component__color:first-of-type {\n    border-radius: 6px 0 0 6px;\n}\n.ndpl-component__color:last-of-type {\n    border-radius: 0 6px 6px 0;\n}\n.ndpl-component__color:first-of-type:last-of-type {\n    border-radius: 6px;\n    width: 100%;\n}\n.ndpl-component__color div {\n    border: 1px solid #FFF;\n    border-radius: 3px;\n    color: #FFF;\n    display: inline-block;\n    font-size: 13px;\n    letter-spacing: 1px;\n    line-height: 13px;\n    padding: 6px 9px;\n    text-transform: uppercase;\n}\n.ndpl-component__color div.ndpl-dark-text {\n    color: #B0B1B3 !important;\n    border-color: #B0B1B3;\n}\n\n@media only screen and (min-width: 60em) {\n\n    .ndpl-component__colors {\n        padding: 0;\n    }\n    .ndpl-component__color-container {\n        margin-right: 3%;\n        width: 17.5%;\n    }\n    .ndpl-component__color-container:nth-child(even) {\n        margin-right: 3%;\n    }\n    .ndpl-component__color-container:nth-child(5n) {\n        margin-right: 0;\n    }\n    .ndpl-component__color-container:nth-child(-n + 5) {\n        margin-top: 0;\n    }\n    .ndpl-component__color {\n        padding: 48px 0;\n        width: 100%;\n    }\n    .ndpl-component__color:first-of-type {\n        border-radius: 6px 6px 0 0;\n    }\n    .ndpl-component__color:last-of-type {\n        border-radius: 0 0 6px 6px;\n    }\n}\n\n/**\n * Component - Preview & code sample\n * ----------------------------------------//\n */\n.ndpl-component__sample {\n    background-color: #FFF;\n    border-top: 1px solid #E0E6ED;\n    border-bottom: 1px solid #E0E6ED;\n    padding: 36px 12px;\n    position: relative;\n}\n.ndpl-component__sample:after {\n    display: block;\n    clear: both;\n    content: \"\";\n}\n.ndpl-component__sample--inverted {\n    background-color: #333;\n}\n.ndpl-component__sample-missing,\n.ndpl-component__sample-hidden {\n    display: block;\n    margin: 0 12px;\n    text-align: center;\n}\n.ndpl-component__code {\n    border-bottom: 1px solid #E0E6ED;\n}\n.ndpl-component__code .ndpl-pre {\n    margin: 0;\n}\n\n/* We apply the same code styling to page, description and component elements. */\n.ndpl-page pre code,\n.ndpl-component__description pre code,\n.ndpl-component__code .ndpl-code {\n    box-sizing: border-box;\n    color: #616367;\n    font-size: 12px;\n    line-height: 18px;\n    opacity: 0.75;\n    overflow-x: auto;\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    padding: 36px 12px;\n    white-space: pre;\n    width: 100%;\n}\n.ndpl-page pre code,\n.ndpl-component__description pre code {\n    padding: 12px;\n}\n\n.ndpl-component__code-toggle {\n    border-bottom: 1px solid transparent;\n    color: #B0B1B3;\n    cursor: pointer;\n    display: block;\n    font-size: 12px;\n    letter-spacing: 1px;\n    padding: 9px 12px 9px 12px;\n    text-align: center;\n    text-transform: uppercase;\n}\n\n@media only screen and (min-width: 60em) {\n\n    .ndpl-component__sample {\n        border: 1px solid #E0E6ED;\n        border-radius: 6px 6px 0 0;\n        padding: 36px;\n    }\n    .ndpl-component__sample--disabled-code {\n        border-radius: 6px;\n    }\n    .ndpl-component__sample-missing,\n    .ndpl-component__sample-hidden {\n        margin: 0;\n    }\n    .ndpl-component__code {\n        border: 1px solid #E0E6ED;\n        border-top: none;\n    }\n    .ndpl-page pre code,\n    .ndpl-component__description pre code,\n    .ndpl-component__code .ndpl-code {\n        font-size: 15px;\n        line-height: 21px;\n        padding: 36px;\n    }\n    .ndpl-page pre code,\n    .ndpl-component__description pre code {\n        padding: 12px;\n    }\n    .ndpl-component__code-toggle {\n        border-left: 1px solid transparent;\n        border-right: 1px solid transparent;\n        border-radius: 0 0 6px 6px;\n    }\n}\n"
  },
  {
    "path": "pattern-library/app/js/main.js",
    "content": "/**\n * Component component\n */\nvar ndplComponent = Vue.extend({\n\n    data: function() {\n        return {\n            loaded: false,\n            hide_sample_code: false\n        }\n    },\n\n    props: {\n        component: {\n            required: true\n        }\n    },\n\n    computed: {\n        inline_styles: function() {\n            var _this = this,\n                styles = '';\n\n            // These inline style are only applied after the component has fully loaded\n            if(_this.loaded) {\n                if(_this.component.options.sample_min_height) {\n                    styles += 'min-height:' + _this.component.options.sample_min_height + 'px;';\n                }\n            }\n\n            if(_this.component.options.sample_overflow_hidden) {\n                styles += 'overflow: hidden;';\n            }\n            if(_this.component.options.sample_background_color) {\n                styles += 'background-color:' + _this.component.options.sample_background_color + ' !important;';\n            }\n\n            return styles;\n        }\n    },\n\n    watch: {\n        'component.html': function() {\n            var _this = this;\n\n            // Apply syntax highlighting when component html is loaded\n            if(this.component.html.length) {\n                _this.$root.applySyntaxHighlighting(_this.$el);\n            }\n        }\n    },\n\n    ready: function() {\n        var _this = this;\n\n        // Listen for loaded event\n        _this.$on('loaded', function() {\n\n            // Monitor scroll and resize events and update navigation active state appropirately\n            window.addEventListener('scroll', _this.updateActive);\n            window.addEventListener('resize', _this.updateActive);\n\n            _this.setHideSample(function() {\n                _this.loaded = true;\n            });\n        });\n\n        // Listen for resizing event\n        _this.$on('resizing', function(is_resizing) {\n            _this.loaded = false;\n\n            if(! is_resizing) {\n                _this.setHideSample(function() {\n                    _this.loaded = true;\n                });\n            }\n        });\n\n        if (_this.component.html) {\n            _this.$root.applySyntaxHighlighting(_this.$el);\n        }\n    },\n\n    methods: {\n\n        /**\n         * Update component active in navigation.\n         */\n        updateActive: function() {\n            var _this = this;\n\n            // If scroll position is great than or equal to component offset top - 60 pixels\n            // and scroll position is less than component offset top plus component height plus 60 pixels\n            // and active component is not this component\n            if(_this.$root && _this.$root.scroll_position >= _this.$el.offsetTop - 60 &&\n                _this.$root.scroll_position < _this.$el.offsetTop + _this.$el.offsetHeight) {\n\n                // If not currently auto scrolling to component\n                // and component is not active\n                if(!_this.$root.scrolling_to &&\n                    !_this.isActive(_this.component)) {\n\n                    // Set this component to active\n                    _this.$root.active_components.push(_this.component);\n                    _this.$root.open_group = null;\n                    _this.$root.updateHash(_this.component.id);\n                }\n            } else {\n\n                // If not currently auto scrolling to component\n                if(_this.$root && !_this.$root.scrolling_to) {\n\n                    // Loop through active components and remove this component\n                    for (var i = 0; i < _this.$root.active_components.length; i++) {\n                        var component = _this.$root.active_components[i];\n\n                        if (component.id === _this.component.id) {\n                            _this.$root.active_components.splice(i, 1);\n\n                            return;\n                        }\n                    }\n                }\n            }\n        },\n\n        /**\n         * Is component active in navigation.\n         *\n         * @param component\n         * @returns {boolean}\n         */\n        isActive: function(component) {\n            var _this = this;\n\n            for (var i = 0; i < _this.$root.active_components.length; i++) {\n                var c = _this.$root.active_components[i];\n\n                if (component.id === c.id) {\n                    return true;\n                }\n            }\n\n            return false;\n        },\n\n        /**\n         * Should invert text based on hex brightness.\n         *\n         * @param hex\n         * @returns {boolean}\n         */\n        shouldInvertText: function(hex) {\n            var rgb = this.$root.convertHexToRgb(hex),\n                brightness = this.$root.getColorBrightness(rgb);\n\n            return brightness > 210;\n        },\n\n        /**\n         * Should apply border based on hex brightness.\n         *\n         * @param hex\n         * @returns {boolean}\n         */\n        shouldApplyBorder: function(hex) {\n            var rgb = this.$root.convertHexToRgb(hex),\n                brightness = this.$root.getColorBrightness(rgb);\n\n            return brightness > 240;\n        },\n\n        /**\n         * Set component sample element to be hidden if the sample\n         * itself is hidden in the assets CSS stylesheet.\n         *\n         * @param callback\n         */\n        setHideSample: function(callback) {\n            callback = typeof callback !== 'undefined' ?  callback : function() {};\n\n            var _this = this;\n\n            _this.hide_sample_code = false;\n\n            setTimeout(function() {\n                if(_this.$el.querySelector('.ndpl-component__code')) {\n\n                    /**\n                     * Auto-detect hidden sample.\n                     */\n                    if (_this.$el.querySelector('.ndpl-component__sample').offsetHeight <= 74 &&\n                        !_this.component.options.disabled_auto_sample_hiding) {\n                        _this.hide_sample_code = true;\n                    }\n\n                    /**\n                     * If manually specifying when to show nad hide samples.\n                     */\n                    if (_this.component.options.disabled_auto_sample_hiding &&\n                        _this.component.options.disabled_auto_sample_hiding.hasOwnProperty('show_on_mobile') &&\n                        _this.component.options.disabled_auto_sample_hiding.hasOwnProperty('show_on_desktop')) {\n\n\n                        if(_this.$root.mobile_view) {\n                            _this.hide_sample_code = !_this.component.options.disabled_auto_sample_hiding.show_on_mobile;\n                        } else {\n                            _this.hide_sample_code = !_this.component.options.disabled_auto_sample_hiding.show_on_desktop;\n                        }\n                    }\n                }\n\n                callback();\n            }, 0);\n        },\n\n        /**\n         * Is sample code visible.\n         *\n         * @returns {boolean}\n         */\n        isCodeVisible: function() {\n            var _this = this;\n\n            return ! _this.hide_sample_code;\n        }\n    }\n});\nVue.component('ndpl-component', ndplComponent);\n\n/**\n * Group component\n */\nvar ndplGroup = Vue.extend({\n\n    props: {\n        group: {\n            required: true\n        }\n    }\n});\nVue.component('ndpl-group', ndplGroup);\n\n/**\n * Script component\n */\nvar ndplScript = Vue.extend({\n\n    props: {\n        script: {\n            required: true\n        }\n    },\n\n    methods: {\n\n        /**\n         * Loads TypeKit.\n         */\n        loadTypekit: function() {\n            try {\n                Typekit.load({\n                    async: true\n                });\n            } catch(e) {};\n        }\n    }\n});\nVue.component('ndpl-script', ndplScript);\n\n/**\n * Vue instance\n */\nnew Vue({\n    el: 'html',\n\n    data: {\n        intro: null,\n        project_logo: null,\n        project_favicon: null,\n        project_name: null,\n        project_url: null,\n        copyright_start_year: null,\n        client_name: null,\n        client_url: null,\n        creators: {},\n        content: {},\n        groups: {},\n        theme: {},\n        assets: {\n            css: [],\n            js: []\n        },\n        font_libraries: {\n            typekit_code: null,\n            google_web_fonts: null,\n            typography_web_fonts: null\n        },\n        log: {\n            error: [],\n            info: []\n        },\n        components_count: 0,\n        groups_count: 0,\n        components_loaded_count: 0,\n        groups_loaded_count: 0,\n        groups_loaded: false,\n        loaded: false,\n        resizing: false,\n        typekit_loaded: false,\n        scroll_position: 0,\n        prev_scroll_position: 0,\n        active_group: null,\n        active_components: [],\n        active_page: null,\n        open_group: null,\n        show_first_page_on_load: false,\n        scrolling_to: false,\n        sidebar_scrolling: false,\n        window_outer_width: 0,\n        breakpoint: 960,\n        mobile_view: false,\n        open_nav: false,\n        rtime: new Date(1, 1, 2000, 12,00,00),\n        timeout: false,\n        delta: 200,\n        version: null\n    },\n\n    computed: {\n        project: function() {\n            if(this.project_name && this.project_url) {\n                return '<a href=\"' + this.project_url + '\" target=\"_blank\"><span>' + this.project_name + '</span></a>';\n            }\n\n            if(this.project_name && !this.project_url) {\n                return this.project_name;\n            }\n\n            return null;\n        },\n\n        copyright_year: function() {\n            var date = new Date();\n\n            if(date.getFullYear() == this.copyright_start_year) {\n                return this.copyright_start_year;\n            }\n\n            return this.copyright_start_year + ' - ' + date.getFullYear();\n        },\n\n        client: function() {\n            if(this.client_name && this.client_url) {\n                return '<a href=\"' + this.client_url + '\" target=\"_blank\">' + this.client_name + '</a>';\n            }\n\n            if(this.client_name && !this.client_url) {\n                return this.client_name;\n            }\n\n            return null;\n        },\n\n        all_creators: function() {\n            var formattedCreators = '';\n\n            if(this.creators.length && this.creators[0].name) {\n                for (var i = 0; i < this.creators.length; i++) {\n                    prefix = i === this.creators.length - 1 ? ' & ' : ', ';\n                    url = this.creators[i].url;\n                    name = this.creators[i].name.replace(' ', '&nbsp;');\n\n                    formattedCreators += prefix + '<a href=\"' + url + '\" target=\"_blank\">' + name + '</a>';\n                }\n\n                return formattedCreators.substring(2);\n            }\n\n            return null;\n        },\n\n        library_inline_styles: function() {\n            var _this = this,\n                styles = '';\n\n            if(_this.theme.max_width) {\n                styles += 'max-width:' + _this.theme.max_width + 'px;';\n            }\n\n            return styles;\n        }\n    },\n\n    watch: {\n        groups_loaded: function() {\n            var _this = this;\n\n            _this.setupComponents();\n        },\n        loaded: function() {\n            var _this = this;\n\n            _this.scrollTo(window.location.hash);\n\n            _this.$broadcast('loaded');\n        }\n    },\n\n    ready: function() {\n        var _this = this;\n\n        _this.loadDataFile();\n\n        _this.window_outer_width = window.outerWidth;\n\n        _this.mobile_view = _this.window_outer_width >= _this.breakpoint ? false : true;\n\n        window.addEventListener('scroll', _this.setScrollPosition);\n        window.addEventListener('resize', function() {\n            _this.window_outer_width = window.outerWidth;\n            _this.setScrollPosition();\n\n            _this.mobile_view = _this.window_outer_width >= _this.breakpoint ? false : true;\n\n            _this.rtime = new Date();\n\n            if (_this.timeout === false && !_this.mobile_view) {\n                _this.timeout = true;\n                setTimeout(_this.trackResizing, _this.delta);\n            }\n        });\n\n        /**\n         * Disable body scrolling when mouseover/mouseleave\n         * sidebar to prevent library scroll jumping.\n         */\n        var sidebar = document.querySelector('.ndpl-sidebar');\n        sidebar.addEventListener('mouseover', function(e) {\n            _this.sidebar_scrolling = true;\n        })\n        sidebar.addEventListener('mouseleave', function(e) {\n            _this.sidebar_scrolling = false;\n        });\n\n        /**\n         * Set active page based on hash or show first\n         * page on load variable.\n         */\n        setTimeout(function() {\n            var page = _this.isLoadingPage();\n\n            if(page) {\n                _this.loadPage(page);\n            }\n        }, 0);\n    },\n\n    methods: {\n\n        /**\n         * Apply syntax highlighting to pre code elements\n         * within passed element.\n         *\n         * @param el\n         */\n        applySyntaxHighlighting: function(el) {\n\n            setTimeout(function() {\n                var blocks = el.querySelectorAll('pre code');\n\n                for(var i = 0; i < blocks.length; i++) {\n                    var block = blocks[i];\n\n                    hljs.highlightBlock(block);\n                }\n            }, 0);\n        },\n\n        /**\n         * Reads the data.json file.\n         */\n        loadDataFile: function () {\n            var _this = this;\n\n            _this.$http.get('./data.json' + '?cb=' + new Date()).then(function (response) {\n                _this.initData(response.data, function() {\n                    if(_this.$data.groups.length) {\n                        _this.setupGroups();\n                    } else {\n                        _this.logInfo('You need to add a component to your library before it can be loaded.<br/>You can either do this manually by editing your <code>data.json</code> file,<br/> or you can use the command line helper: <code>astrum new [group_name/component_name]</code>');\n                    }\n                });\n            });\n        },\n\n        /**\n         * Determine if a page should be loaded.\n         */\n        isLoadingPage: function() {\n            var _this = this,\n                hash = location.hash;\n\n            if(_this.content.pages !== undefined && _this.content.pages.length) {\n\n                if(hash) {\n                    for (var i = 0; i < _this.content.pages.length; i++) {\n                        var page = _this.content.pages[i];\n\n                        if (page.name == hash.replace('#', '')) return page;\n                    }\n                } else if(_this.content.show_first_page_on_load) {\n                    return _this.content.pages[0];\n                }\n            }\n\n            return false;\n        },\n\n        /**\n         * Initilise data bindings.\n         *\n         * @param data\n         */\n        initData: function(data, callback) {\n            callback = typeof callback !== 'undefined' ?  callback : function() {};\n\n            var _this = this;\n\n            for(var key in data) {\n                _this.$set(key, data[key]);\n            }\n\n            callback();\n        },\n\n        /**\n         * Update URL hash.\n         *\n         * @param hash\n         */\n        updateHash: function(hash) {\n            history.pushState ? history.pushState(null, null, '#' + hash) : location.hash = hash;\n        },\n\n        /**\n         * Setup component groups.\n         */\n        setupGroups: function() {\n            var _this = this;\n\n            // Loop through the groups\n            for (var i = 0; i < _this.groups.length; i++) {\n                var group = _this.groups[i];\n\n                // Set group navigation navigation\n                _this.$set('groups[' + i + '].id', 'group-' + group.name);\n                _this.$set('groups[' + i + '].active', false);\n\n                // Set default variables\n                _this.$set('groups[' + i + '].description', '');\n\n                // Count groups\n                _this.groups_count = _this.groups.length;\n\n                // Load group\n                _this.loadGroup(_this.groups[i]);\n            }\n        },\n\n        setupComponents: function() {\n            var _this = this;\n\n            // Loop through the components\n            for (var i = 0; i < _this.groups.length; i++) {\n                var group = _this.groups[i];\n\n                // Count components\n                _this.components_count += group.components.length;\n\n                // Add group components to group\n                for (var j = 0; j < group.components.length; j++) {\n\n                    // Set default variables\n                    _this.$set('groups[' + i + '].components[' + j + '].id', 'group-' + group.name + '-component-' + group.components[j].name);\n                    _this.$set('groups[' + i + '].components[' + j + '].group_id', 'group-' + group.name);\n                    _this.$set('groups[' + i + '].components[' + j + '].active', false);\n                    _this.$set('groups[' + i + '].components[' + j + '].options', group.components[j].options ? group.components[j].options : false);\n                    _this.$set('groups[' + i + '].components[' + j + '].options.sample_always_show', group.components[j].options.sample_always_show ? group.components[j].options.sample_always_show : false);\n                    _this.$set('groups[' + i + '].components[' + j + '].options.sample_mobile_hidden', group.components[j].options.sample_mobile_hidden ? group.components[j].options.sample_mobile_hidden : false);\n                    _this.$set('groups[' + i + '].components[' + j + '].options.sample_dark_background', group.components[j].options.sample_dark_background ? group.components[j].options.sample_dark_background : false);\n                    _this.$set('groups[' + i + '].components[' + j + '].options.disable_code_sample', group.components[j].options.disable_code_sample ? group.components[j].options.disable_code_sample : false);\n                    _this.$set('groups[' + i + '].components[' + j + '].code_show', false);\n                    _this.$set('groups[' + i + '].components[' + j + '].type', group.components[j].type ? group.components[j].type : 'standard');\n                    _this.$set('groups[' + i + '].components[' + j + '].width', group.components[j].width ? group.components[j].width : 'full');\n\n                    // Add html and description properties to the component object.\n                    _this.$set('groups[' + i + '].components[' + j + '].html', '');\n                    _this.$set('groups[' + i + '].components[' + j + '].description', '');\n\n                    _this.loadComponent(_this.groups[i].components[j]);\n                }\n            }\n        },\n\n        /**\n         * Load group files.\n         *\n         * @param group\n         */\n        loadGroup: function(group) {\n            var _this = this,\n                group_path = './components/' + group.name;\n\n            // Get and set component description\n            _this.$http.get(group_path + '/description.md' + '?cb=' + new Date()).then(function (response) {\n                group.description = marked(response.data);\n                _this.areGroupsLoaded();\n            }, function () {\n                _this.logError('Description file for <strong>' + group.name + '</strong> group failed to load from <code>' + group_path + '/description.md</code>');\n            });\n        },\n\n        /**\n         * Load component files.\n         *\n         * @param component\n         */\n        loadComponent: function(component) {\n            var _this = this,\n                component_path = './components/' + component.group + '/' + component.name;\n\n            // Get and set component markup\n            _this.$http.get(component_path + '/markup.html' + '?cb=' + new Date()).then(function (response) {\n                component.html = response.data;\n                _this.areComponentsLoaded();\n            }, function () {\n                _this.logError('HTML file for <strong>' + component.name + '</strong> component failed to load from <code>' + component_path + '/html.md</code>');\n            });\n\n            // Get and set component description\n            _this.$http.get(component_path + '/description.md' + '?cb=' + new Date()).then(function (response) {\n                component.description = marked(response.data);\n                _this.areComponentsLoaded();\n            }, function () {\n                _this.logError('Description file for <strong>' + component.name + '</strong> component failed to load from <code>' + component_path + '/description.md</code>');\n            });\n        },\n\n        /**\n         * Increment groups loaded.\n         */\n        areGroupsLoaded: function() {\n            var _this = this;\n\n            _this.groups_loaded_count += 1;\n\n            if (_this.groups_loaded_count === _this.groups_count) {\n\n                setTimeout(function() {\n                    _this.groups_loaded = true;\n                }, 1000);\n            }\n        },\n\n        /**\n         * Increment components loaded.\n         */\n        areComponentsLoaded: function() {\n            var _this = this;\n\n            _this.components_loaded_count += 1;\n\n            if (_this.components_loaded_count === _this.components_count * 2) {\n\n                setTimeout(function() {\n                    _this.loaded = true;\n                }, 2000);\n            }\n        },\n\n        /**\n         * Add to log.\n         *\n         * @param message\n         * @param data\n         * @param type\n         */\n        addLog: function(message, data, type) {\n            var _this = this;\n\n            type = typeof type !== 'undefined' ? type : 'error';\n            data = typeof data !== 'undefined' ? data : null;\n\n            _this.log[type].push(message);\n            console[type]('[Pattern Library warn]: ' + message);\n\n            if(data) {\n                console[type](data);\n            }\n        },\n\n        /**\n         * Log error helper.\n         *\n         * @param message\n         * @param data\n         */\n        logError: function(message, data) {\n            var _this = this;\n\n            _this.addLog(message, data, 'error');\n        },\n\n        /**\n         * Log info helper.\n         *\n         * @param message\n         * @param data\n         */\n        logInfo: function(message, data) {\n            var _this = this;\n\n            _this.addLog(message, data, 'info');\n        },\n\n        /**\n         * Set scroll position.\n         */\n        setScrollPosition: function() {\n            var _this = this,\n                doc = document.documentElement,\n                top = doc && doc.scrollTop || document.body.scrollTop;\n\n            _this.prev_scroll_position = _this.scroll_position;\n            _this.scroll_position = top;\n        },\n\n        /**\n         * Get scroll direction.\n         *\n         * @returns {string}\n         */\n        getScrollDirection: function() {\n            var _this = this;\n\n            return _this.prev_scroll_position < _this.scroll_position ? 'down' : 'up';\n        },\n\n        /**\n         * Scroll to element.\n         *\n         * @param e\n         */\n        scrollToHref: function(e) {\n            var _this = this;\n\n            _this.scrollTo(e.target.hash);\n            _this.active_page = null;\n        },\n\n        /**\n         * Animate scroll to.\n         *\n         * @param hash\n         */\n        scrollTo: function(hash) {\n            var _this = this,\n                offset = _this.mobile_view ? 79 : 30;\n\n            if(!hash) return;\n\n            _this.scrolling_to = true;\n\n            smoothScroll.animateScroll(hash, null, {\n                offset: offset,\n                callback: function() {\n                    _this.scrolling_to = false;\n                    _this.open_nav = false;\n                }\n            });\n        },\n\n        /**\n         * Toggle navigation.\n         */\n        toggleNav: function() {\n            var _this = this;\n\n            _this.open_nav = ! _this.open_nav;\n        },\n\n        /**\n         * Toggle open groups.\n         *\n         * @param group\n         */\n        toggleOpenGroups: function(group) {\n            var _this = this;\n\n            _this.open_group = _this.open_group == group.id ? null : group.id;\n            _this.active_page = null;\n        },\n\n        /**\n         * Load content page.\n         * @param page\n         */\n        loadPage: function(page) {\n            var _this = this;\n\n            _this.active_page = page;\n            _this.active_components = [];\n            _this.open_group = null;\n            _this.open_nav = false;\n\n            _this.$http.get(page.file + '?cb=' + new Date()).then(function (response) {\n                _this.$set('active_page.markup', marked(response.data));\n\n                _this.applySyntaxHighlighting(document);\n            });\n\n            _this.updateHash(page.name);\n        },\n\n        /**\n         * Track resizing and broadcast resizing events.\n      */\n        trackResizing: function() {\n            var _this = this;\n\n            _this.resizing = true;\n            _this.$broadcast('resizing', true);\n\n            if (new Date() - _this.rtime < _this.delta) {\n                setTimeout(_this.trackResizing, _this.delta);\n            } else {\n                _this.timeout = false;\n\n                setTimeout(function() {\n                    _this.resizing = false;\n                    _this.$broadcast('resizing', false);\n                }, 1000);\n            }\n        },\n\n        /**\n         * Convert hex color value to rgb color values.\n         *\n         * @param hex\n         * @returns {{r: number, g: number, b: number}}\n         */\n        convertHexToRgb: function(hex) {\n            // Expand shorthand form (e.g. \"03F\") to full form (e.g. \"0033FF\")\n            var shorthandRegex = /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i;\n            hex = hex.replace(shorthandRegex, function(m, r, g, b) {\n                return r + r + g + g + b + b;\n            });\n\n            var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n            return result ? {\n                r: parseInt(result[1], 16),\n                g: parseInt(result[2], 16),\n                b: parseInt(result[3], 16)\n            } : null;\n        },\n\n        /**\n         * Get color brightness value from rgb color values.\n         *\n         * @param rgb\n         * @returns {number}\n         */\n        getColorBrightness: function(rgb) {\n            return Math.round(((parseInt(rgb.r) * 299) + (parseInt(rgb.g) * 587) + (parseInt(rgb.b) * 114)) /1000);\n        }\n    }\n});"
  },
  {
    "path": "pattern-library/assets/js/patterns.js",
    "content": "(function() {\n    var componentSamples = [].slice.call(document.querySelectorAll('.ndpl-component__sample'));\n\n    if(componentSamples.length) {\n        componentSamples.map(function(item) {\n            item.classList.add('boilerform');\n        });\n    }\n}());"
  },
  {
    "path": "pattern-library/components/button/default/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/button/default/markup.html",
    "content": "<button class=\"c-button\">A button</button>"
  },
  {
    "path": "pattern-library/components/button/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/check-field/checkbox/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/check-field/checkbox/markup.html",
    "content": "<div class=\"c-check-field\">\n    <input type=\"checkbox\" name=\"checkbox-field\" id=\"checkbox-field\" class=\"c-check-field__input\" />\n    <label for=\"checkbox-field\" class=\"c-check-field__decor\" aria-hidden=\"true\" role=\"presentation\"></label>\n    <label for=\"checkbox-field\" class=\"c-check-field__label\">A checkbox field</label>\n</div>"
  },
  {
    "path": "pattern-library/components/check-field/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/check-field/error-state/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/check-field/error-state/markup.html",
    "content": "<div class=\"[ c-check-field ] [ is-error ]\">\n    <input type=\"checkbox\" name=\"checkbox-error-field\" id=\"checkbox-error-field\" class=\"c-check-field__input\" />\n    <label for=\"checkbox-error-field\" class=\"c-check-field__decor\" aria-hidden=\"true\" role=\"presentation\"></label>\n    <label for=\"checkbox-error-field\" class=\"c-check-field__label\">A checkbox field</label>\n</div>\n<div class=\"[ c-check-field c-check-field--radio ] [ is-error ]\">\n    <input type=\"radio\" name=\"radio-error-field\" id=\"radio-error-field\" class=\"c-check-field__input\" />\n    <label for=\"radio-error-field\" class=\"c-check-field__decor\" aria-hidden=\"true\" role=\"presentation\"></label>\n    <label for=\"radio-error-field\" class=\"c-check-field__label\">A radio button</label>\n</div>\n"
  },
  {
    "path": "pattern-library/components/check-field/radio/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/check-field/radio/markup.html",
    "content": "<div class=\"c-check-field c-check-field--radio\">\n    <input type=\"radio\" name=\"checkbox-field\" id=\"checkbox-radio-field-1\" class=\"c-check-field__input\" />\n    <label for=\"checkbox-radio-field-1\" class=\"c-check-field__decor\" aria-hidden=\"true\" role=\"presentation\"></label>\n    <label for=\"checkbox-radio-field-1\" class=\"c-check-field__label\">A radio button</label>\n</div>\n<div class=\"c-check-field c-check-field--radio\">\n    <input type=\"radio\" name=\"checkbox-field\" id=\"checkbox-radio-field-2\" class=\"c-check-field__input\" />\n    <label for=\"checkbox-radio-field-2\" class=\"c-check-field__decor\" aria-hidden=\"true\" role=\"presentation\"></label>\n    <label for=\"checkbox-radio-field-2\" class=\"c-check-field__label\">Another radio button</label>\n</div>"
  },
  {
    "path": "pattern-library/components/input-field/description.md",
    "content": "Generic input fields with variations for size, placeholders and validation states. Relevant attributes are added to help users input data as efficiently as possible."
  },
  {
    "path": "pattern-library/components/input-field/email/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/input-field/email/markup.html",
    "content": "<input type=\"email\" name=\"\" id=\"\" autocapitalize=\"none\" autocorrect=\"off\" class=\"c-input-field\" value=\"user@email.com\" />"
  },
  {
    "path": "pattern-library/components/input-field/error-state/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/input-field/error-state/markup.html",
    "content": "<input type=\"text\" name=\"\" id=\"\" class=\"[ c-input-field ] [ is-error ]\" value=\"Generic text\" />"
  },
  {
    "path": "pattern-library/components/input-field/number/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/input-field/number/markup.html",
    "content": "<input type=\"number\" name=\"\" id=\"\" min=\"1\" max=\"999\" step=\"1\" class=\"c-input-field\" value=\"123\" />"
  },
  {
    "path": "pattern-library/components/input-field/search/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/input-field/search/markup.html",
    "content": "<input type=\"search\" name=\"\" id=\"\" autocorrect=\"off\" class=\"c-input-field\" value=\"Some search terms\" />"
  },
  {
    "path": "pattern-library/components/input-field/tel/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/input-field/tel/markup.html",
    "content": "<input type=\"tel\" name=\"\" id=\"\" class=\"c-input-field\" value=\"01234 567 890\" />"
  },
  {
    "path": "pattern-library/components/input-field/text/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/input-field/text/markup.html",
    "content": "<input type=\"text\" name=\"\" id=\"\" class=\"c-input-field\" value=\"Generic text\" />"
  },
  {
    "path": "pattern-library/components/input-field/text-area/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/input-field/text-area/markup.html",
    "content": "<textarea name=\"\" id=\"\" class=\"c-input-field c-input-field--multiline\">Some multiline text</textarea>"
  },
  {
    "path": "pattern-library/components/label/default/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/label/default/markup.html",
    "content": "<label for=\"\" class=\"c-label\">A label for a field</label>\n<input class=\"c-input-field\" value=\"fdsfds\" />"
  },
  {
    "path": "pattern-library/components/label/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/select-field/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/select-field/error-state/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/select-field/error-state/markup.html",
    "content": "<div class=\"[ c-select-field ] [ is-error ]\">\n    <select name=\"\" id=\"\" class=\"c-select-field__menu\">\n        <option>Select an item</option>\n        <option value=\"1\">Item 1</option>\n        <option value=\"2\">Item 2</option>\n        <option value=\"3\">Item 3</option>\n        <option value=\"4\">Item 5</option>\n    </select>\n    <span class=\"c-select-field__decor\" aria-hidden=\"true\" role=\"presentation\">&dtrif;</span>\n</div>"
  },
  {
    "path": "pattern-library/components/select-field/select-menu/description.md",
    "content": ""
  },
  {
    "path": "pattern-library/components/select-field/select-menu/markup.html",
    "content": "<div class=\"c-select-field\">\n    <select name=\"\" id=\"\" class=\"c-select-field__menu\">\n        <option>Select an item</option>\n        <option value=\"1\">Item 1</option>\n        <option value=\"2\">Item 2</option>\n        <option value=\"3\">Item 3</option>\n        <option value=\"4\">Item 5</option>\n    </select>\n    <span class=\"c-select-field__decor\" aria-hidden=\"true\" role=\"presentation\">&dtrif;</span>\n</div>"
  },
  {
    "path": "pattern-library/data.json",
    "content": "{\n    \"project_logo\": \"/assets/images/logo/logo.svg\",\n    \"project_favicon\": \"favicon.png\",\n    \"project_name\": \"Boilerform\",\n    \"project_url\": null,\n    \"copyright_start_year\": null,\n    \"client_name\": null,\n    \"client_url\": null,\n    \"creators\": [\n        {\n            \"name\": \"Boilerform site\",\n            \"url\": \"//boilerform.hankchizljaw.com\"\n        },\n        {\n            \"name\": \"Boilerform repo\",\n            \"url\": \"//github.com/hankchizljaw/boilerform\"\n        },\n        {\n            \"name\": \"By hankchizljaw\",\n            \"url\": \"//hankchizljaw.com\"\n        }\n    ],\n    \"theme\": {\n        \"border_color\": \"#E0E6ED\",\n        \"highlight_color\": \"#F9FAFC\",\n        \"brand_color\": \"#A03EA0\",\n        \"background_color\": \"#FFFFFF\",\n        \"code_highlight_theme\": \"github\",\n        \"override_code_highlight_bg\": \"#F9FAFC\",\n        \"sample_dark_background\": \"#333333\",\n        \"show_project_name\": false,\n        \"show_version\": true,\n        \"max_width\": null,\n        \"titles\": {\n            \"library_title\": \"Patterns\",\n            \"pages_title\": \"Overview\",\n            \"components_title\": \"Components\"\n        }\n    },\n    \"assets\": {\n        \"css\": [\n            \"https://cdn.statically.io/gh/hankchizljaw/boilerform/70a13a07/dist/css/boilerform.min.css\"\n        ],\n        \"js\": [\n            \"/assets/js/patterns.js?v=1.1.1\"\n        ]\n    },\n    \"font_libraries\": {\n        \"typekit_code\": null,\n        \"typography_web_fonts\": null,\n        \"google_web_fonts\": null\n    },\n    \"content\": null,\n    \"groups\": [\n        {\n            \"name\": \"input-field\",\n            \"title\": \"Input Field\",\n            \"components\": [\n                {\n                    \"group\": \"input-field\",\n                    \"name\": \"text\",\n                    \"title\": \"Text\",\n                    \"width\": \"half\"\n                },\n                {\n                    \"group\": \"input-field\",\n                    \"name\": \"email\",\n                    \"title\": \"Email\",\n                    \"width\": \"half\"\n                },\n                {\n                    \"group\": \"input-field\",\n                    \"name\": \"search\",\n                    \"title\": \"Search\",\n                    \"width\": \"half\"\n                },\n                {\n                    \"group\": \"input-field\",\n                    \"name\": \"number\",\n                    \"title\": \"Number\",\n                    \"width\": \"half\"\n                },\n                {\n                    \"group\": \"input-field\",\n                    \"name\": \"tel\",\n                    \"title\": \"Tel\",\n                    \"width\": \"half\"\n                },\n                {\n                    \"group\": \"input-field\",\n                    \"name\": \"text-area\",\n                    \"title\": \"Textarea / Multiline\",\n                    \"width\": \"half\"\n                },\n                {\n                    \"group\": \"input-field\",\n                    \"name\": \"error-state\",\n                    \"title\": \"Error State\",\n                    \"width\": \"half\"\n                }\n            ]\n        },\n        {\n            \"name\": \"select-field\",\n            \"title\": \"Select Field\",\n            \"components\": [\n                {\n                    \"group\": \"select-field\",\n                    \"name\": \"select-menu\",\n                    \"title\": \"Select Menu\",\n                    \"width\": \"half\"\n                },\n                {\n                    \"group\": \"select-field\",\n                    \"name\": \"error-state\",\n                    \"title\": \"Error State\",\n                    \"width\": \"half\"\n                }\n            ]\n        },\n        {\n            \"name\": \"check-field\",\n            \"title\": \"Check Field\",\n            \"components\": [\n                {\n                    \"group\": \"check-field\",\n                    \"name\": \"checkbox\",\n                    \"title\": \"Checkbox\",\n                    \"width\": \"half\"\n                },\n                {\n                    \"group\": \"check-field\",\n                    \"name\": \"radio\",\n                    \"title\": \"Radio\",\n                    \"width\": \"half\"\n                },\n                {\n                    \"group\": \"check-field\",\n                    \"name\": \"error-state\",\n                    \"title\": \"Error State\",\n                    \"width\": \"half\"\n                }\n            ]\n        },\n        {\n            \"name\": \"button\",\n            \"title\": \"Button\",\n            \"components\": [\n                {\n                    \"group\": \"button\",\n                    \"name\": \"default\",\n                    \"title\": \"Default\",\n                    \"width\": \"half\"\n                }\n            ]\n        },\n        {\n            \"name\": \"label\",\n            \"title\": \"Label\",\n            \"components\": [\n                {\n                    \"group\": \"label\",\n                    \"name\": \"default\",\n                    \"title\": \"Default\",\n                    \"width\": \"half\"\n                }\n            ]\n        }\n    ],\n    \"version\": \"1.9.5\"\n}\n"
  },
  {
    "path": "pattern-library/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\" class=\"ndpl-c-background\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta name=\"viewport\" content=\"width=device-width\">\n\n        <title v-text=\"project_name ? project_name + ' | Pattern Library' : 'Pattern Library'\"></title>\n\n        <!-- Astrum (https://github.com/NoDivide/astrum) -->\n        <meta name=\"application-name\" content=\"Astrum {{ version }}\" />\n\n        <!-- Favicon -->\n        <link rel=\"shortcut icon\" type=\"image/png\" :href=\"project_favicon\" />\n\n        <!-- Pattern Library Stylesheets: DO NOT CHANGE -->\n        <link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700\" rel='stylesheet' type='text/css'>\n        <script src=\"https://ajax.googleapis.com/ajax/libs/webfont/1.6.16/webfont.js\"></script>\n        <script>\n            WebFont.load({\n                google: {\n                    families: ['Open Sans']\n                }\n            });\n        </script>\n        <style>\n            /* Targeted theme styles */\n            .ndpl-folding-cube .ndpl-cube:before { background-color: {{ theme.brand_color }} !important; }\n            .ndpl-component__sample--inverted    { background-color: {{ theme.sample_dark_background }} !important }\n            .ndpl-c-background                   { background-color: {{ theme.background_color }} !important; }\n            .ndpl-c-border                       { border-color: {{ theme.border_color }} !important; }\n            .ndpl-c-border-b                     { border-bottom-color: {{ theme.border_color }} !important; }\n            .ndpl-c-highlight                    { background-color: {{ theme.highlight_color }} !important; }\n            .ndpl-c-highlight-ca a.active,\n            .ndpl-c-highlight-ca a:hover         { background-color: {{ theme.highlight_color }} !important; }\n            .ndpl-c-brand-c                      { color: {{ theme.brand_color }} !important; }\n            .ndpl-c-brand-bg                     { background-color: {{ theme.brand_color }} !important; }\n            .ndpl-c-brand-b                      { border-color: {{ theme.brand_color }} !important; }\n            .ndpl-c-brand-bl-ca a.active,\n            .ndpl-c-brand-bl-ca a:hover          { border-left-color: {{ theme.brand_color }} !important; }\n            .ndpl-c-brand-a:hover                { color: {{ theme.brand_color }} !important; }\n            .ndpl-c-brand-ca a:hover             { color: {{ theme.brand_color }} !important; }\n            .ndpl-c-brand-cai a                  { color: {{ theme.brand_color }} !important; }\n        </style>\n        <link rel=\"stylesheet\" v-if=\"theme.code_highlight_theme\" :href=\"'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/' + theme.code_highlight_theme + '.min.css'\">\n        <style v-if=\"theme.override_code_highlight_bg\">.hljs { background: {{ theme.override_code_highlight_bg }}} !important; }</style>\n        <link rel=\"stylesheet\" href=\"app/css/styles.min.css\">\n\n        <!-- Font Libraries -->\n        <link rel=\"stylesheet\" v-if=\"font_libraries.google_web_fonts\" :href=\"font_libraries.google_web_fonts\">\n        <link rel=\"stylesheet\" v-if=\"font_libraries.typography_web_fonts\" :href=\"font_libraries.typography_web_fonts\">\n        <ndpl-script :script=\"'https://use.typekit.net/' + font_libraries.typekit_code + '.js'\" v-if=\"font_libraries.typekit_code\" inline-template>\n            <script :src=\"script\" @load=\"loadTypekit\"></script>\n        </ndpl-script>\n\n        <!-- Custom stylesheets are loaded from the assets.css array in data.json -->\n        <link rel=\"stylesheet\" v-for=\"css in assets.css\" :href=\"css\">\n    </head>\n    <body id=\"top\"\n          class=\"ndpl-body ndpl-c-background\"\n          :class=\"{ 'ndpl-inverted': theme.invert_text, 'ndpl-desktop': !mobile_view, 'ndpl-mobile': mobile_view, 'ndpl-disable-scrolling': sidebar_scrolling }\">\n\n    <div class=\"ndpl-loading\" :class=\"{ 'in-progress': ! loaded }\">\n        <div class=\"ndpl-folding-cube\" v-if=\"!log.error.length && !log.info.length\">\n            <div class=\"ndpl-cube1 ndpl-cube\"></div>\n            <div class=\"ndpl-cube2 ndpl-cube\"></div>\n            <div class=\"ndpl-cube4 ndpl-cube\"></div>\n            <div class=\"ndpl-cube3 ndpl-cube\"></div>\n        </div>\n\n        <h3 class=\"ndpl-loading__title\" v-if=\"! loaded && !log.error.length && !log.info.length\">Building pattern library...</h3>\n        <h3 class=\"ndpl-loading__title\" v-if=\"log.error.length\">Hold up! We have some errors...</h3>\n        <h3 class=\"ndpl-loading__title\" v-if=\"log.info.length && !log.error.length\">Looks like you have some setup to do...</h3>\n\n        <ul class=\"ndpl-error\" v-if=\"log.error.length\">\n            <li class=\"ndpl-error__item\" v-for=\"error in log.error\">{{{ error }}}</li>\n        </ul>\n        <ul class=\"ndpl-info\" v-if=\"log.info.length && !log.error.length\">\n            <li class=\"ndpl-info__item\" v-for=\"info in log.info\">{{{ info }}}</li>\n        </ul>\n    </div>\n\n    <div class=\"ndpl-container\"\n         :class=\"{ 'loaded': loaded }\">\n\n        <header class=\"ndpl-header\">\n\n            <img class=\"ndpl-header__logo\"\n                 :src=\"project_logo\"\n                 :alt=\"project_name\"\n                 v-if=\"project_logo\"/>\n\n            <h1 class=\"ndpl-header__title ndpl-c-brand-ca\">\n                <span v-if=\"theme.show_project_name\">{{{ project }}}</span>\n                <small v-if=\"theme.titles.library_title\"\n                       v-text=\"theme.titles.library_title\"></small>\n            </h1>\n\n            <div class=\"ndpl-nav-handle\"\n                 :class=\"{ 'open': open_nav }\"\n                 @click=\"toggleNav\">\n                <div class=\"ndpl-nav-handle__container\">\n                    <span></span>\n                    <span></span>\n                    <span></span>\n                </div>\n            </div>\n        </header>\n\n        <div class=\"ndpl-sidebar\"\n             :class=\"{ 'open': open_nav }\">\n\n            <header class=\"ndpl-sidebar__header\">\n\n                <img class=\"ndpl-sidebar__logo\"\n                     :src=\"project_logo\"\n                     :alt=\"project_name\"\n                     v-if=\"project_logo\"/>\n\n                <h1 class=\"ndpl-sidebar__title ndpl-c-brand-ca\">\n                    <span v-if=\"theme.show_project_name\">{{{ project }}}</span>\n                    <small v-if=\"theme.titles.library_title\"\n                           v-text=\"theme.titles.library_title\"></small>\n                </h1>\n\n            </header>\n\n            <nav class=\"ndpl-nav\">\n                <template v-if=\"content\">\n                    <h2 class=\"ndpl-nav__title\"\n                        v-if=\"theme.titles.pages_title\"\n                        v-text=\"theme.titles.pages_title\"></h2>\n\n                    <ul class=\"ndpl-nav__items ndpl-c-border ndpl-c-highlight-ca ndpl-c-brand-bl-ca\">\n                        <li class=\"ndpl-nav__item\" v-for=\"page in content.pages\">\n                            <a class=\"ndpl-nav__page ndpl-nsc ndpl-c-border-b\"\n                               :class=\"{ 'active': active_page && active_page.title === page.title }\"\n                               v-text=\"page.title\"\n                               @click.prevent=\"loadPage(page)\">\n                            </a>\n                        </li>\n                    </ul>\n                </template>\n\n                <h2 class=\"ndpl-nav__title\">\n                    <a class=\"ndpl-nsc\"\n                       href=\"#top\"\n                       @click.prevent=\"scrollToHref\"\n                       v-if=\"theme.titles.components_title\"\n                       v-text=\"theme.titles.components_title\"></a>\n                </h2>\n\n                <ul class=\"ndpl-nav__items ndpl-c-border\">\n                    <li class=\"ndpl-nav__item\"\n                        v-for=\"group in groups\"\n                        :class=\"{ 'active': active_components.length > 0 && group.id == active_components[0].group_id || group.id == open_group }\">\n\n                        <a :href=\"'#' + group.id\"\n                           class=\"ndpl-nav__group ndpl-nsc ndpl-c-border-b\"\n                           v-text=\"group.title\"\n                           @click.prevent=\"toggleOpenGroups(group)\">\n                        </a>\n\n                        <ul class=\"ndpl-nav__child-items ndpl-c-highlight\"\n                            v-if=\"group.components.length\">\n\n                            <li class=\"ndpl-nav__child-item ndpl-c-border-b ndpl-c-brand-bl-ca\"\n                                v-for=\"component in group.components\">\n                                <a :href=\"'#' + component.id\"\n                                   class=\"ndpl-nav__component ndpl-nsc\"\n                                   :class=\"{ 'active': active_components.indexOf(component) >= 0 }\"\n                                   v-text=\"component.title\"\n                                   @click.prevent=\"scrollToHref\">\n                                </a>\n                            </li>\n                        </ul>\n                    </li>\n                </ul>\n\n            </nav>\n\n            <div class=\"ndpl-copyright ndpl-c-brand-ca\">\n\n                <p v-if=\"copyright_start_year && client || all_creators\">\n                    <template v-if=\"copyright_start_year && client\">\n                        &copy; {{ copyright_year }} {{{ client }}}.\n                    </template>\n                    <template v-if=\"all_creators\">\n                        <br/>Pattern library created by {{{ all_creators }}}.\n                    </template>\n                </p>\n\n                <p v-if=\"theme.show_version\">Astrum v{{ version }}</p>\n\n            </div>\n        </div>\n\n        <div class=\"ndpl-content\" data-app=\"astrum\">\n            <div class=\"ndpl-page ndpl-c-brand-cai\" :style=\"library_inline_styles\" v-if=\"active_page\">{{{ active_page.markup }}}</div>\n            <div class=\"ndpl-library\" :style=\"library_inline_styles\" :class=\"{ 'ndpl-preloaded': active_page }\">\n\n                <ndpl-group v-for=\"group in groups\"\n                            :group=\"group\"\n                            inline-template>\n\n                    <div class=\"ndpl-library__group\"\n                         :id=\"group.id\">\n\n                        <h2 class=\"ndpl-library__title\">{{ group.title }}</h2>\n\n                        <div class=\"ndpl-group__description ndpl-c-brand-ca\"\n                             v-html=\"group.description\"\n                             v-if=\"group.description\"></div>\n\n                        <div class=\"ndpl-components\">\n                            <ndpl-component v-for=\"component in group.components\"\n                                            :component=\"component\"\n                                            inline-template>\n\n                                <div class=\"ndpl-component\"\n                                     :id=\"component.id\"\n                                     :group-id=\"component.group_id\"\n                                     :class=\"'ndpl-component--' + component.width\">\n\n                                    <h3 class=\"ndpl-component__title\">{{ component.title }}</h3>\n\n                                    <div class=\"ndpl-component__description ndpl-c-brand-ca\"\n                                         v-html=\"component.description\"></div>\n\n                                    <template v-if=\"component.type == 'colors'\">\n                                        <div v-if=\"component.colors.length\" class=\"ndpl-component__colors ndpl-cf\">\n\n                                            <div class=\"ndpl-component__color-container\"\n                                                 v-for=\"color in component.colors\">\n\n                                                <div class=\"ndpl-component__color\"\n                                                     v-for=\"item in color.split(',')\"\n                                                     :class=\"{ 'ndpl-apply-border ndpl-c-border': shouldApplyBorder(item), }\"\n                                                     :style=\"'background-color:' + item\">\n                                                    <div :class=\"{ 'ndpl-dark-text': shouldInvertText(item) }\">{{ item }}</div>\n                                                </div>\n\n                                            </div>\n\n                                        </div>\n                                        <ul v-else class=\"ndpl-component__sample-missing ndpl-info\">\n                                            <li class=\"ndpl-info__item\">Locate this component in your <code>data.json</code> file and add your colors to the \"colors\" array that has been created for you e.g.:</li>\n                                            <li><pre class=\"ndpl-pre\">\"colors\": [\"#4c4c4c\",\"#7d8284\",\"#a6b1b5\",\"#e6eaf2\",\"#FFFFFF\"]</pre></li>\n                                        </ul>\n                                    </template>\n                                    <template v-else>\n                                        <div class=\"ndpl-component__container\"\n                                             v-show=\"isCodeVisible()\">\n\n                                            <div class=\"ndpl-component__sample ndpl-c-border\"\n                                                 :class=\"{\n                                                    'ndpl-component__sample--inverted': component.options.sample_dark_background,\n                                                    'ndpl-component__sample--disabled-code': component.options.disable_code_sample\n                                                 }\"\n                                                 :style=\"inline_styles\"\n                                                 v-if=\"component.html\">\n                                                {{{ component.html }}}\n                                            </div>\n\n                                            <template v-if=\"component.html\">\n                                                <div class=\"ndpl-component__code ndpl-c-border\"\n                                                     v-show=\"component.code_show\">\n                                                    <pre class=\"ndpl-pre\"><code class=\"ndpl-code html\" v-text=\"component.html\"></code></pre>\n                                                </div>\n                                                <a v-if=\"!component.options.disable_code_sample\"\n                                                   class=\"ndpl-component__code-toggle ndpl-c-highlight ndpl-c-border\"\n                                                   @click.prevent=\"component.code_show = ! component.code_show\"\n                                                   v-text=\"component.code_show ? 'Hide code sample' : 'Show code sample'\"></a>\n                                            </template>\n                                            <ul v-else class=\"ndpl-component__sample-missing ndpl-info\">\n                                                <li class=\"ndpl-info__item\">Add your component markup to <code>/components/{{ component.group }}/{{ component.name }}/markup.html</code></li>\n                                            </ul>\n\n                                        </div>\n\n                                        <div class=\"ndpl-component__sample-hidden ndpl-info\"\n                                             v-show=\"!isCodeVisible()\">\n                                            This component is hidden at this resolution.\n                                        </div>\n                                    </template>\n                                </div>\n                            </ndpl-component>\n                        </div>\n                    </div>\n                </ndpl-group>\n            </div>\n        </div>\n    </div>\n\n    <ndpl-script v-for=\"script in assets.js\"\n                 :script=\"script\"\n                 v-if=\"loaded\"\n                 inline-template>\n        <script :src=\"script\"></script>\n    </ndpl-script>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.25/vue.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.8.0/vue-resource.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/smooth-scroll/10.0.0/js/smooth-scroll.min.js\"></script>\n    <script src=\"app/js/main.min.js\"></script>\n    </body>\n</html>\n"
  },
  {
    "path": "readme.md",
    "content": "# Boilerform\n\n<img src=\"https://s3-us-west-2.amazonaws.com/s.cdpn.io/174183/share.png\" style=\"max-width: 100%\" alt=\"The Boilerform logo\" />\n\nBoilerform is a little HTML and CSS boilerplate to take the pain away from working with forms.\n\nBy providing baseline BEM structured CSS and appropriate attributes on elements: Boilerform gives you a head start building forms in the best possible way with a view to being dropped into most projects.\n\nThe idea was first thought-up by [@chriscoyier](https://twitter.com/chriscoyier) on [CSS Tricks](https://css-tricks.com/boilerform).\n\n🌍 <https://boilerform.hankchizljaw.com>\n\n\n## Getting started\nBoilerform is designed to be straight-forward to implement. In its most basic form, you can drop a CSS file into your head with the following snippet:\n\n```html\n<link rel=\"stylesheet\" media=\"all\" href=\"https://cdn.jsdelivr.net/gh/hankchizljaw/boilerform@master/dist/css/boilerform.min.css?v=1.1.1\" />\n```\n\nThen all you need to do is wrap your elements in a `.boilerform` wrapper. It could be something like this:\n\n```html\n<div class=\"boilerform\">\n    <!-- Add all of your boilerform elements in here 👍 -->\n</div>\n```\n\nYou can also take compiled CSS and HTML from the [dist directory](https://github.com/hankchizljaw/boilerform/tree/master/dist/) of this repository, if that's what you prefer.\n\nIf you want a bit more control, you can work with the [Sass](https://github.com/hankchizljaw/boilerform/tree/master/assets/scss) and [Pattern Library](https://github.com/hankchizljaw/boilerform/tree/master/pattern-library). This is where the source of Boilerform lives.\n\nTo compile assets, you can run the following commands in your terminal:\n\n- `npm run watch` will compile your assets and watch for further changes\n- `npm run build` will compile your assets into a production ready state in the `dist` directory\n\nThe pattern library is powered by [Astrum](http://astrum.nodividestudio.com/). You can find [detailed documentation here](https://github.com/NoDivide/Astrum).\n\n## Validation interface\n\nThere's a basic validation interface available with Boilerform which extends the native HTML validation facility with a few visual tweaks.\n### Getting started\n\nFirst of all, you need the JavaScript in your project. You can either take the [source code](https://github.com/hankchizljaw/boilerform/blob/master/assets/js/modules/validation.js) and add to your project, or add the dist version to bottom of your page.\n\n```html\n<script src=\"https://cdn.jsdelivr.net/gh/hankchizljaw/boilerform@master/dist/js/boilerform.min.js?v=1.1.1\" async defer></script>\n```\n\nNow that you've got the script, it'll work, as long as your elements have the `required` attribute, which will allow them to fire an `invalid` event. You'll also need to make sure your `<form>` elements either live in a `.boilerform` parent element or have the `.boilerform` class.\n\n---\n\nMade with ❤️ by [HankChizlJaw](https://twitter.com/hankchizljaw) and [friends](https://github.com/hankchizljaw/boilerform/graphs/contributors).\n"
  },
  {
    "path": "webpack.config.js",
    "content": "// Pull in .env settings \nrequire('dotenv').config();\n\n// Create CSS and JS output paths \nvar CSS_OUTPUT_PATH = process.env.CSS_OUTPUT_PATH ? process.env.CSS_OUTPUT_PATH : '../css/boilerform.css';\nvar JS_OUTPUT_PATH = process.env.JS_OUTPUT_PATH ? process.env.JS_OUTPUT_PATH : '/dist/js';\n\n// Define webpack stuff\nvar ExtractTextPlugin = require('extract-text-webpack-plugin');\nvar isProduction = process.env.NODE_ENV === 'production';\nvar path = require('path');\nvar plugins = [];\nvar settings = {\n    libraryName: 'boilerform',\n    inputs: {\n        js: {\n            entryPath: '/assets/js/boilerform.js'\n        }\n    },\n    outputs: {\n        js: {\n            fileName: 'boilerform.js',\n            minFileName: 'boilerform.min.js',\n            path: JS_OUTPUT_PATH\n        },\n        css: {\n            path: CSS_OUTPUT_PATH \n        }\n    }\n};\nvar webpack = require('webpack');\n\nif(isProduction) {\n    plugins.push(new webpack.optimize.UglifyJsPlugin({ minimize: true }));\n}\n\n// Create an extract text plugin instance for Sass\nvar extractPlugin = new ExtractTextPlugin(settings.outputs.css.path);\n\nplugins.push(extractPlugin);\n\nmodule.exports = {\n    entry: path.join(__dirname, settings.inputs.js.entryPath),\n    devtool: 'source-map',\n    output: {\n        path: path.join(__dirname, settings.outputs.js.path),\n        filename: (isProduction ? settings.outputs.js.minFileName : settings.outputs.js.fileName),\n        library: settings.libraryName,\n        libraryTarget: 'umd',\n        umdNamedDefine: true\n    },\n    module: {\n        rules: [\n            {\n                test: /\\.js$/,\n                exclude: /node_modules/,\n                use: [\n                    {\n                        loader: 'babel-loader'\n                    }\n                ]\n            },\n            {\n                test: /\\.scss$/,\n                use: extractPlugin.extract({\n                    use: ['css-loader', 'sass-loader']\n                })\n            }\n        ]\n    },\n    resolve: {\n        extensions: ['.js']\n    },\n    plugins: plugins\n};\n"
  }
]