diff options
| author | schneefux <schneefux+commit@schneefux.xyz> | 2017-03-22 19:19:26 +0100 |
|---|---|---|
| committer | schneefux <schneefux+commit@schneefux.xyz> | 2017-03-22 19:19:26 +0100 |
| commit | d42c8b528eb595101954f478e0024e3f079f6fbf (patch) | |
| tree | 61a528cf94f1f6941f4683ae8736a4a0135c035e /templates/assets/bootstrap | |
| download | minionlivesmatter-d42c8b528eb595101954f478e0024e3f079f6fbf.tar.gz minionlivesmatter-d42c8b528eb595101954f478e0024e3f079f6fbf.zip | |
first implementation of fun stats site
Diffstat (limited to 'templates/assets/bootstrap')
117 files changed, 16334 insertions, 0 deletions
diff --git a/templates/assets/bootstrap/.bower.json b/templates/assets/bootstrap/.bower.json new file mode 100644 index 0000000..06b071c --- /dev/null +++ b/templates/assets/bootstrap/.bower.json @@ -0,0 +1,44 @@ +{ + "name": "bootstrap", + "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", + "keywords": [ + "css", + "js", + "sass", + "mobile-first", + "responsive", + "front-end", + "framework", + "web" + ], + "homepage": "https://getbootstrap.com", + "license": "MIT", + "moduleType": "globals", + "main": [ + "scss/bootstrap.scss", + "dist/js/bootstrap.js" + ], + "ignore": [ + "/.*", + "_config.yml", + "CNAME", + "composer.json", + "CONTRIBUTING.md", + "docs", + "js/tests", + "test-infra" + ], + "dependencies": { + "jquery": ">=1.9.1", + "tether": "^1.4.0" + }, + "_release": "78fc4d23fc", + "_resolution": { + "type": "branch", + "branch": "v4-dev", + "commit": "78fc4d23fcefe31397444b75f43728c38e13c590" + }, + "_source": "https://github.com/twbs/bootstrap.git", + "_target": "v4-dev", + "_originalSource": "bootstrap" +}
\ No newline at end of file diff --git a/templates/assets/bootstrap/CHANGELOG.md b/templates/assets/bootstrap/CHANGELOG.md new file mode 100644 index 0000000..7b60d7c --- /dev/null +++ b/templates/assets/bootstrap/CHANGELOG.md @@ -0,0 +1,5 @@ +Bootstrap uses [GitHub's Releases feature](https://github.com/blog/1547-release-your-software) for its changelogs. + +See [the Releases section of our GitHub project](https://github.com/twbs/bootstrap/releases) for changelogs for each release version of Bootstrap. + +Release announcement posts on [the official Bootstrap blog](https://blog.getbootstrap.com) contain summaries of the most noteworthy changes made in each release. diff --git a/templates/assets/bootstrap/Gemfile b/templates/assets/bootstrap/Gemfile new file mode 100644 index 0000000..958c7a9 --- /dev/null +++ b/templates/assets/bootstrap/Gemfile @@ -0,0 +1,8 @@ +source 'https://rubygems.org' + +group :development, :test do + gem 'jekyll', '~> 3.4.2' + gem 'jekyll-redirect-from', '~> 0.12.1' + gem 'jekyll-sitemap', '~> 1.0.0' + gem 'scss_lint', '~> 0.52.0' +end diff --git a/templates/assets/bootstrap/Gemfile.lock b/templates/assets/bootstrap/Gemfile.lock new file mode 100644 index 0000000..242ec49 --- /dev/null +++ b/templates/assets/bootstrap/Gemfile.lock @@ -0,0 +1,58 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.5.0) + public_suffix (~> 2.0, >= 2.0.2) + colorator (1.1.0) + ffi (1.9.18) + forwardable-extended (2.6.0) + jekyll (3.4.2) + addressable (~> 2.4) + colorator (~> 1.0) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 1.1) + kramdown (~> 1.3) + liquid (~> 3.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (~> 1.7) + safe_yaml (~> 1.0) + jekyll-redirect-from (0.12.1) + jekyll (~> 3.3) + jekyll-sass-converter (1.5.0) + sass (~> 3.4) + jekyll-sitemap (1.0.0) + jekyll (~> 3.3) + jekyll-watch (1.5.0) + listen (~> 3.0, < 3.1) + kramdown (1.13.2) + liquid (3.0.6) + listen (3.0.8) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + mercenary (0.3.6) + pathutil (0.14.0) + forwardable-extended (~> 2.6) + public_suffix (2.0.5) + rake (12.0.0) + rb-fsevent (0.9.8) + rb-inotify (0.9.8) + ffi (>= 0.5.0) + rouge (1.11.1) + safe_yaml (1.0.4) + sass (3.4.23) + scss_lint (0.52.0) + rake (>= 0.9, < 13) + sass (~> 3.4.20) + +PLATFORMS + ruby + +DEPENDENCIES + jekyll (~> 3.4.2) + jekyll-redirect-from (~> 0.12.1) + jekyll-sitemap (~> 1.0.0) + scss_lint (~> 0.52.0) + +BUNDLED WITH + 1.14.6 diff --git a/templates/assets/bootstrap/Gruntfile.js b/templates/assets/bootstrap/Gruntfile.js new file mode 100644 index 0000000..7675e2f --- /dev/null +++ b/templates/assets/bootstrap/Gruntfile.js @@ -0,0 +1,321 @@ +/*! + * Bootstrap's Gruntfile + * https://getbootstrap.com + * Copyright 2013-2017 The Bootstrap Authors + * Copyright 2013-2017 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +module.exports = function (grunt) { + 'use strict' + + // Force use of Unix newlines + grunt.util.linefeed = '\n' + + RegExp.quote = function (string) { + return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&') + } + + var isTravis = require('is-travis') + + // Project configuration. + grunt.initConfig({ + + // Metadata. + pkg: grunt.file.readJSON('package.json'), + banner: '/*!\n' + + ' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' + + ' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' + + ' * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n' + + ' */\n', + jqueryCheck: 'if (typeof jQuery === \'undefined\') {\n' + + ' throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\\'s JavaScript.\')\n' + + '}\n', + jqueryVersionCheck: '+function ($) {\n' + + ' var version = $.fn.jquery.split(\' \')[0].split(\'.\')\n' + + ' if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] >= 4)) {\n' + + ' throw new Error(\'Bootstrap\\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0\')\n' + + ' }\n' + + '}(jQuery);\n\n', + + // Task configuration. + clean: { + dist: 'dist', + docs: 'docs/dist' + }, + + // JS build configuration + babel: { + dev: { + options: { + sourceMap: true + }, + files: { + 'js/dist/util.js' : 'js/src/util.js', + 'js/dist/alert.js' : 'js/src/alert.js', + 'js/dist/button.js' : 'js/src/button.js', + 'js/dist/carousel.js' : 'js/src/carousel.js', + 'js/dist/collapse.js' : 'js/src/collapse.js', + 'js/dist/dropdown.js' : 'js/src/dropdown.js', + 'js/dist/modal.js' : 'js/src/modal.js', + 'js/dist/scrollspy.js' : 'js/src/scrollspy.js', + 'js/dist/tab.js' : 'js/src/tab.js', + 'js/dist/tooltip.js' : 'js/src/tooltip.js', + 'js/dist/popover.js' : 'js/src/popover.js' + } + }, + dist: { + options: { + extends: '../../.babelrc' + }, + files: { + '<%= concat.bootstrap.dest %>' : '<%= concat.bootstrap.dest %>' + } + } + }, + + stamp: { + options: { + banner: '<%= banner %>\n<%= jqueryCheck %>\n<%= jqueryVersionCheck %>\n+function () {\n', + footer: '\n}();' + }, + bootstrap: { + files: { + src: '<%= concat.bootstrap.dest %>' + } + } + }, + + concat: { + options: { + // Custom function to remove all export and import statements + process: function (src) { + return src.replace(/^(export|import).*/gm, '') + } + }, + bootstrap: { + src: [ + 'js/src/util.js', + 'js/src/alert.js', + 'js/src/button.js', + 'js/src/carousel.js', + 'js/src/collapse.js', + 'js/src/dropdown.js', + 'js/src/modal.js', + 'js/src/scrollspy.js', + 'js/src/tab.js', + 'js/src/tooltip.js', + 'js/src/popover.js' + ], + dest: 'dist/js/<%= pkg.name %>.js' + } + }, + + qunit: { + options: { + inject: 'js/tests/unit/phantom.js' + }, + files: 'js/tests/index.html' + }, + + // CSS build configuration + copy: { + docs: { + expand: true, + cwd: 'dist/', + src: [ + '**/*' + ], + dest: 'docs/dist/' + } + }, + + connect: { + server: { + options: { + port: 3000, + base: '.' + } + } + }, + + watch: { + src: { + files: '<%= concat.bootstrap.src %>', + tasks: ['babel:dev'] + }, + sass: { + files: 'scss/**/*.scss', + tasks: ['dist-css', 'docs'] + }, + docs: { + files: 'docs/assets/scss/**/*.scss', + tasks: ['dist-css', 'docs'] + } + }, + + 'saucelabs-qunit': { + all: { + options: { + build: process.env.TRAVIS_JOB_ID, + concurrency: 10, + maxRetries: 3, + maxPollRetries: 4, + urls: ['http://127.0.0.1:3000/js/tests/index.html?hidepassed'], + browsers: grunt.file.readYAML('grunt/sauce_browsers.yml') + } + } + }, + + exec: { + 'clean-css': { + command: 'npm run clean-css' + }, + 'clean-css-docs': { + command: 'npm run clean-css-docs' + }, + postcss: { + command: 'npm run postcss' + }, + 'postcss-docs': { + command: 'npm run postcss-docs' + }, + htmlhint: { + command: 'npm run htmlhint' + }, + htmllint: { + command: 'npm run htmllint' + }, + jekyll: { + command: 'npm run jekyll' + }, + 'jekyll-github': { + command: 'npm run jekyll-github' + }, + sass: { + command: 'npm run sass' + }, + 'sass-docs': { + command: 'npm run sass-docs' + }, + 'scss-lint': { + command: 'npm run scss-lint' + }, + 'scss-lint-docs': { + command: 'npm run scss-lint-docs' + }, + uglify: { + command: 'npm run uglify' + }, + 'uglify-docs': { + command: 'npm run uglify-docs' + } + }, + + buildcontrol: { + options: { + dir: '_gh_pages', + commit: true, + push: true, + message: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%' + }, + pages: { + options: { + remote: 'git@github.com:twbs/derpstrap.git', + branch: 'gh-pages' + } + } + }, + + compress: { + main: { + options: { + archive: 'bootstrap-<%= pkg.version %>-dist.zip', + mode: 'zip', + level: 9, + pretty: true + }, + files: [ + { + expand: true, + cwd: 'dist/', + src: ['**'], + dest: 'bootstrap-<%= pkg.version %>-dist' + } + ] + } + } + + }) + + + // These plugins provide necessary tasks. + require('load-grunt-tasks')(grunt) + require('time-grunt')(grunt) + + // Docs HTML validation task + grunt.registerTask('validate-html', ['exec:jekyll', 'exec:htmllint', 'exec:htmlhint']) + + var runSubset = function (subset) { + return !process.env.TWBS_TEST || process.env.TWBS_TEST === subset + } + var isUndefOrNonZero = function (val) { + return val === undefined || val !== '0' + } + + // Test task. + var testSubtasks = [] + // Skip core tests if running a different subset of the test suite + if (runSubset('core') && + // Skip core tests if this is a Savage build + process.env.TRAVIS_REPO_SLUG !== 'twbs-savage/bootstrap') { + testSubtasks = testSubtasks.concat(['dist-css', 'dist-js', 'test-scss', 'qunit', 'docs']) + } + // Skip HTML validation if running a different subset of the test suite + if (runSubset('validate-html') && + isTravis && + // Skip HTML5 validator when [skip validator] is in the commit message + isUndefOrNonZero(process.env.TWBS_DO_VALIDATOR)) { + testSubtasks.push('validate-html') + } + // Only run Sauce Labs tests if there's a Sauce access key + if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' && + // Skip Sauce if running a different subset of the test suite + runSubset('sauce-js-unit')) { + testSubtasks = testSubtasks.concat(['dist', 'docs-css', 'docs-js', 'clean:docs', 'copy:docs']) + // Skip Sauce on Travis when [skip sauce] is in the commit message + if (isUndefOrNonZero(process.env.TWBS_DO_SAUCE)) { + testSubtasks.push('connect') + testSubtasks.push('saucelabs-qunit') + } + } + grunt.registerTask('test', testSubtasks) + + // JS distribution task. + grunt.registerTask('dist-js', ['babel:dev', 'concat', 'babel:dist', 'stamp', 'exec:uglify']) + + grunt.registerTask('test-scss', ['exec:scss-lint']) + + // CSS distribution task. + grunt.registerTask('sass-compile', ['exec:sass', 'exec:sass-docs']) + + grunt.registerTask('dist-css', ['sass-compile', 'exec:postcss', 'exec:clean-css', 'exec:clean-css-docs']) + + // Full distribution task. + grunt.registerTask('dist', ['clean:dist', 'dist-css', 'dist-js']) + + // Default task. + grunt.registerTask('default', ['clean:dist', 'test']) + + // Docs task. + grunt.registerTask('docs-css', ['exec:clean-css-docs', 'exec:postcss-docs']) + grunt.registerTask('lint-docs-css', ['exec:scss-lint-docs']) + grunt.registerTask('docs-js', ['exec:uglify-docs']) + grunt.registerTask('docs', ['lint-docs-css', 'docs-css', 'docs-js', 'clean:docs', 'copy:docs']) + grunt.registerTask('docs-github', ['exec:jekyll-github']) + + grunt.registerTask('prep-release', ['dist', 'docs', 'docs-github', 'compress']) + + // Publish to GitHub + grunt.registerTask('publish', ['buildcontrol:pages']) +} diff --git a/templates/assets/bootstrap/ISSUE_TEMPLATE.md b/templates/assets/bootstrap/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..d2a406f --- /dev/null +++ b/templates/assets/bootstrap/ISSUE_TEMPLATE.md @@ -0,0 +1,22 @@ +Before opening an issue: + +- [Search for duplicate or closed issues](https://github.com/twbs/bootstrap/issues?utf8=%E2%9C%93&q=is%3Aissue) +- [Validate](https://validator.w3.org/nu/) and [lint](https://github.com/twbs/bootlint#in-the-browser) any HTML to avoid common problems +- Prepare a [reduced test case](https://css-tricks.com/reduced-test-cases/) for any bugs +- Read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md) + +When asking general "how to" questions: + +- Please do not open an issue here +- Instead, ask for help on [StackOverflow, IRC, or Slack](https://github.com/twbs/bootstrap/blob/master/README.md#community) + +When reporting a bug, include: + +- Operating system and version (Windows, Mac OS X, Android, iOS, Win10 Mobile) +- Browser and version (Chrome, Firefox, Safari, IE, MS Edge, Opera 15+, Android Browser) +- Reduced test cases and potential fixes using [JS Bin](https://jsbin.com) + +When suggesting a feature, include: + +- As much detail as possible for what we should add and why it's important to Bootstrap +- Relevant links to prior art, screenshots, or live demos whenever possible diff --git a/templates/assets/bootstrap/LICENSE b/templates/assets/bootstrap/LICENSE new file mode 100644 index 0000000..1381cb2 --- /dev/null +++ b/templates/assets/bootstrap/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2011-2017 Twitter, Inc. +Copyright (c) 2011-2017 The Bootstrap Authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/templates/assets/bootstrap/README.md b/templates/assets/bootstrap/README.md new file mode 100644 index 0000000..7028798 --- /dev/null +++ b/templates/assets/bootstrap/README.md @@ -0,0 +1,149 @@ +<p align="center"> + <a href="https://v4-alpha.getbootstrap.com"> + <img src="http://v4-alpha.getbootstrap.com/assets/brand/bootstrap-solid.svg" width=72 height=72> + </a> + + <h3 align="center">Bootstrap</h3> + + <p align="center"> + Sleek, intuitive, and powerful front-end framework for faster and easier web development. + <br> + <a href="https://v4-alpha.getbootstrap.com"><strong>Visit Bootstrap »</strong></a> + </p> +</p> + +<br> + +## Table of contents + +- [Quick start](#quick-start) +- [Status](#status) +- [What's included](#whats-included) +- [Bugs and feature requests](#bugs-and-feature-requests) +- [Documentation](#documentation) +- [Contributing](#contributing) +- [Community](#community) +- [Versioning](#versioning) +- [Creators](#creators) +- [Copyright and license](#copyright-and-license) + +## Quick start + +Several quick start options are available: + +- [Download the latest release.](https://github.com/twbs/bootstrap/archive/v4.0.0-alpha.6.zip) +- Clone the repo: `git clone https://github.com/twbs/bootstrap.git` +- Install with [npm](https://www.npmjs.com): `npm install bootstrap@4.0.0-alpha.6` +- Install with [yarn](https://github.com/yarnpkg/yarn): `yarn add bootstrap@4.0.0-alpha.6` +- Install with [Composer](https://getcomposer.org): `composer require twbs/bootstrap:4.0.0-alpha.6` +- Install with [Bower](https://bower.io): `bower install bootstrap#v4.0.0-alpha.6` +- Install with [NuGet](https://www.nuget.org): CSS: `Install-Package bootstrap -Pre` Sass: `Install-Package bootstrap.sass -Pre` (`-Pre` is only required until Bootstrap v4 has a stable release). + +Read the [Getting started page](https://getbootstrap.com/getting-started/) for information on the framework contents, templates and examples, and more. + +## Status + +[](https://bootstrap-slack.herokuapp.com) + +[](https://www.npmjs.com/package/bootstrap) +[](https://rubygems.org/gems/bootstrap) +[](https://travis-ci.org/twbs/bootstrap) +[](https://david-dm.org/twbs/bootstrap?type=dev) +[](https://atmospherejs.com/twbs/bootstrap) +[](https://packagist.org/packages/twbs/bootstrap) +[](https://www.nuget.org/packages/bootstrap/4.0.0-alpha5) + +[](https://saucelabs.com/u/bootstrap) + +## What's included + +Within the download you'll find the following directories and files, logically grouping common assets and providing both compiled and minified variations. You'll see something like this: + +``` +bootstrap/ +├── css/ +│ ├── bootstrap.css +│ ├── bootstrap.css.map +│ ├── bootstrap.min.css +│ └── bootstrap.min.css.map +└── js/ + ├── bootstrap.js + └── bootstrap.min.js +``` + +We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). CSS [source maps](https://developers.google.com/web/tools/chrome-devtools/debug/readability/source-maps) (`bootstrap.*.map`) are available for use with certain browsers' developer tools. + + +## Bugs and feature requests + +Have a bug or a feature request? Please first read the [issue guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md#using-the-issue-tracker) and search for existing and closed issues. If your problem or idea is not addressed yet, [please open a new issue](https://github.com/twbs/bootstrap/issues/new). + + +## Documentation + +Bootstrap's documentation, included in this repo in the root directory, is built with [Jekyll](https://jekyllrb.com) and publicly hosted on GitHub Pages at <https://getbootstrap.com>. The docs may also be run locally. + +### Running documentation locally + +1. Run through the [tooling setup](https://github.com/twbs/bootstrap/blob/v4-dev/docs/getting-started/build-tools.md#tooling-setup) to install Jekyll (the site builder) and other Ruby dependencies with `bundle install`. +2. Run `grunt` (or a specific set of Grunt tasks) to rebuild distributed CSS and JavaScript files, as well as our docs assets. +3. From the root `/bootstrap` directory, run `bundle exec jekyll serve` in the command line. +4. Open <http://localhost:9001> in your browser, and voilà . + +Learn more about using Jekyll by reading its [documentation](https://jekyllrb.com/docs/home/). + +### Documentation for previous releases + +Documentation for v2.3.2 has been made available for the time being at <https://getbootstrap.com/2.3.2/> while folks transition to Bootstrap 3. + +[Previous releases](https://github.com/twbs/bootstrap/releases) and their documentation are also available for download. + + + +## Contributing + +Please read through our [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md). Included are directions for opening issues, coding standards, and notes on development. + +Moreover, if your pull request contains JavaScript patches or features, you must include [relevant unit tests](https://github.com/twbs/bootstrap/tree/master/js/tests). All HTML and CSS should conform to the [Code Guide](https://github.com/mdo/code-guide), maintained by [Mark Otto](https://github.com/mdo). + +Editor preferences are available in the [editor config](https://github.com/twbs/bootstrap/blob/master/.editorconfig) for easy use in common text editors. Read more and download plugins at <http://editorconfig.org>. + + + +## Community + +Get updates on Bootstrap's development and chat with the project maintainers and community members. + +- Follow [@getbootstrap on Twitter](https://twitter.com/getbootstrap). +- Read and subscribe to [The Official Bootstrap Blog](https://blog.getbootstrap.com). +- Join [the official Slack room](https://bootstrap-slack.herokuapp.com). +- Chat with fellow Bootstrappers in IRC. On the `irc.freenode.net` server, in the `##bootstrap` channel. +- Implementation help may be found at Stack Overflow (tagged [`bootstrap-4`](https://stackoverflow.com/questions/tagged/bootstrap-4)). +- Developers should use the keyword `bootstrap` on packages which modify or add to the functionality of Bootstrap when distributing through [npm](https://www.npmjs.com/browse/keyword/bootstrap) or similar delivery mechanisms for maximum discoverability. + + + +## Versioning + +For transparency into our release cycle and in striving to maintain backward compatibility, Bootstrap is maintained under [the Semantic Versioning guidelines](http://semver.org/). Sometimes we screw up, but we'll adhere to those rules whenever possible. + +See [the Releases section of our GitHub project](https://github.com/twbs/bootstrap/releases) for changelogs for each release version of Bootstrap. Release announcement posts on [the official Bootstrap blog](https://blog.getbootstrap.com) contain summaries of the most noteworthy changes made in each release. + + +## Creators + +**Mark Otto** + +- <https://twitter.com/mdo> +- <https://github.com/mdo> + +**Jacob Thornton** + +- <https://twitter.com/fat> +- <https://github.com/fat> + + + +## Copyright and license + +Code and documentation copyright 2011-2017 the [Bootstrap Authors](https://github.com/twbs/bootstrap/graphs/contributors) and [Twitter, Inc.](https://twitter.com) Code released under the [MIT License](https://github.com/twbs/bootstrap/blob/master/LICENSE). Docs released under [Creative Commons](https://github.com/twbs/bootstrap/blob/master/docs/LICENSE). diff --git a/templates/assets/bootstrap/bower.json b/templates/assets/bootstrap/bower.json new file mode 100644 index 0000000..5107709 --- /dev/null +++ b/templates/assets/bootstrap/bower.json @@ -0,0 +1,35 @@ +{ + "name": "bootstrap", + "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", + "keywords": [ + "css", + "js", + "sass", + "mobile-first", + "responsive", + "front-end", + "framework", + "web" + ], + "homepage": "https://getbootstrap.com", + "license": "MIT", + "moduleType": "globals", + "main": [ + "scss/bootstrap.scss", + "dist/js/bootstrap.js" + ], + "ignore": [ + "/.*", + "_config.yml", + "CNAME", + "composer.json", + "CONTRIBUTING.md", + "docs", + "js/tests", + "test-infra" + ], + "dependencies": { + "jquery": ">=1.9.1", + "tether": "^1.4.0" + } +} diff --git a/templates/assets/bootstrap/grunt/change-version.js b/templates/assets/bootstrap/grunt/change-version.js new file mode 100755 index 0000000..5ea5918 --- /dev/null +++ b/templates/assets/bootstrap/grunt/change-version.js @@ -0,0 +1,110 @@ +#!/usr/bin/env node + +'use strict' + +/*! + * Script to update version number references in the project. + * Copyright 2017 The Bootstrap Authors + * Copyright 2017 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +/* global Set */ + +var fs = require('fs') +var path = require('path') +var sh = require('shelljs') +sh.config.fatal = true +var sed = sh.sed + +// Blame TC39... https://github.com/benjamingr/RegExp.escape/issues/37 +RegExp.quote = function (string) { + return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&') +} +RegExp.quoteReplacement = function (string) { + return string.replace(/[$]/g, '$$') +} + +var DRY_RUN = false + +function walkAsync(directory, excludedDirectories, fileCallback, errback) { + if (excludedDirectories.has(path.parse(directory).base)) { + return + } + fs.readdir(directory, function (err, names) { + if (err) { + errback(err) + return + } + names.forEach(function (name) { + var filepath = path.join(directory, name) + fs.lstat(filepath, function (err, stats) { + if (err) { + process.nextTick(errback, err) + return + } + if (stats.isSymbolicLink()) { + return + } + else if (stats.isDirectory()) { + process.nextTick(walkAsync, filepath, excludedDirectories, fileCallback, errback) + } + else if (stats.isFile()) { + process.nextTick(fileCallback, filepath) + } + }) + }) + }) +} + +function replaceRecursively(directory, excludedDirectories, allowedExtensions, original, replacement) { + original = new RegExp(RegExp.quote(original), 'g') + replacement = RegExp.quoteReplacement(replacement) + var updateFile = !DRY_RUN ? function (filepath) { + if (allowedExtensions.has(path.parse(filepath).ext)) { + sed('-i', original, replacement, filepath) + } + } : function (filepath) { + if (allowedExtensions.has(path.parse(filepath).ext)) { + console.log('FILE: ' + filepath) + } + else { + console.log('EXCLUDED:' + filepath) + } + } + walkAsync(directory, excludedDirectories, updateFile, function (err) { + console.error('ERROR while traversing directory!:') + console.error(err) + process.exit(1) + }) +} + +function main(args) { + if (args.length !== 2) { + console.error('USAGE: change-version old_version new_version') + console.error('Got arguments:', args) + process.exit(1) + } + var oldVersion = args[0] + var newVersion = args[1] + var EXCLUDED_DIRS = new Set([ + '.git', + 'node_modules', + 'vendor' + ]) + var INCLUDED_EXTENSIONS = new Set([ + // This extension whitelist is how we avoid modifying binary files + '', + '.css', + '.html', + '.js', + '.json', + '.md', + '.scss', + '.txt', + '.yml' + ]) + replaceRecursively('.', EXCLUDED_DIRS, INCLUDED_EXTENSIONS, oldVersion, newVersion) +} + +main(process.argv.slice(2)) diff --git a/templates/assets/bootstrap/grunt/gcp-key.json.enc b/templates/assets/bootstrap/grunt/gcp-key.json.enc Binary files differnew file mode 100644 index 0000000..6e1856a --- /dev/null +++ b/templates/assets/bootstrap/grunt/gcp-key.json.enc diff --git a/templates/assets/bootstrap/grunt/npm-shrinkwrap.json b/templates/assets/bootstrap/grunt/npm-shrinkwrap.json new file mode 100644 index 0000000..f35e330 --- /dev/null +++ b/templates/assets/bootstrap/grunt/npm-shrinkwrap.json @@ -0,0 +1,4164 @@ +{ + "name": "bootstrap", + "version": "4.0.0-alpha.6", + "dependencies": { + "abbrev": { + "version": "1.1.0", + "from": "abbrev@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", + "dev": true + }, + "accepts": { + "version": "1.3.3", + "from": "accepts@>=1.3.3 <1.4.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", + "dev": true + }, + "acorn": { + "version": "4.0.4", + "from": "acorn@4.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.4.tgz", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "from": "acorn-jsx@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "dev": true, + "dependencies": { + "acorn": { + "version": "3.3.0", + "from": "acorn@>=3.0.4 <4.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "dev": true + } + } + }, + "agent-base": { + "version": "2.0.1", + "from": "agent-base@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz", + "dev": true, + "dependencies": { + "semver": { + "version": "5.0.3", + "from": "semver@>=5.0.1 <5.1.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", + "dev": true + } + } + }, + "ajv": { + "version": "4.11.5", + "from": "ajv@>=4.7.0 <5.0.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.5.tgz", + "dev": true + }, + "ajv-keywords": { + "version": "1.5.1", + "from": "ajv-keywords@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "from": "align-text@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "from": "ansi-escapes@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "from": "ansi-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "from": "ansi-styles@>=2.2.1 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "dev": true + }, + "any-promise": { + "version": "1.3.0", + "from": "any-promise@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "dev": true + }, + "anymatch": { + "version": "1.3.0", + "from": "anymatch@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", + "dev": true + }, + "aproba": { + "version": "1.1.1", + "from": "aproba@>=1.0.3 <2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz", + "dev": true + }, + "archiver": { + "version": "1.3.0", + "from": "archiver@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz", + "dev": true, + "dependencies": { + "async": { + "version": "2.1.5", + "from": "async@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz", + "dev": true + } + } + }, + "archiver-utils": { + "version": "1.3.0", + "from": "archiver-utils@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.2", + "from": "are-we-there-yet@>=1.1.2 <1.2.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz", + "dev": true + }, + "argparse": { + "version": "1.0.9", + "from": "argparse@>=1.0.7 <2.0.0", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "dev": true + }, + "arr-diff": { + "version": "2.0.0", + "from": "arr-diff@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "dev": true + }, + "arr-flatten": { + "version": "1.0.1", + "from": "arr-flatten@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.1.tgz", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "from": "array-differ@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "from": "array-find-index@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "from": "array-union@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "dev": true + }, + "array-uniq": { + "version": "1.0.3", + "from": "array-uniq@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "from": "array-unique@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "from": "arrify@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "dev": true + }, + "asap": { + "version": "2.0.5", + "from": "asap@>=2.0.3 <2.1.0", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.5.tgz", + "dev": true + }, + "asn1": { + "version": "0.2.3", + "from": "asn1@>=0.2.3 <0.3.0", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "dev": true + }, + "assert-plus": { + "version": "0.2.0", + "from": "assert-plus@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "dev": true + }, + "async": { + "version": "1.5.2", + "from": "async@>=1.5.2 <1.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "from": "async-each@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "dev": true + }, + "async-foreach": { + "version": "0.1.3", + "from": "async-foreach@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "from": "asynckit@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "dev": true + }, + "autoprefixer": { + "version": "6.7.7", + "from": "autoprefixer@>=6.7.7 <7.0.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", + "dev": true + }, + "aws-sign2": { + "version": "0.6.0", + "from": "aws-sign2@>=0.6.0 <0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "dev": true + }, + "aws4": { + "version": "1.6.0", + "from": "aws4@>=1.2.1 <2.0.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "dev": true + }, + "babel-code-frame": { + "version": "6.22.0", + "from": "babel-code-frame@>=6.16.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", + "dev": true + }, + "babel-core": { + "version": "6.24.0", + "from": "babel-core@>=6.0.12 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.24.0.tgz", + "dev": true + }, + "babel-eslint": { + "version": "7.1.1", + "from": "babel-eslint@>=7.1.1 <8.0.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.1.1.tgz", + "dev": true + }, + "babel-generator": { + "version": "6.24.0", + "from": "babel-generator@>=6.24.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.24.0.tgz", + "dev": true, + "dependencies": { + "jsesc": { + "version": "1.3.0", + "from": "jsesc@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "dev": true + } + } + }, + "babel-helper-call-delegate": { + "version": "6.22.0", + "from": "babel-helper-call-delegate@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.22.0.tgz", + "dev": true + }, + "babel-helper-define-map": { + "version": "6.23.0", + "from": "babel-helper-define-map@>=6.23.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.23.0.tgz", + "dev": true + }, + "babel-helper-function-name": { + "version": "6.23.0", + "from": "babel-helper-function-name@>=6.23.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.23.0.tgz", + "dev": true + }, + "babel-helper-get-function-arity": { + "version": "6.22.0", + "from": "babel-helper-get-function-arity@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.22.0.tgz", + "dev": true + }, + "babel-helper-hoist-variables": { + "version": "6.22.0", + "from": "babel-helper-hoist-variables@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.22.0.tgz", + "dev": true + }, + "babel-helper-optimise-call-expression": { + "version": "6.23.0", + "from": "babel-helper-optimise-call-expression@>=6.23.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.23.0.tgz", + "dev": true + }, + "babel-helper-regex": { + "version": "6.22.0", + "from": "babel-helper-regex@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.22.0.tgz", + "dev": true + }, + "babel-helper-replace-supers": { + "version": "6.23.0", + "from": "babel-helper-replace-supers@>=6.23.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.23.0.tgz", + "dev": true + }, + "babel-helpers": { + "version": "6.23.0", + "from": "babel-helpers@>=6.23.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.23.0.tgz", + "dev": true + }, + "babel-messages": { + "version": "6.23.0", + "from": "babel-messages@>=6.23.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "dev": true + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "from": "babel-plugin-check-es2015-constants@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "from": "babel-plugin-transform-es2015-arrow-functions@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "from": "babel-plugin-transform-es2015-block-scoped-functions@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.23.0", + "from": "babel-plugin-transform-es2015-block-scoping@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.23.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.23.0", + "from": "babel-plugin-transform-es2015-classes@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.23.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.22.0", + "from": "babel-plugin-transform-es2015-computed-properties@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "from": "babel-plugin-transform-es2015-destructuring@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.22.0", + "from": "babel-plugin-transform-es2015-duplicate-keys@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "from": "babel-plugin-transform-es2015-for-of@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.22.0", + "from": "babel-plugin-transform-es2015-function-name@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "from": "babel-plugin-transform-es2015-literals@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.0", + "from": "babel-plugin-transform-es2015-modules-amd@>=6.24.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.24.0", + "from": "babel-plugin-transform-es2015-modules-commonjs@>=6.24.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-modules-strip": { + "version": "0.1.0", + "from": "babel-plugin-transform-es2015-modules-strip@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-strip/-/babel-plugin-transform-es2015-modules-strip-0.1.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.23.0", + "from": "babel-plugin-transform-es2015-modules-systemjs@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.23.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.0", + "from": "babel-plugin-transform-es2015-modules-umd@>=6.24.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.22.0", + "from": "babel-plugin-transform-es2015-object-super@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.23.0", + "from": "babel-plugin-transform-es2015-parameters@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.23.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.22.0", + "from": "babel-plugin-transform-es2015-shorthand-properties@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "from": "babel-plugin-transform-es2015-spread@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.22.0", + "from": "babel-plugin-transform-es2015-sticky-regex@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "from": "babel-plugin-transform-es2015-template-literals@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "from": "babel-plugin-transform-es2015-typeof-symbol@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "dev": true + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.22.0", + "from": "babel-plugin-transform-es2015-unicode-regex@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-regenerator": { + "version": "6.22.0", + "from": "babel-plugin-transform-regenerator@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.22.0.tgz", + "dev": true + }, + "babel-plugin-transform-strict-mode": { + "version": "6.22.0", + "from": "babel-plugin-transform-strict-mode@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.22.0.tgz", + "dev": true + }, + "babel-preset-es2015": { + "version": "6.24.0", + "from": "babel-preset-es2015@>=6.24.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.0.tgz", + "dev": true + }, + "babel-register": { + "version": "6.24.0", + "from": "babel-register@>=6.24.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.0.tgz", + "dev": true + }, + "babel-runtime": { + "version": "6.23.0", + "from": "babel-runtime@>=6.22.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", + "dev": true + }, + "babel-template": { + "version": "6.23.0", + "from": "babel-template@>=6.23.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.23.0.tgz", + "dev": true + }, + "babel-traverse": { + "version": "6.23.1", + "from": "babel-traverse@>=6.15.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.23.1.tgz", + "dev": true + }, + "babel-types": { + "version": "6.23.0", + "from": "babel-types@>=6.15.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.23.0.tgz", + "dev": true + }, + "babylon": { + "version": "6.16.1", + "from": "babylon@>=6.13.0 <7.0.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.16.1.tgz", + "dev": true + }, + "balanced-match": { + "version": "0.4.2", + "from": "balanced-match@>=0.4.1 <0.5.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "dev": true + }, + "basic-auth": { + "version": "1.1.0", + "from": "basic-auth@>=1.1.0 <1.2.0", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", + "dev": true + }, + "batch": { + "version": "0.5.3", + "from": "batch@0.5.3", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.5.3.tgz", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "from": "bcrypt-pbkdf@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "dev": true, + "optional": true + }, + "binary-extensions": { + "version": "1.8.0", + "from": "binary-extensions@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.8.0.tgz", + "dev": true + }, + "bl": { + "version": "1.2.0", + "from": "bl@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.0.tgz", + "dev": true + }, + "block-stream": { + "version": "0.0.9", + "from": "block-stream@*", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "dev": true + }, + "bluebird": { + "version": "3.5.0", + "from": "bluebird@>=3.0.6 <4.0.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "dev": true + }, + "body-parser": { + "version": "1.14.2", + "from": "body-parser@>=1.14.0 <1.15.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz", + "dev": true, + "dependencies": { + "debug": { + "version": "2.2.0", + "from": "debug@>=2.2.0 <2.3.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "dev": true + }, + "http-errors": { + "version": "1.3.1", + "from": "http-errors@>=1.3.1 <1.4.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "dev": true + }, + "iconv-lite": { + "version": "0.4.13", + "from": "iconv-lite@0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "dev": true + }, + "ms": { + "version": "0.7.1", + "from": "ms@0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "dev": true + }, + "qs": { + "version": "5.2.0", + "from": "qs@5.2.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz", + "dev": true + } + } + }, + "boom": { + "version": "2.10.1", + "from": "boom@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "dev": true + }, + "brace-expansion": { + "version": "1.1.6", + "from": "brace-expansion@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", + "dev": true + }, + "braces": { + "version": "1.8.5", + "from": "braces@>=1.8.2 <2.0.0", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "dev": true + }, + "browserslist": { + "version": "1.7.6", + "from": "browserslist@>=1.7.6 <2.0.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.6.tgz", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "from": "buffer-crc32@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "dev": true + }, + "buffer-shims": { + "version": "1.0.0", + "from": "buffer-shims@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "from": "builtin-modules@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "dev": true + }, + "bulk-require": { + "version": "1.0.0", + "from": "bulk-require@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/bulk-require/-/bulk-require-1.0.0.tgz", + "dev": true, + "dependencies": { + "glob": { + "version": "3.2.11", + "from": "glob@>=3.2.7 <3.3.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "dev": true + }, + "minimatch": { + "version": "0.3.0", + "from": "minimatch@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "dev": true + } + } + }, + "bytes": { + "version": "2.2.0", + "from": "bytes@2.2.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", + "dev": true + }, + "caller-path": { + "version": "0.1.0", + "from": "caller-path@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "dev": true + }, + "callsites": { + "version": "0.2.0", + "from": "callsites@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "from": "camelcase@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "from": "camelcase-keys@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "dev": true + }, + "caniuse-db": { + "version": "1.0.30000637", + "from": "caniuse-db@>=1.0.30000634 <2.0.0", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000637.tgz", + "dev": true + }, + "caseless": { + "version": "0.11.0", + "from": "caseless@>=0.11.0 <0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "from": "center-align@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "from": "chalk@>=1.1.3 <2.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "dev": true, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "from": "supports-color@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "dev": true + } + } + }, + "chokidar": { + "version": "1.6.1", + "from": "chokidar@>=1.6.1 <2.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz", + "dev": true + }, + "circular-json": { + "version": "0.3.1", + "from": "circular-json@>=0.3.1 <0.4.0", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz", + "dev": true + }, + "cjson": { + "version": "0.5.0", + "from": "cjson@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.5.0.tgz", + "dev": true + }, + "clean-css": { + "version": "4.0.9", + "from": "clean-css@>=4.0.9 <5.0.0", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.0.9.tgz", + "dev": true + }, + "clean-css-cli": { + "version": "4.0.9", + "from": "clean-css-cli@>=4.0.9 <5.0.0", + "resolved": "https://registry.npmjs.org/clean-css-cli/-/clean-css-cli-4.0.9.tgz", + "dev": true + }, + "cli": { + "version": "0.6.6", + "from": "cli@>=0.6.0 <0.7.0", + "resolved": "https://registry.npmjs.org/cli/-/cli-0.6.6.tgz", + "dev": true, + "dependencies": { + "glob": { + "version": "3.2.11", + "from": "glob@>=3.2.1 <3.3.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "dev": true + }, + "minimatch": { + "version": "0.3.0", + "from": "minimatch@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "dev": true + } + } + }, + "cli-cursor": { + "version": "1.0.2", + "from": "cli-cursor@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "dev": true + }, + "cli-spinners": { + "version": "1.0.0", + "from": "cli-spinners@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.0.0.tgz", + "dev": true + }, + "cli-width": { + "version": "2.1.0", + "from": "cli-width@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "from": "cliui@>=3.2.0 <4.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "dev": true + }, + "co": { + "version": "4.6.0", + "from": "co@>=4.6.0 <5.0.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "from": "code-point-at@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "dev": true + }, + "coffee-script": { + "version": "1.10.0", + "from": "coffee-script@>=1.10.0 <1.11.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.10.0.tgz", + "dev": true + }, + "colors": { + "version": "1.1.2", + "from": "colors@>=1.1.2 <1.2.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "dev": true + }, + "combined-stream": { + "version": "1.0.5", + "from": "combined-stream@>=1.0.5 <1.1.0", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "dev": true + }, + "commander": { + "version": "2.9.0", + "from": "commander@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "dev": true + }, + "compress-commons": { + "version": "1.2.0", + "from": "compress-commons@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.0.tgz", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "dev": true + }, + "concat-stream": { + "version": "1.6.0", + "from": "concat-stream@>=1.5.2 <2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "dev": true + }, + "connect": { + "version": "3.6.0", + "from": "connect@>=3.4.0 <4.0.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.0.tgz", + "dev": true, + "dependencies": { + "debug": { + "version": "2.6.1", + "from": "debug@2.6.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.1.tgz", + "dev": true + } + } + }, + "connect-livereload": { + "version": "0.5.4", + "from": "connect-livereload@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.5.4.tgz", + "dev": true + }, + "console-browserify": { + "version": "1.1.0", + "from": "console-browserify@>=1.1.0 <1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "from": "console-control-strings@>=1.1.0 <1.2.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "dev": true + }, + "content-type": { + "version": "1.0.2", + "from": "content-type@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", + "dev": true + }, + "convert-source-map": { + "version": "1.4.0", + "from": "convert-source-map@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.4.0.tgz", + "dev": true + }, + "core-js": { + "version": "2.4.1", + "from": "core-js@>=2.4.0 <3.0.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "dev": true + }, + "cosmiconfig": { + "version": "2.1.1", + "from": "cosmiconfig@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.1.1.tgz", + "dev": true, + "dependencies": { + "minimist": { + "version": "1.2.0", + "from": "minimist@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "dev": true + } + } + }, + "crc": { + "version": "3.4.4", + "from": "crc@>=3.4.4 <4.0.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz", + "dev": true + }, + "crc32-stream": { + "version": "2.0.0", + "from": "crc32-stream@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "dev": true + }, + "cross-spawn": { + "version": "3.0.1", + "from": "cross-spawn@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "dev": true, + "dependencies": { + "lru-cache": { + "version": "4.0.2", + "from": "lru-cache@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "dev": true + } + } + }, + "cryptiles": { + "version": "2.0.5", + "from": "cryptiles@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "dev": true + }, + "csslint": { + "version": "0.10.0", + "from": "csslint@0.10.0", + "resolved": "https://registry.npmjs.org/csslint/-/csslint-0.10.0.tgz", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "from": "currently-unhandled@>=0.4.1 <0.5.0", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "dev": true + }, + "d": { + "version": "1.0.0", + "from": "d@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "from": "dashdash@>=1.12.0 <2.0.0", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "dev": true, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "dev": true + } + } + }, + "date-now": { + "version": "0.1.4", + "from": "date-now@>=0.1.4 <0.2.0", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "dev": true + }, + "date-time": { + "version": "1.1.0", + "from": "date-time@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-1.1.0.tgz", + "dev": true + }, + "dateformat": { + "version": "1.0.12", + "from": "dateformat@>=1.0.12 <1.1.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "dev": true + }, + "debug": { + "version": "2.6.3", + "from": "debug@>=2.2.0 <3.0.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.3.tgz", + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "from": "decamelize@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "from": "deep-is@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "dev": true + }, + "del": { + "version": "2.2.2", + "from": "del@>=2.0.2 <3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "from": "delayed-stream@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "from": "delegates@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "dev": true + }, + "depd": { + "version": "1.1.0", + "from": "depd@>=1.1.0 <1.2.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz", + "dev": true + }, + "destroy": { + "version": "1.0.4", + "from": "destroy@>=1.0.4 <1.1.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "dev": true + }, + "detect-file": { + "version": "0.1.0", + "from": "detect-file@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "from": "detect-indent@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "dev": true + }, + "doctrine": { + "version": "2.0.0", + "from": "doctrine@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "dev": true + }, + "dom-serializer": { + "version": "0.1.0", + "from": "dom-serializer@>=0.0.0 <1.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "dev": true, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "from": "domelementtype@>=1.1.1 <1.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "dev": true + }, + "entities": { + "version": "1.1.1", + "from": "entities@>=1.1.1 <1.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.0", + "from": "domelementtype@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "dev": true + }, + "domhandler": { + "version": "2.3.0", + "from": "domhandler@>=2.3.0 <2.4.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "dev": true + }, + "domutils": { + "version": "1.5.1", + "from": "domutils@>=1.5.0 <1.6.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "from": "ecc-jsbn@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "dev": true, + "optional": true + }, + "ee-first": { + "version": "1.1.1", + "from": "ee-first@1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "dev": true + }, + "electron-to-chromium": { + "version": "1.2.7", + "from": "electron-to-chromium@>=1.2.5 <2.0.0", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.2.7.tgz", + "dev": true + }, + "encodeurl": { + "version": "1.0.1", + "from": "encodeurl@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "dev": true + }, + "end-of-stream": { + "version": "1.4.0", + "from": "end-of-stream@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", + "dev": true + }, + "entities": { + "version": "1.0.0", + "from": "entities@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "dev": true + }, + "error-ex": { + "version": "1.3.1", + "from": "error-ex@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "dev": true + }, + "es5-ext": { + "version": "0.10.14", + "from": "es5-ext@>=0.10.14 <0.11.0", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.14.tgz", + "dev": true + }, + "es6-iterator": { + "version": "2.0.1", + "from": "es6-iterator@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "dev": true + }, + "es6-map": { + "version": "0.1.5", + "from": "es6-map@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "dev": true + }, + "es6-object-assign": { + "version": "1.1.0", + "from": "es6-object-assign@>=1.0.3 <2.0.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "dev": true + }, + "es6-promise": { + "version": "4.0.5", + "from": "es6-promise@>=4.0.3 <4.1.0", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz", + "dev": true + }, + "es6-set": { + "version": "0.1.5", + "from": "es6-set@>=0.1.5 <0.2.0", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "dev": true + }, + "es6-symbol": { + "version": "3.1.1", + "from": "es6-symbol@>=3.1.1 <3.2.0", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "dev": true + }, + "es6-weak-map": { + "version": "2.0.2", + "from": "es6-weak-map@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "from": "escape-html@>=1.0.3 <1.1.0", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "from": "escape-string-regexp@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "dev": true + }, + "escope": { + "version": "3.6.0", + "from": "escope@>=3.6.0 <4.0.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "dev": true + }, + "eslint": { + "version": "3.18.0", + "from": "eslint@>=3.18.0 <4.0.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.18.0.tgz", + "dev": true + }, + "espree": { + "version": "3.4.0", + "from": "espree@>=3.4.0 <4.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.4.0.tgz", + "dev": true + }, + "esprima": { + "version": "3.1.3", + "from": "esprima@>=3.1.1 <4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "dev": true + }, + "esquery": { + "version": "1.0.0", + "from": "esquery@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "dev": true + }, + "esrecurse": { + "version": "4.1.0", + "from": "esrecurse@>=4.1.0 <5.0.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz", + "dev": true, + "dependencies": { + "estraverse": { + "version": "4.1.1", + "from": "estraverse@>=4.1.0 <4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz", + "dev": true + } + } + }, + "estraverse": { + "version": "4.2.0", + "from": "estraverse@>=4.2.0 <5.0.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "from": "esutils@>=2.0.2 <3.0.0", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "dev": true + }, + "etag": { + "version": "1.8.0", + "from": "etag@>=1.8.0 <1.9.0", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "from": "event-emitter@>=0.3.5 <0.4.0", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "dev": true + }, + "eventemitter2": { + "version": "0.4.14", + "from": "eventemitter2@>=0.4.13 <0.5.0", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "dev": true + }, + "exit": { + "version": "0.1.2", + "from": "exit@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "dev": true + }, + "exit-hook": { + "version": "1.1.1", + "from": "exit-hook@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "from": "expand-brackets@>=0.1.4 <0.2.0", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "dev": true + }, + "expand-range": { + "version": "1.8.2", + "from": "expand-range@>=1.8.1 <2.0.0", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "dev": true + }, + "expand-tilde": { + "version": "1.2.2", + "from": "expand-tilde@>=1.2.2 <2.0.0", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "dev": true + }, + "extend": { + "version": "3.0.0", + "from": "extend@>=3.0.0 <3.1.0", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", + "dev": true + }, + "extglob": { + "version": "0.3.2", + "from": "extglob@>=0.3.1 <0.4.0", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "dev": true + }, + "extract-zip": { + "version": "1.5.0", + "from": "extract-zip@>=1.5.0 <1.6.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.5.0.tgz", + "dev": true, + "dependencies": { + "concat-stream": { + "version": "1.5.0", + "from": "concat-stream@1.5.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.0.tgz", + "dev": true + }, + "debug": { + "version": "0.7.4", + "from": "debug@0.7.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", + "dev": true + }, + "mkdirp": { + "version": "0.5.0", + "from": "mkdirp@0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "dev": true + }, + "readable-stream": { + "version": "2.0.6", + "from": "readable-stream@>=2.0.0 <2.1.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "dev": true + } + } + }, + "extsprintf": { + "version": "1.0.2", + "from": "extsprintf@1.0.2", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "from": "fast-levenshtein@>=2.0.4 <2.1.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "dev": true + }, + "faye-websocket": { + "version": "0.10.0", + "from": "faye-websocket@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "dev": true + }, + "fd-slicer": { + "version": "1.0.1", + "from": "fd-slicer@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "dev": true + }, + "fg-lodash": { + "version": "0.0.2", + "from": "fg-lodash@0.0.2", + "resolved": "https://registry.npmjs.org/fg-lodash/-/fg-lodash-0.0.2.tgz", + "dev": true, + "dependencies": { + "lodash": { + "version": "2.4.2", + "from": "lodash@>=2.4.1 <3.0.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "dev": true + }, + "underscore.string": { + "version": "2.3.3", + "from": "underscore.string@>=2.3.3 <2.4.0", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", + "dev": true + } + } + }, + "figures": { + "version": "1.7.0", + "from": "figures@>=1.3.5 <2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "dev": true + }, + "file-entry-cache": { + "version": "2.0.0", + "from": "file-entry-cache@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "dev": true + }, + "file-sync-cmp": { + "version": "0.1.1", + "from": "file-sync-cmp@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz", + "dev": true + }, + "filename-regex": { + "version": "2.0.0", + "from": "filename-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.0.tgz", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "from": "fill-range@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "dev": true + }, + "finalhandler": { + "version": "1.0.0", + "from": "finalhandler@1.0.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.0.tgz", + "dev": true, + "dependencies": { + "debug": { + "version": "2.6.1", + "from": "debug@2.6.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.1.tgz", + "dev": true + } + } + }, + "find-up": { + "version": "1.1.2", + "from": "find-up@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "dev": true + }, + "findup-sync": { + "version": "0.3.0", + "from": "findup-sync@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "dev": true, + "dependencies": { + "glob": { + "version": "5.0.15", + "from": "glob@>=5.0.0 <5.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "dev": true + } + } + }, + "fined": { + "version": "1.0.2", + "from": "fined@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.0.2.tgz", + "dev": true + }, + "flagged-respawn": { + "version": "0.3.2", + "from": "flagged-respawn@>=0.3.2 <0.4.0", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", + "dev": true + }, + "flat-cache": { + "version": "1.2.2", + "from": "flat-cache@>=1.2.1 <2.0.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "from": "for-in@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "from": "for-own@>=0.1.4 <0.2.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "from": "forever-agent@>=0.6.1 <0.7.0", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "dev": true + }, + "form-data": { + "version": "2.1.2", + "from": "form-data@>=2.1.1 <2.2.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz", + "dev": true + }, + "fresh": { + "version": "0.5.0", + "from": "fresh@0.5.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz", + "dev": true + }, + "fs-exists-sync": { + "version": "0.1.0", + "from": "fs-exists-sync@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "dev": true + }, + "fs-extra": { + "version": "1.0.0", + "from": "fs-extra@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "dev": true + }, + "fs-promise": { + "version": "1.0.0", + "from": "fs-promise@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-1.0.0.tgz", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "from": "fs.realpath@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "dev": true + }, + "fstream": { + "version": "1.0.11", + "from": "fstream@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "dev": true + }, + "gauge": { + "version": "2.7.3", + "from": "gauge@>=2.7.1 <2.8.0", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.3.tgz", + "dev": true + }, + "gaze": { + "version": "1.1.2", + "from": "gaze@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", + "dev": true + }, + "generate-function": { + "version": "2.0.0", + "from": "generate-function@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "from": "generate-object-property@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "dev": true + }, + "get-caller-file": { + "version": "1.0.2", + "from": "get-caller-file@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "from": "get-stdin@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "dev": true + }, + "getobject": { + "version": "0.1.0", + "from": "getobject@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", + "dev": true + }, + "getpass": { + "version": "0.1.6", + "from": "getpass@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", + "dev": true, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "dev": true + } + } + }, + "glob": { + "version": "7.1.1", + "from": "glob@>=7.0.3 <8.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "dev": true + }, + "glob-base": { + "version": "0.3.0", + "from": "glob-base@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "dev": true + }, + "glob-parent": { + "version": "2.0.0", + "from": "glob-parent@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "dev": true + }, + "global-modules": { + "version": "0.2.3", + "from": "global-modules@>=0.2.3 <0.3.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "dev": true + }, + "global-prefix": { + "version": "0.1.5", + "from": "global-prefix@>=0.1.4 <0.2.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "dev": true + }, + "globals": { + "version": "9.16.0", + "from": "globals@>=9.0.0 <10.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.16.0.tgz", + "dev": true + }, + "globby": { + "version": "5.0.0", + "from": "globby@>=5.0.0 <6.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "dev": true + }, + "globule": { + "version": "1.1.0", + "from": "globule@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.1.0.tgz", + "dev": true, + "dependencies": { + "lodash": { + "version": "4.16.6", + "from": "lodash@>=4.16.4 <4.17.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.16.6.tgz", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "from": "graceful-fs@>=4.1.2 <5.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "dev": true + }, + "graceful-readlink": { + "version": "1.0.1", + "from": "graceful-readlink@>=1.0.0", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "dev": true + }, + "grunt": { + "version": "1.0.1", + "from": "grunt@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.1.tgz", + "dev": true, + "dependencies": { + "esprima": { + "version": "2.7.3", + "from": "esprima@>=2.6.0 <3.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "dev": true + }, + "glob": { + "version": "7.0.6", + "from": "glob@>=7.0.0 <7.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "dev": true + }, + "grunt-cli": { + "version": "1.2.0", + "from": "grunt-cli@>=1.2.0 <1.3.0", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", + "dev": true + }, + "js-yaml": { + "version": "3.5.5", + "from": "js-yaml@>=3.5.2 <3.6.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "from": "resolve@>=1.1.0 <1.2.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "dev": true + }, + "rimraf": { + "version": "2.2.8", + "from": "rimraf@>=2.2.8 <2.3.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "dev": true + } + } + }, + "grunt-babel": { + "version": "6.0.0", + "from": "grunt-babel@>=6.0.0 <7.0.0", + "resolved": "https://registry.npmjs.org/grunt-babel/-/grunt-babel-6.0.0.tgz", + "dev": true + }, + "grunt-build-control": { + "version": "0.7.1", + "from": "grunt-build-control@>=0.7.1 <0.8.0", + "resolved": "https://registry.npmjs.org/grunt-build-control/-/grunt-build-control-0.7.1.tgz", + "dev": true, + "dependencies": { + "semver": { + "version": "4.3.6", + "from": "semver@>=4.3.3 <4.4.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "dev": true + }, + "shelljs": { + "version": "0.2.6", + "from": "shelljs@>=0.2.6 <0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.2.6.tgz", + "dev": true + } + } + }, + "grunt-contrib-clean": { + "version": "1.0.0", + "from": "grunt-contrib-clean@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-1.0.0.tgz", + "dev": true + }, + "grunt-contrib-compress": { + "version": "1.4.1", + "from": "grunt-contrib-compress@>=1.4.1 <2.0.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-compress/-/grunt-contrib-compress-1.4.1.tgz", + "dev": true + }, + "grunt-contrib-concat": { + "version": "1.0.1", + "from": "grunt-contrib-concat@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-1.0.1.tgz", + "dev": true + }, + "grunt-contrib-connect": { + "version": "1.0.2", + "from": "grunt-contrib-connect@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-connect/-/grunt-contrib-connect-1.0.2.tgz", + "dev": true + }, + "grunt-contrib-copy": { + "version": "1.0.0", + "from": "grunt-contrib-copy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz", + "dev": true + }, + "grunt-contrib-qunit": { + "version": "1.3.0", + "from": "grunt-contrib-qunit@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-1.3.0.tgz", + "dev": true + }, + "grunt-contrib-watch": { + "version": "1.0.0", + "from": "grunt-contrib-watch@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.0.0.tgz", + "dev": true, + "dependencies": { + "lodash": { + "version": "3.10.1", + "from": "lodash@>=3.10.1 <4.0.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "dev": true + } + } + }, + "grunt-exec": { + "version": "2.0.0", + "from": "grunt-exec@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/grunt-exec/-/grunt-exec-2.0.0.tgz", + "dev": true + }, + "grunt-known-options": { + "version": "1.1.0", + "from": "grunt-known-options@>=1.1.0 <1.2.0", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.0.tgz", + "dev": true + }, + "grunt-legacy-log": { + "version": "1.0.0", + "from": "grunt-legacy-log@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-1.0.0.tgz", + "dev": true, + "dependencies": { + "lodash": { + "version": "3.10.1", + "from": "lodash@>=3.10.1 <3.11.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "dev": true + } + } + }, + "grunt-legacy-log-utils": { + "version": "1.0.0", + "from": "grunt-legacy-log-utils@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-1.0.0.tgz", + "dev": true, + "dependencies": { + "lodash": { + "version": "4.3.0", + "from": "lodash@>=4.3.0 <4.4.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz", + "dev": true + } + } + }, + "grunt-legacy-util": { + "version": "1.0.0", + "from": "grunt-legacy-util@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.0.0.tgz", + "dev": true, + "dependencies": { + "lodash": { + "version": "4.3.0", + "from": "lodash@>=4.3.0 <4.4.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz", + "dev": true + } + } + }, + "grunt-lib-phantomjs": { + "version": "1.1.0", + "from": "grunt-lib-phantomjs@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/grunt-lib-phantomjs/-/grunt-lib-phantomjs-1.1.0.tgz", + "dev": true + }, + "grunt-saucelabs": { + "version": "9.0.0", + "from": "grunt-saucelabs@>=9.0.0 <10.0.0", + "resolved": "https://registry.npmjs.org/grunt-saucelabs/-/grunt-saucelabs-9.0.0.tgz", + "dev": true, + "dependencies": { + "lodash": { + "version": "4.13.1", + "from": "lodash@>=4.13.1 <4.14.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz", + "dev": true + } + } + }, + "grunt-stamp": { + "version": "0.3.0", + "from": "grunt-stamp@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/grunt-stamp/-/grunt-stamp-0.3.0.tgz", + "dev": true + }, + "har-validator": { + "version": "2.0.6", + "from": "har-validator@>=2.0.6 <2.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "from": "has-ansi@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "dev": true + }, + "has-flag": { + "version": "1.0.0", + "from": "has-flag@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "from": "has-unicode@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "dev": true + }, + "hasha": { + "version": "2.2.0", + "from": "hasha@>=2.2.0 <2.3.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", + "dev": true + }, + "hawk": { + "version": "3.1.3", + "from": "hawk@>=3.1.3 <3.2.0", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "dev": true + }, + "hoek": { + "version": "2.16.3", + "from": "hoek@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "dev": true + }, + "home-or-tmp": { + "version": "2.0.0", + "from": "home-or-tmp@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "dev": true + }, + "homedir-polyfill": { + "version": "1.0.1", + "from": "homedir-polyfill@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "dev": true + }, + "hooker": { + "version": "0.2.3", + "from": "hooker@>=0.2.3 <0.3.0", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "dev": true + }, + "hosted-git-info": { + "version": "2.3.1", + "from": "hosted-git-info@>=2.1.4 <3.0.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.3.1.tgz", + "dev": true + }, + "htmlhint": { + "version": "0.9.13", + "from": "htmlhint@>=0.9.13 <0.10.0", + "resolved": "https://registry.npmjs.org/htmlhint/-/htmlhint-0.9.13.tgz", + "dev": true, + "dependencies": { + "async": { + "version": "1.4.2", + "from": "async@1.4.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.4.2.tgz", + "dev": true + }, + "colors": { + "version": "1.0.3", + "from": "colors@1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "dev": true + }, + "commander": { + "version": "2.6.0", + "from": "commander@2.6.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz", + "dev": true + }, + "glob": { + "version": "5.0.15", + "from": "glob@5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "dev": true + }, + "strip-json-comments": { + "version": "1.0.4", + "from": "strip-json-comments@1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "dev": true + } + } + }, + "htmllint": { + "version": "0.6.0", + "from": "htmllint@>=0.6.0 <0.7.0", + "resolved": "https://registry.npmjs.org/htmllint/-/htmllint-0.6.0.tgz", + "dev": true + }, + "htmllint-cli": { + "version": "0.0.6", + "from": "htmllint-cli@>=0.0.6 <0.0.7", + "resolved": "https://registry.npmjs.org/htmllint-cli/-/htmllint-cli-0.0.6.tgz", + "dev": true + }, + "htmlparser2": { + "version": "3.8.3", + "from": "htmlparser2@>=3.8.0 <3.9.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "dev": true, + "dependencies": { + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "from": "readable-stream@>=1.1.0 <1.2.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "dev": true + } + } + }, + "http-errors": { + "version": "1.5.1", + "from": "http-errors@>=1.5.0 <1.6.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz", + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "from": "http-signature@>=1.1.0 <1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "dev": true + }, + "http2": { + "version": "3.3.6", + "from": "http2@>=3.3.4 <4.0.0", + "resolved": "https://registry.npmjs.org/http2/-/http2-3.3.6.tgz", + "dev": true + }, + "https-proxy-agent": { + "version": "1.0.0", + "from": "https-proxy-agent@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", + "dev": true + }, + "iconv-lite": { + "version": "0.4.15", + "from": "iconv-lite@>=0.4.13 <0.5.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", + "dev": true + }, + "ignore": { + "version": "3.2.6", + "from": "ignore@>=3.2.0 <4.0.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.2.6.tgz", + "dev": true + }, + "iltorb": { + "version": "1.0.13", + "from": "iltorb@>=1.0.13 <2.0.0", + "resolved": "https://registry.npmjs.org/iltorb/-/iltorb-1.0.13.tgz", + "dev": true, + "optional": true + }, + "imurmurhash": { + "version": "0.1.4", + "from": "imurmurhash@>=0.1.4 <0.2.0", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "dev": true + }, + "in-publish": { + "version": "2.0.0", + "from": "in-publish@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "from": "indent-string@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "from": "inflight@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "from": "inherits@>=2.0.3 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "dev": true + }, + "ini": { + "version": "1.3.4", + "from": "ini@>=1.3.4 <2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "dev": true + }, + "inquirer": { + "version": "0.12.0", + "from": "inquirer@>=0.12.0 <0.13.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "dev": true + }, + "interpret": { + "version": "1.0.1", + "from": "interpret@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.1.tgz", + "dev": true + }, + "invariant": { + "version": "2.2.2", + "from": "invariant@>=2.2.0 <3.0.0", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "from": "invert-kv@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "dev": true + }, + "is-absolute": { + "version": "0.2.6", + "from": "is-absolute@>=0.2.3 <0.3.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "from": "is-arrayish@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "from": "is-binary-path@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "dev": true + }, + "is-buffer": { + "version": "1.1.5", + "from": "is-buffer@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "from": "is-builtin-module@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "dev": true + }, + "is-dotfile": { + "version": "1.0.2", + "from": "is-dotfile@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "from": "is-equal-shallow@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "from": "is-extendable@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "from": "is-extglob@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "from": "is-finite@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "from": "is-fullwidth-code-point@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "from": "is-glob@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "dev": true + }, + "is-my-json-valid": { + "version": "2.16.0", + "from": "is-my-json-valid@>=2.10.0 <3.0.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", + "dev": true + }, + "is-number": { + "version": "2.1.0", + "from": "is-number@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "dev": true + }, + "is-path-cwd": { + "version": "1.0.0", + "from": "is-path-cwd@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "from": "is-path-in-cwd@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "dev": true + }, + "is-path-inside": { + "version": "1.0.0", + "from": "is-path-inside@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "dev": true + }, + "is-posix-bracket": { + "version": "0.1.1", + "from": "is-posix-bracket@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "from": "is-primitive@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "dev": true + }, + "is-property": { + "version": "1.0.2", + "from": "is-property@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "dev": true + }, + "is-relative": { + "version": "0.2.1", + "from": "is-relative@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", + "dev": true + }, + "is-resolvable": { + "version": "1.0.0", + "from": "is-resolvable@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "from": "is-stream@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "dev": true + }, + "is-travis": { + "version": "1.0.0", + "from": "is-travis@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-travis/-/is-travis-1.0.0.tgz", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "from": "is-typedarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "dev": true + }, + "is-unc-path": { + "version": "0.1.2", + "from": "is-unc-path@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "from": "is-utf8@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "dev": true + }, + "is-windows": { + "version": "0.2.0", + "from": "is-windows@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "from": "isarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "dev": true + }, + "isexe": { + "version": "1.1.2", + "from": "isexe@>=1.1.1 <2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "from": "isobject@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "from": "isstream@>=0.1.2 <0.2.0", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "dev": true + }, + "jju": { + "version": "1.3.0", + "from": "jju@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.3.0.tgz", + "dev": true + }, + "jodid25519": { + "version": "1.0.2", + "from": "jodid25519@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", + "dev": true, + "optional": true + }, + "jquery": { + "version": "3.2.0", + "from": "jquery@>=1.9.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.0.tgz" + }, + "js-base64": { + "version": "2.1.9", + "from": "js-base64@>=2.1.9 <3.0.0", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz", + "dev": true + }, + "js-tokens": { + "version": "3.0.1", + "from": "js-tokens@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", + "dev": true + }, + "js-yaml": { + "version": "3.8.2", + "from": "js-yaml@>=3.5.1 <4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.2.tgz", + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "from": "jsbn@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "dev": true, + "optional": true + }, + "jsesc": { + "version": "0.5.0", + "from": "jsesc@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "dev": true + }, + "jshint": { + "version": "2.8.0", + "from": "jshint@2.8.0", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.8.0.tgz", + "dev": true, + "dependencies": { + "lodash": { + "version": "3.7.0", + "from": "lodash@>=3.7.0 <3.8.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz", + "dev": true + }, + "minimatch": { + "version": "2.0.10", + "from": "minimatch@>=2.0.0 <2.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "dev": true + }, + "shelljs": { + "version": "0.3.0", + "from": "shelljs@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "dev": true + }, + "strip-json-comments": { + "version": "1.0.4", + "from": "strip-json-comments@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "dev": true + } + } + }, + "json-parse-helpfulerror": { + "version": "1.0.3", + "from": "json-parse-helpfulerror@>=1.0.3 <2.0.0", + "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "from": "json-schema@0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "from": "json-stable-stringify@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "from": "json-stringify-safe@>=5.0.1 <5.1.0", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "dev": true + }, + "json5": { + "version": "0.5.1", + "from": "json5@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "dev": true + }, + "jsonfile": { + "version": "2.4.0", + "from": "jsonfile@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "dev": true + }, + "jsonify": { + "version": "0.0.0", + "from": "jsonify@>=0.0.0 <0.1.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "from": "jsonpointer@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "dev": true + }, + "jsprim": { + "version": "1.4.0", + "from": "jsprim@>=1.2.2 <2.0.0", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", + "dev": true, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "dev": true + } + } + }, + "kew": { + "version": "0.7.0", + "from": "kew@>=0.7.0 <0.8.0", + "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", + "dev": true + }, + "kind-of": { + "version": "3.1.0", + "from": "kind-of@>=3.0.2 <4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.1.0.tgz", + "dev": true + }, + "klaw": { + "version": "1.3.1", + "from": "klaw@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "dev": true + }, + "lazy-cache": { + "version": "1.0.4", + "from": "lazy-cache@>=1.0.3 <2.0.0", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "dev": true + }, + "lazystream": { + "version": "1.0.0", + "from": "lazystream@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "from": "lcid@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "dev": true + }, + "levn": { + "version": "0.3.0", + "from": "levn@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "dev": true + }, + "liftoff": { + "version": "2.3.0", + "from": "liftoff@>=2.3.0 <3.0.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", + "dev": true, + "dependencies": { + "findup-sync": { + "version": "0.4.3", + "from": "findup-sync@>=0.4.2 <0.5.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", + "dev": true + } + } + }, + "livereload-js": { + "version": "2.2.2", + "from": "livereload-js@>=2.2.0 <3.0.0", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.2.2.tgz", + "dev": true + }, + "load-grunt-tasks": { + "version": "3.5.2", + "from": "load-grunt-tasks@>=3.5.2 <4.0.0", + "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.5.2.tgz", + "dev": true + }, + "load-json-file": { + "version": "1.1.0", + "from": "load-json-file@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "dev": true, + "dependencies": { + "strip-bom": { + "version": "2.0.0", + "from": "strip-bom@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "dev": true + } + } + }, + "lodash": { + "version": "4.17.4", + "from": "lodash@>=4.2.0 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "dev": true + }, + "lodash.assign": { + "version": "4.2.0", + "from": "lodash.assign@>=4.2.0 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "dev": true + }, + "lodash.assignwith": { + "version": "4.2.0", + "from": "lodash.assignwith@>=4.0.7 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "from": "lodash.clonedeep@>=4.3.2 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "dev": true + }, + "lodash.isempty": { + "version": "4.4.0", + "from": "lodash.isempty@>=4.2.1 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "from": "lodash.isplainobject@>=4.0.4 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "from": "lodash.isstring@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "dev": true + }, + "lodash.mapvalues": { + "version": "4.6.0", + "from": "lodash.mapvalues@>=4.4.0 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", + "dev": true + }, + "lodash.mergewith": { + "version": "4.6.0", + "from": "lodash.mergewith@>=4.6.0 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz", + "dev": true + }, + "lodash.pick": { + "version": "4.4.0", + "from": "lodash.pick@>=4.2.1 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "dev": true + }, + "lodash.pickby": { + "version": "4.6.0", + "from": "lodash.pickby@>=4.6.0 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", + "dev": true + }, + "log-symbols": { + "version": "1.0.2", + "from": "log-symbols@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "dev": true + }, + "longest": { + "version": "1.0.1", + "from": "longest@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "from": "loose-envify@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "from": "loud-rejection@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "dev": true + }, + "lru-cache": { + "version": "2.7.3", + "from": "lru-cache@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "dev": true + }, + "map-cache": { + "version": "0.2.2", + "from": "map-cache@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "from": "map-obj@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "from": "media-typer@0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "dev": true + }, + "meow": { + "version": "3.7.0", + "from": "meow@>=3.3.0 <4.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "dev": true, + "dependencies": { + "minimist": { + "version": "1.2.0", + "from": "minimist@>=1.1.3 <2.0.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "dev": true + } + } + }, + "micromatch": { + "version": "2.3.11", + "from": "micromatch@>=2.3.7 <3.0.0", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "dev": true + }, + "mime": { + "version": "1.3.4", + "from": "mime@1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", + "dev": true + }, + "mime-db": { + "version": "1.26.0", + "from": "mime-db@>=1.26.0 <1.27.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.26.0.tgz", + "dev": true + }, + "mime-types": { + "version": "2.1.14", + "from": "mime-types@>=2.1.11 <2.2.0", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.14.tgz", + "dev": true + }, + "mimic-fn": { + "version": "1.1.0", + "from": "mimic-fn@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "dev": true + }, + "minimatch": { + "version": "3.0.3", + "from": "minimatch@>=3.0.2 <4.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "dev": true + }, + "minimist": { + "version": "0.0.8", + "from": "minimist@0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "from": "mkdirp@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "dev": true + }, + "morgan": { + "version": "1.8.1", + "from": "morgan@>=1.6.1 <2.0.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.8.1.tgz", + "dev": true, + "dependencies": { + "debug": { + "version": "2.6.1", + "from": "debug@2.6.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.1.tgz", + "dev": true + } + } + }, + "ms": { + "version": "0.7.2", + "from": "ms@0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "dev": true + }, + "multimatch": { + "version": "2.1.0", + "from": "multimatch@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "dev": true + }, + "mute-stream": { + "version": "0.0.5", + "from": "mute-stream@0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "dev": true + }, + "mz": { + "version": "2.6.0", + "from": "mz@>=2.3.1 <3.0.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.6.0.tgz", + "dev": true + }, + "nan": { + "version": "2.5.1", + "from": "nan@>=2.4.0 <3.0.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.5.1.tgz", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "from": "natural-compare@>=1.4.0 <2.0.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "dev": true + }, + "negotiator": { + "version": "0.6.1", + "from": "negotiator@0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "dev": true + }, + "node-gyp": { + "version": "3.6.0", + "from": "node-gyp@>=3.3.1 <4.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.0.tgz", + "dev": true + }, + "node-sass": { + "version": "4.5.0", + "from": "node-sass@>=4.5.0 <5.0.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.5.0.tgz", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "from": "nopt@>=3.0.6 <3.1.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "dev": true + }, + "normalize-package-data": { + "version": "2.3.6", + "from": "normalize-package-data@>=2.3.4 <3.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.6.tgz", + "dev": true + }, + "normalize-path": { + "version": "2.0.1", + "from": "normalize-path@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.0.1.tgz", + "dev": true + }, + "normalize-range": { + "version": "0.1.2", + "from": "normalize-range@>=0.1.2 <0.2.0", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "dev": true + }, + "npmlog": { + "version": "4.0.2", + "from": "npmlog@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.0.2.tgz", + "dev": true + }, + "num2fraction": { + "version": "1.2.2", + "from": "num2fraction@>=1.2.2 <2.0.0", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "from": "number-is-nan@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "from": "oauth-sign@>=0.8.1 <0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "from": "object-assign@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "dev": true + }, + "object.omit": { + "version": "2.0.1", + "from": "object.omit@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "from": "on-finished@>=2.3.0 <2.4.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "dev": true + }, + "on-headers": { + "version": "1.0.1", + "from": "on-headers@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "dev": true + }, + "once": { + "version": "1.4.0", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "dev": true + }, + "onetime": { + "version": "1.1.0", + "from": "onetime@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "dev": true + }, + "opn": { + "version": "4.0.2", + "from": "opn@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", + "dev": true + }, + "optionator": { + "version": "0.8.2", + "from": "optionator@>=0.8.2 <0.9.0", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "dev": true + }, + "ora": { + "version": "1.1.0", + "from": "ora@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-1.1.0.tgz", + "dev": true, + "dependencies": { + "cli-cursor": { + "version": "2.1.0", + "from": "cli-cursor@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "dev": true + }, + "onetime": { + "version": "2.0.0", + "from": "onetime@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.0.tgz", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "from": "restore-cursor@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "dev": true + } + } + }, + "os-homedir": { + "version": "1.0.2", + "from": "os-homedir@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "dev": true + }, + "os-locale": { + "version": "1.4.0", + "from": "os-locale@>=1.4.0 <2.0.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "from": "os-tmpdir@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "dev": true + }, + "osenv": { + "version": "0.1.4", + "from": "osenv@>=0.0.0 <1.0.0", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", + "dev": true + }, + "package": { + "version": "1.0.1", + "from": "package@>=1.0.0 <1.2.0", + "resolved": "https://registry.npmjs.org/package/-/package-1.0.1.tgz", + "dev": true + }, + "parse-filepath": { + "version": "1.0.1", + "from": "parse-filepath@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", + "dev": true + }, + "parse-glob": { + "version": "3.0.4", + "from": "parse-glob@3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "from": "parse-json@>=2.2.0 <3.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "dev": true + }, + "parse-ms": { + "version": "1.0.1", + "from": "parse-ms@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz", + "dev": true + }, + "parse-passwd": { + "version": "1.0.0", + "from": "parse-passwd@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "dev": true + }, + "parserlib": { + "version": "0.2.5", + "from": "parserlib@>=0.2.2 <0.3.0", + "resolved": "https://registry.npmjs.org/parserlib/-/parserlib-0.2.5.tgz", + "dev": true + }, + "parseurl": { + "version": "1.3.1", + "from": "parseurl@>=1.3.1 <1.4.0", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "from": "path-exists@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "from": "path-is-absolute@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "from": "path-is-inside@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "from": "path-parse@>=1.0.5 <2.0.0", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "dev": true + }, + "path-root": { + "version": "0.1.1", + "from": "path-root@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "dev": true + }, + "path-root-regex": { + "version": "0.1.2", + "from": "path-root-regex@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "from": "path-type@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "dev": true + }, + "pend": { + "version": "1.2.0", + "from": "pend@>=1.2.0 <1.3.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "dev": true + }, + "phantomjs-prebuilt": { + "version": "2.1.14", + "from": "phantomjs-prebuilt@>=2.1.3 <3.0.0", + "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.14.tgz", + "dev": true + }, + "pify": { + "version": "2.3.0", + "from": "pify@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "from": "pinkie@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "from": "pinkie-promise@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "dev": true + }, + "pkg-up": { + "version": "1.0.0", + "from": "pkg-up@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "dev": true + }, + "plur": { + "version": "1.0.0", + "from": "plur@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", + "dev": true + }, + "pluralize": { + "version": "1.2.1", + "from": "pluralize@>=1.2.1 <2.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "dev": true + }, + "portscanner": { + "version": "1.2.0", + "from": "portscanner@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-1.2.0.tgz", + "dev": true + }, + "postcss": { + "version": "5.2.16", + "from": "postcss@>=5.2.16 <6.0.0", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.16.tgz", + "dev": true + }, + "postcss-cli": { + "version": "3.0.0", + "from": "postcss-cli@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-3.0.0.tgz", + "dev": true, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "from": "camelcase@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "dev": true + }, + "get-stdin": { + "version": "5.0.1", + "from": "get-stdin@>=5.0.1 <6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "dev": true + }, + "globby": { + "version": "6.1.0", + "from": "globby@>=6.1.0 <7.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "dev": true + }, + "yargs": { + "version": "7.0.2", + "from": "yargs@>=7.0.2 <8.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.0.2.tgz", + "dev": true + }, + "yargs-parser": { + "version": "5.0.0", + "from": "yargs-parser@>=5.0.0 <6.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "dev": true + } + } + }, + "postcss-flexbugs-fixes": { + "version": "2.1.0", + "from": "postcss-flexbugs-fixes@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-2.1.0.tgz", + "dev": true + }, + "postcss-load-config": { + "version": "1.2.0", + "from": "postcss-load-config@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz", + "dev": true + }, + "postcss-load-options": { + "version": "1.2.0", + "from": "postcss-load-options@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz", + "dev": true + }, + "postcss-load-plugins": { + "version": "2.3.0", + "from": "postcss-load-plugins@>=2.3.0 <3.0.0", + "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz", + "dev": true + }, + "postcss-reporter": { + "version": "3.0.0", + "from": "postcss-reporter@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-3.0.0.tgz", + "dev": true + }, + "postcss-value-parser": { + "version": "3.3.0", + "from": "postcss-value-parser@>=3.2.3 <4.0.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "from": "prelude-ls@>=1.1.2 <1.2.0", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "from": "preserve@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "dev": true + }, + "pretty-bytes": { + "version": "3.0.1", + "from": "pretty-bytes@>=3.0.1 <4.0.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-3.0.1.tgz", + "dev": true + }, + "pretty-ms": { + "version": "2.1.0", + "from": "pretty-ms@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", + "dev": true + }, + "private": { + "version": "0.1.7", + "from": "private@>=0.1.6 <0.2.0", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "from": "process-nextick-args@>=1.0.6 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "dev": true + }, + "progress": { + "version": "1.1.8", + "from": "progress@>=1.1.8 <2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "dev": true + }, + "promise": { + "version": "7.1.1", + "from": "promise@>=7.1.1 <8.0.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.1.1.tgz", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "from": "pseudomap@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "from": "punycode@>=1.4.1 <2.0.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "dev": true + }, + "q": { + "version": "1.4.1", + "from": "q@>=1.4.1 <1.5.0", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "dev": true + }, + "qs": { + "version": "6.3.2", + "from": "qs@>=6.3.0 <6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", + "dev": true + }, + "randomatic": { + "version": "1.1.6", + "from": "randomatic@>=1.1.3 <2.0.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.6.tgz", + "dev": true + }, + "range-parser": { + "version": "1.2.0", + "from": "range-parser@>=1.2.0 <1.3.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "dev": true + }, + "raw-body": { + "version": "2.1.7", + "from": "raw-body@>=2.1.5 <2.2.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz", + "dev": true, + "dependencies": { + "bytes": { + "version": "2.4.0", + "from": "bytes@2.4.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", + "dev": true + }, + "iconv-lite": { + "version": "0.4.13", + "from": "iconv-lite@0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "dev": true + } + } + }, + "read-pkg": { + "version": "1.1.0", + "from": "read-pkg@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "dev": true + }, + "read-pkg-up": { + "version": "1.0.1", + "from": "read-pkg-up@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "dev": true + }, + "readable-stream": { + "version": "2.2.6", + "from": "readable-stream@>=2.2.2 <3.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.6.tgz", + "dev": true + }, + "readdirp": { + "version": "2.1.0", + "from": "readdirp@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "dev": true + }, + "readline2": { + "version": "1.0.1", + "from": "readline2@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "dev": true + }, + "rechoir": { + "version": "0.6.2", + "from": "rechoir@>=0.6.2 <0.7.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "dev": true + }, + "redent": { + "version": "1.0.0", + "from": "redent@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "dev": true + }, + "regenerate": { + "version": "1.3.2", + "from": "regenerate@>=1.2.1 <2.0.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", + "dev": true + }, + "regenerator-runtime": { + "version": "0.10.3", + "from": "regenerator-runtime@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz", + "dev": true + }, + "regenerator-transform": { + "version": "0.9.8", + "from": "regenerator-transform@0.9.8", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.8.tgz", + "dev": true + }, + "regex-cache": { + "version": "0.4.3", + "from": "regex-cache@>=0.4.2 <0.5.0", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", + "dev": true + }, + "regexpu-core": { + "version": "2.0.0", + "from": "regexpu-core@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "dev": true + }, + "regjsgen": { + "version": "0.2.0", + "from": "regjsgen@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "from": "regjsparser@>=0.1.4 <0.2.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "from": "repeat-element@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "from": "repeat-string@>=1.5.2 <2.0.0", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "from": "repeating@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "dev": true + }, + "request": { + "version": "2.79.0", + "from": "request@>=2.79.0 <2.80.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "dev": true + }, + "request-progress": { + "version": "2.0.1", + "from": "request-progress@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", + "dev": true + }, + "requestretry": { + "version": "1.9.1", + "from": "requestretry@>=1.9.0 <1.10.0", + "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.9.1.tgz", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "from": "require-directory@>=2.1.1 <3.0.0", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "dev": true + }, + "require-from-string": { + "version": "1.2.1", + "from": "require-from-string@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "from": "require-main-filename@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "dev": true + }, + "require-uncached": { + "version": "1.0.3", + "from": "require-uncached@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "dev": true + }, + "resolve": { + "version": "1.3.2", + "from": "resolve@>=1.1.6 <2.0.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.2.tgz", + "dev": true + }, + "resolve-dir": { + "version": "0.1.1", + "from": "resolve-dir@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "dev": true + }, + "resolve-from": { + "version": "1.0.1", + "from": "resolve-from@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "dev": true + }, + "resolve-pkg": { + "version": "0.1.0", + "from": "resolve-pkg@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-0.1.0.tgz", + "dev": true, + "dependencies": { + "resolve-from": { + "version": "2.0.0", + "from": "resolve-from@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "dev": true + } + } + }, + "restore-cursor": { + "version": "1.0.1", + "from": "restore-cursor@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "from": "right-align@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "dev": true + }, + "rimraf": { + "version": "2.6.1", + "from": "rimraf@>=2.2.8 <3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "dev": true + }, + "run-async": { + "version": "0.1.0", + "from": "run-async@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "dev": true + }, + "rx-lite": { + "version": "3.1.2", + "from": "rx-lite@>=3.1.2 <4.0.0", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "dev": true + }, + "sass-graph": { + "version": "2.1.2", + "from": "sass-graph@>=2.1.1 <3.0.0", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.1.2.tgz", + "dev": true, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "from": "camelcase@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "dev": true + }, + "yargs": { + "version": "4.8.1", + "from": "yargs@>=4.7.1 <5.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "dev": true + }, + "yargs-parser": { + "version": "2.4.1", + "from": "yargs-parser@>=2.4.1 <3.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "dev": true + } + } + }, + "sauce-tunnel": { + "version": "2.5.0", + "from": "sauce-tunnel@>=2.5.0 <2.6.0", + "resolved": "https://registry.npmjs.org/sauce-tunnel/-/sauce-tunnel-2.5.0.tgz", + "dev": true + }, + "saucelabs": { + "version": "1.2.0", + "from": "saucelabs@>=1.2.0 <1.3.0", + "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.2.0.tgz", + "dev": true + }, + "semver": { + "version": "5.3.0", + "from": "semver@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0||>=4.0.0 <5.0.0||>=5.0.0 <6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "dev": true + }, + "send": { + "version": "0.15.1", + "from": "send@0.15.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.15.1.tgz", + "dev": true, + "dependencies": { + "debug": { + "version": "2.6.1", + "from": "debug@2.6.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.1.tgz", + "dev": true + }, + "http-errors": { + "version": "1.6.1", + "from": "http-errors@>=1.6.1 <1.7.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.1.tgz", + "dev": true + }, + "setprototypeof": { + "version": "1.0.3", + "from": "setprototypeof@1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "dev": true + } + } + }, + "serve-index": { + "version": "1.8.0", + "from": "serve-index@>=1.7.1 <2.0.0", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.8.0.tgz", + "dev": true, + "dependencies": { + "debug": { + "version": "2.2.0", + "from": "debug@>=2.2.0 <2.3.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "dev": true + }, + "ms": { + "version": "0.7.1", + "from": "ms@0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "dev": true + } + } + }, + "serve-static": { + "version": "1.12.1", + "from": "serve-static@>=1.10.0 <2.0.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.1.tgz", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "from": "set-blocking@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "from": "set-immediate-shim@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "dev": true + }, + "setprototypeof": { + "version": "1.0.2", + "from": "setprototypeof@1.0.2", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz", + "dev": true + }, + "shelljs": { + "version": "0.7.7", + "from": "shelljs@>=0.7.7 <0.8.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.7.tgz", + "dev": true + }, + "shx": { + "version": "0.2.2", + "from": "shx@>=0.2.2 <0.3.0", + "resolved": "https://registry.npmjs.org/shx/-/shx-0.2.2.tgz", + "dev": true, + "dependencies": { + "minimist": { + "version": "1.2.0", + "from": "minimist@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "dev": true + } + } + }, + "sigmund": { + "version": "1.0.1", + "from": "sigmund@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "from": "signal-exit@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "dev": true + }, + "slash": { + "version": "1.0.0", + "from": "slash@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "dev": true + }, + "slice-ansi": { + "version": "0.0.4", + "from": "slice-ansi@0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "dev": true + }, + "sntp": { + "version": "1.0.9", + "from": "sntp@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "dev": true + }, + "source-map": { + "version": "0.5.6", + "from": "source-map@>=0.5.6 <0.6.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "dev": true + }, + "source-map-support": { + "version": "0.4.14", + "from": "source-map-support@>=0.4.2 <0.5.0", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.14.tgz", + "dev": true + }, + "spdx-correct": { + "version": "1.0.2", + "from": "spdx-correct@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "dev": true + }, + "spdx-expression-parse": { + "version": "1.0.4", + "from": "spdx-expression-parse@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "from": "spdx-license-ids@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "dev": true + }, + "split": { + "version": "1.0.0", + "from": "split@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.0.tgz", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "from": "sprintf-js@>=1.0.2 <1.1.0", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "dev": true + }, + "sshpk": { + "version": "1.11.0", + "from": "sshpk@>=1.7.0 <2.0.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.11.0.tgz", + "dev": true, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "dev": true + } + } + }, + "statuses": { + "version": "1.3.1", + "from": "statuses@>=1.3.1 <1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "dev": true + }, + "stdout-stream": { + "version": "1.4.0", + "from": "stdout-stream@>=1.4.0 <2.0.0", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", + "dev": true + }, + "stream-buffers": { + "version": "2.2.0", + "from": "stream-buffers@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "from": "string-width@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "dev": true + }, + "stringstream": { + "version": "0.0.5", + "from": "stringstream@>=0.0.4 <0.1.0", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "from": "strip-ansi@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "from": "strip-bom@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "from": "strip-indent@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "from": "strip-json-comments@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "from": "supports-color@>=3.2.3 <4.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "dev": true + }, + "table": { + "version": "3.8.3", + "from": "table@>=3.7.8 <4.0.0", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "from": "is-fullwidth-code-point@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "dev": true + }, + "string-width": { + "version": "2.0.0", + "from": "string-width@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", + "dev": true + } + } + }, + "tar": { + "version": "2.2.1", + "from": "tar@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "dev": true + }, + "tar-stream": { + "version": "1.5.2", + "from": "tar-stream@>=1.5.0 <2.0.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.2.tgz", + "dev": true + }, + "temporary": { + "version": "0.0.8", + "from": "temporary@>=0.0.8 <0.0.9", + "resolved": "https://registry.npmjs.org/temporary/-/temporary-0.0.8.tgz", + "dev": true + }, + "tether": { + "version": "1.4.0", + "from": "tether@>=1.4.0 <2.0.0", + "resolved": "https://registry.npmjs.org/tether/-/tether-1.4.0.tgz" + }, + "text-table": { + "version": "0.2.0", + "from": "text-table@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "dev": true + }, + "thenify": { + "version": "3.2.1", + "from": "thenify@>=3.1.0 <4.0.0", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.2.1.tgz", + "dev": true + }, + "thenify-all": { + "version": "1.6.0", + "from": "thenify-all@>=1.6.0 <2.0.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "dev": true + }, + "throttleit": { + "version": "1.0.0", + "from": "throttleit@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "dev": true + }, + "through": { + "version": "2.3.8", + "from": "through@>=2.3.6 <3.0.0", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "dev": true + }, + "time-grunt": { + "version": "1.4.0", + "from": "time-grunt@>=1.4.0 <2.0.0", + "resolved": "https://registry.npmjs.org/time-grunt/-/time-grunt-1.4.0.tgz", + "dev": true + }, + "time-zone": { + "version": "0.1.0", + "from": "time-zone@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-0.1.0.tgz", + "dev": true + }, + "tiny-lr": { + "version": "0.2.1", + "from": "tiny-lr@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.2.1.tgz", + "dev": true, + "dependencies": { + "debug": { + "version": "2.2.0", + "from": "debug@>=2.2.0 <2.3.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "dev": true + }, + "ms": { + "version": "0.7.1", + "from": "ms@0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "dev": true + }, + "qs": { + "version": "5.1.0", + "from": "qs@>=5.1.0 <5.2.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz", + "dev": true + } + } + }, + "to-fast-properties": { + "version": "1.0.2", + "from": "to-fast-properties@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.2.tgz", + "dev": true + }, + "tough-cookie": { + "version": "2.3.2", + "from": "tough-cookie@>=2.3.0 <2.4.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "dev": true + }, + "trim-newlines": { + "version": "1.0.0", + "from": "trim-newlines@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "from": "trim-right@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "dev": true + }, + "tryit": { + "version": "1.0.3", + "from": "tryit@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "dev": true + }, + "tunnel-agent": { + "version": "0.4.3", + "from": "tunnel-agent@>=0.4.1 <0.5.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "dev": true + }, + "tweetnacl": { + "version": "0.14.5", + "from": "tweetnacl@>=0.14.0 <0.15.0", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "dev": true, + "optional": true + }, + "type-check": { + "version": "0.3.2", + "from": "type-check@>=0.3.2 <0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "dev": true + }, + "type-is": { + "version": "1.6.14", + "from": "type-is@>=1.6.10 <1.7.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.14.tgz", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "from": "typedarray@>=0.0.6 <0.0.7", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "dev": true + }, + "uglify-js": { + "version": "2.8.14", + "from": "uglify-js@>=2.8.14 <3.0.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.14.tgz", + "dev": true, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "from": "camelcase@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "dev": true + }, + "cliui": { + "version": "2.1.0", + "from": "cliui@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "dev": true + }, + "window-size": { + "version": "0.1.0", + "from": "window-size@0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "dev": true + }, + "wordwrap": { + "version": "0.0.2", + "from": "wordwrap@0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "from": "yargs@>=3.10.0 <3.11.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "dev": true + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "from": "uglify-to-browserify@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "dev": true + }, + "unc-path-regex": { + "version": "0.1.2", + "from": "unc-path-regex@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "dev": true + }, + "underscore.string": { + "version": "3.2.3", + "from": "underscore.string@>=3.2.3 <3.3.0", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "from": "unpipe@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "dev": true + }, + "user-home": { + "version": "2.0.0", + "from": "user-home@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "from": "util-deprecate@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "dev": true + }, + "utils-merge": { + "version": "1.0.0", + "from": "utils-merge@1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "dev": true + }, + "uuid": { + "version": "3.0.1", + "from": "uuid@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "from": "validate-npm-package-license@>=3.0.1 <4.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "dev": true + }, + "verror": { + "version": "1.3.6", + "from": "verror@1.3.6", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "dev": true + }, + "walkdir": { + "version": "0.0.11", + "from": "walkdir@>=0.0.11 <0.0.12", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz", + "dev": true + }, + "websocket-driver": { + "version": "0.6.5", + "from": "websocket-driver@>=0.5.1", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "dev": true + }, + "websocket-extensions": { + "version": "0.1.1", + "from": "websocket-extensions@>=0.1.1", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz", + "dev": true + }, + "when": { + "version": "3.7.8", + "from": "when@>=3.7.5 <3.8.0", + "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", + "dev": true + }, + "which": { + "version": "1.2.12", + "from": "which@>=1.2.1 <1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.12.tgz", + "dev": true + }, + "which-module": { + "version": "1.0.0", + "from": "which-module@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "dev": true + }, + "wide-align": { + "version": "1.1.0", + "from": "wide-align@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.0.tgz", + "dev": true + }, + "window-size": { + "version": "0.2.0", + "from": "window-size@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "from": "wordwrap@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "from": "wrap-ansi@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "dev": true + }, + "write": { + "version": "0.2.1", + "from": "write@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "dev": true + }, + "xml": { + "version": "1.0.0", + "from": "xml@1.0.0", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.0.tgz", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "from": "xtend@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "from": "y18n@>=3.2.1 <4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "from": "yallist@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "dev": true + }, + "yargs": { + "version": "6.6.0", + "from": "yargs@>=6.6.0 <7.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "dev": true, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "from": "camelcase@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "dev": true + } + } + }, + "yargs-parser": { + "version": "4.2.1", + "from": "yargs-parser@>=4.2.0 <5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "dev": true, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "from": "camelcase@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "dev": true + } + } + }, + "yauzl": { + "version": "2.4.1", + "from": "yauzl@2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "dev": true + }, + "zip-stream": { + "version": "1.1.1", + "from": "zip-stream@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.1.1.tgz", + "dev": true + } + } +} diff --git a/templates/assets/bootstrap/grunt/postcss.config.js b/templates/assets/bootstrap/grunt/postcss.config.js new file mode 100644 index 0000000..803078a --- /dev/null +++ b/templates/assets/bootstrap/grunt/postcss.config.js @@ -0,0 +1,41 @@ +module.exports = (ctx) => ({ + map: ctx.file.dirname.startsWith('docs') ? false : { + inline: false, + annotation: true, + sourcesContent: true + }, + plugins: { + autoprefixer: { + browsers: [ + // + // Official browser support policy: + // https://v4-alpha.getbootstrap.com/getting-started/browsers-devices/#supported-browsers + // + 'Chrome >= 35', // Exact version number here is kinda arbitrary + // Rather than using Autoprefixer's native "Firefox ESR" version specifier string, + // we deliberately hardcode the number. This is to avoid unwittingly severely breaking the previous ESR in the event that: + // (a) we happen to ship a new Bootstrap release soon after the release of a new ESR, + // such that folks haven't yet had a reasonable amount of time to upgrade; and + // (b) the new ESR has unprefixed CSS properties/values whose absence would severely break webpages + // (e.g. `box-sizing`, as opposed to `background: linear-gradient(...)`). + // Since they've been unprefixed, Autoprefixer will stop prefixing them, + // thus causing them to not work in the previous ESR (where the prefixes were required). + 'Firefox >= 38', // Current Firefox Extended Support Release (ESR); https://www.mozilla.org/en-US/firefox/organizations/faq/ + // Note: Edge versions in Autoprefixer & Can I Use refer to the EdgeHTML rendering engine version, + // NOT the Edge app version shown in Edge's "About" screen. + // For example, at the time of writing, Edge 20 on an up-to-date system uses EdgeHTML 12. + // See also https://github.com/Fyrd/caniuse/issues/1928 + 'Edge >= 12', + 'Explorer >= 10', + // Out of leniency, we prefix these 1 version further back than the official policy. + 'iOS >= 8', + 'Safari >= 8', + // The following remain NOT officially supported, but we're lenient and include their prefixes to avoid severely breaking in them. + 'Android 2.3', + 'Android >= 4', + 'Opera >= 12' + ] + }, + 'postcss-flexbugs-fixes': {} + } +}) diff --git a/templates/assets/bootstrap/grunt/sauce_browsers.yml b/templates/assets/bootstrap/grunt/sauce_browsers.yml new file mode 100644 index 0000000..4d5041b --- /dev/null +++ b/templates/assets/bootstrap/grunt/sauce_browsers.yml @@ -0,0 +1,84 @@ +[ + # Docs: https://wiki.saucelabs.com/display/DOCS/Platform+Configurator + + { + browserName: "safari", + platform: "OS X 10.11" + }, + { + browserName: "chrome", + platform: "OS X 10.11", + version: "latest" + }, + { + browserName: "firefox", + platform: "OS X 10.11", + version: "latest" + }, + + # Mac Opera not currently supported by Sauce Labs + + { + browserName: "MicrosoftEdge", + platform: "Windows 10", + version: "latest" + }, + { + browserName: "internet explorer", + version: "11", + platform: "Windows 8.1" + }, + { + browserName: "internet explorer", + version: "10", + platform: "Windows 8" + }, + { + browserName: "internet explorer", + version: "9", + platform: "Windows 7" + }, + + { + browserName: "chrome", + platform: "Windows 10", + version: "latest" + }, + { + browserName: "firefox", + platform: "Windows 10", + version: "latest" + }, + + # Win Opera 15+ not currently supported by Sauce Labs + + { + browserName: "Safari", + deviceName: "iPhone Simulator", + platformVersion: "9.3", + platformName: "iOS" + }, + + # iOS Chrome not currently supported by Sauce Labs + + # Linux (unofficial) + { + browserName: "chrome", + platform: "Linux", + version: "latest" + }, + { + browserName: "firefox", + platform: "Linux", + version: "latest" + }, + + # Android + { + platform: "Linux", + browserName: "android", + deviceName: "Android Emulator", + version: "latest", + deviceType: "phone" + } +] diff --git a/templates/assets/bootstrap/grunt/upload-preview.sh b/templates/assets/bootstrap/grunt/upload-preview.sh new file mode 100755 index 0000000..08e7fa2 --- /dev/null +++ b/templates/assets/bootstrap/grunt/upload-preview.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# Upload built docs to preview.twbsapps.com + +if [ "$TRAVIS_REPO_SLUG" != twbs-savage/bootstrap ]; then exit 0; fi + +# Add build metadata to version +sed -i "/^current_version:/ s/\$/+pr.${TRAVIS_COMMIT}/" _config.yml +# Fix URLs since the site's root is now a subdirectory +bundle exec jekyll build --destination "$TRAVIS_COMMIT" --baseurl "/c/${TRAVIS_COMMIT}" + +# Install gcloud & gsutil +GSUTIL_VERSION=$(gsutil version | cut -d ' ' -f 3) +if [ ! -d "${HOME}/google-cloud-sdk" ] || [ "${GSUTIL_VERSION}" != '4.19' ]; then + rm -rf "${HOME}/google-cloud-sdk" # Kill Travis' outdated non-updateable preinstalled version + echo 'Installing google-cloud-sdk...' + export CLOUDSDK_CORE_DISABLE_PROMPTS=1 + time (curl -S -s https://sdk.cloud.google.com | bash &>/dev/null) + echo 'Done.' +fi +source "${HOME}/google-cloud-sdk/path.bash.inc" + +openssl aes-256-cbc -K $encrypted_2b749c8e6327_key -iv $encrypted_2b749c8e6327_iv -in grunt/gcp-key.json.enc -out grunt/gcp-key.json -d +gcloud auth activate-service-account "$GCP_SERVICE_ACCOUNT" --key-file grunt/gcp-key.json &> /dev/null || (echo 'GCP login failed!'; exit 1) + +echo "Uploading to http://preview.twbsapps.com/c/${TRAVIS_COMMIT} ..." +time gsutil -q -m cp -z html,css,js,svg -r "./${TRAVIS_COMMIT}" gs://preview.twbsapps.com/c/ +echo 'Done.' diff --git a/templates/assets/bootstrap/js/.eslintrc.json b/templates/assets/bootstrap/js/.eslintrc.json new file mode 100644 index 0000000..07a307a --- /dev/null +++ b/templates/assets/bootstrap/js/.eslintrc.json @@ -0,0 +1,240 @@ +{ + "root": true, + "parser": "babel-eslint", + "env": { + "browser": true, + "es6": true, + "jquery": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 8, + "sourceType": "module" + }, + "rules": { + // Possible Errors + "no-await-in-loop": "error", + "no-compare-neg-zero": "error", + "no-extra-parens": "error", + "no-prototype-builtins": "off", + "no-template-curly-in-string": "error", + "no-unsafe-negation": "error", + "valid-jsdoc": "error", + + // Best Practices + "accessor-pairs": "error", + "array-callback-return": "error", + "block-scoped-var": "error", + "class-methods-use-this": "off", + "complexity": "error", + "consistent-return": "error", + "curly": "error", + "default-case": "error", + "dot-location": ["error", "property"], + "dot-notation": "error", + "eqeqeq": "error", + "guard-for-in": "error", + "no-alert": "error", + "no-caller": "error", + "no-div-regex": "error", + "no-else-return": "error", + "no-empty-function": "error", + "no-eq-null": "error", + "no-eval": "error", + "no-extend-native": "error", + "no-extra-bind": "error", + "no-extra-label": "error", + "no-floating-decimal": "error", + "no-global-assign": "error", + "no-implicit-coercion": "error", + "no-implicit-globals": "error", + "no-implied-eval": "error", + "no-invalid-this": "off", + "no-iterator": "error", + "no-labels": "error", + "no-lone-blocks": "error", + "no-loop-func": "error", + "no-magic-numbers": ["error", { + "ignore": [-1, 0, 1], + "ignoreArrayIndexes": true + } + ], + "no-multi-spaces": ["error", { + "exceptions": { + "AssignmentExpression": true, + "ArrowFunctionExpression": true, + "CallExpression": true, + "VariableDeclarator": true + } + } + ], + "no-multi-str": "error", + "no-new": "error", + "no-new-func": "off", + "no-new-wrappers": "error", + "no-new": "error", + "no-octal-escape": "error", + "no-param-reassign": "off", + "no-proto": "error", + "no-restricted-properties": "error", + "no-return-assign": "off", + "no-return-await": "error", + "no-script-url": "error", + "no-self-compare": "error", + "no-sequences": "error", + "no-throw-literal": "error", + "no-unmodified-loop-condition": "error", + "no-unused-expressions": "error", + "no-useless-call": "error", + "no-useless-concat": "error", + "no-useless-escape": "error", + "no-useless-return": "off", + "no-void": "error", + "no-warning-comments": "off", + "no-with": "error", + "prefer-promise-reject-errors": "error", + "radix": "error", + "vars-on-top": "error", + "wrap-iife": "error", + "yoda": "error", + + // Strict Mode + "strict": "error", + + // Variables + "init-declarations": "off", + "no-catch-shadow": "error", + "no-label-var": "error", + "no-restricted-globals": "error", + "no-shadow": "off", + "no-shadow-restricted-names": "error", + "no-undef-init": "error", + "no-undefined": "off", + "no-use-before-define": "off", + + // Node.js and CommonJS + "callback-return": "off", + "global-require": "error", + "handle-callback-err": "error", + "no-mixed-requires": "error", + "no-new-require": "error", + "no-path-concat": "error", + "no-process-env": "error", + "no-process-exit": "error", + "no-restricted-modules": "error", + "no-sync": "error", + + // Stylistic Issues + "array-bracket-spacing": "error", + "block-spacing": "error", + "brace-style": "error", + "capitalized-comments": "off", + "camelcase": "error", + "comma-dangle": "error", + "comma-spacing": "error", + "comma-style": "error", + "computed-property-spacing": "error", + "consistent-this": "error", + "eol-last": "error", + "func-call-spacing": "error", + "func-name-matching": "error", + "func-names": "off", + "func-style": ["error", "declaration"], + "id-blacklist": "error", + "id-length": "off", + "id-match": "error", + "indent": ["error", 2, { "SwitchCase": 1 }], + "jsx-quotes": "error", + "key-spacing": "off", + "keyword-spacing": "error", + "line-comment-position": "off", + "linebreak-style": ["error", "unix"], + "lines-around-comment": "off", + "lines-around-directive": "error", + "max-depth": ["error", 10], + "max-len": "off", + "max-lines": "off", + "max-nested-callbacks": "error", + "max-params": "off", + "max-statements": "off", + "max-statements-per-line": "error", + "multiline-ternary": "off", + "new-cap": ["error", { "capIsNewExceptionPattern": "$.*" }], + "new-parens": "error", + "newline-after-var": "off", + "newline-before-return": "off", + "newline-per-chained-call": ["error", { "ignoreChainWithDepth": 5 }], + "no-array-constructor": "error", + "no-bitwise": "error", + "no-continue": "off", + "no-inline-comments": "off", + "no-lonely-if": "error", + "no-mixed-operators": "off", + "no-multi-assign": "error", + "no-multiple-empty-lines": "error", + "no-negated-condition": "off", + "no-nested-ternary": "error", + "no-new-object": "error", + "no-plusplus": "off", + "no-restricted-syntax": "error", + "no-tabs": "error", + "no-ternary": "off", + "no-trailing-spaces": "error", + "no-underscore-dangle": "off", + "no-unneeded-ternary": "error", + "no-whitespace-before-property": "error", + "nonblock-statement-body-position": "error", + "object-curly-newline": ["error", { "minProperties": 1 }], + "object-curly-spacing": ["error", "always"], + "object-property-newline": "error", + "one-var": ["error", "never"], + "one-var-declaration-per-line": "error", + "operator-assignment": "error", + "operator-linebreak": "off", + "padded-blocks": "off", + "quote-props": ["error", "as-needed"], + "quotes": ["error", "single"], + "require-jsdoc": "off", + "semi": ["error", "never"], + "semi-spacing": "error", + "sort-keys": "off", + "sort-vars": "error", + "space-before-blocks": "error", + "space-before-function-paren": ["error", { + "anonymous": "always", + "named": "never" + }], + "space-in-parens": "error", + "space-infix-ops": "error", + "space-unary-ops": "error", + "spaced-comment": "error", + "template-tag-spacing": "error", + "unicode-bom": "error", + "wrap-regex": "off", + + // ECMAScript 6 + "arrow-body-style": "off", + "arrow-parens": "error", + "arrow-spacing": "error", + "generator-star-spacing": "error", + "no-confusing-arrow": "error", + "no-duplicate-imports": "error", + "no-restricted-imports": "error", + "no-useless-computed-key": "error", + "no-useless-constructor": "error", + "no-useless-rename": "error", + "no-var": "error", + "object-shorthand": "error", + "prefer-arrow-callback": "error", + "prefer-const": "error", + "prefer-numeric-literals": "error", + "prefer-rest-params": "error", + "prefer-spread": "error", + "prefer-template": "error", + "rest-spread-spacing": "error", + "sort-imports": "error", + "symbol-description": "error", + "template-curly-spacing": "error", + "yield-star-spacing": "error" + } +} diff --git a/templates/assets/bootstrap/js/src/alert.js b/templates/assets/bootstrap/js/src/alert.js new file mode 100644 index 0000000..b30d0d3 --- /dev/null +++ b/templates/assets/bootstrap/js/src/alert.js @@ -0,0 +1,193 @@ +import Util from './util' + + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.6): alert.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const Alert = (($) => { + + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + const NAME = 'alert' + const VERSION = '4.0.0-alpha.6' + const DATA_KEY = 'bs.alert' + const EVENT_KEY = `.${DATA_KEY}` + const DATA_API_KEY = '.data-api' + const JQUERY_NO_CONFLICT = $.fn[NAME] + const TRANSITION_DURATION = 150 + + const Selector = { + DISMISS : '[data-dismiss="alert"]' + } + + const Event = { + CLOSE : `close${EVENT_KEY}`, + CLOSED : `closed${EVENT_KEY}`, + CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}` + } + + const ClassName = { + ALERT : 'alert', + FADE : 'fade', + SHOW : 'show' + } + + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + class Alert { + + constructor(element) { + this._element = element + } + + + // getters + + static get VERSION() { + return VERSION + } + + + // public + + close(element) { + element = element || this._element + + const rootElement = this._getRootElement(element) + const customEvent = this._triggerCloseEvent(rootElement) + + if (customEvent.isDefaultPrevented()) { + return + } + + this._removeElement(rootElement) + } + + dispose() { + $.removeData(this._element, DATA_KEY) + this._element = null + } + + + // private + + _getRootElement(element) { + const selector = Util.getSelectorFromElement(element) + let parent = false + + if (selector) { + parent = $(selector)[0] + } + + if (!parent) { + parent = $(element).closest(`.${ClassName.ALERT}`)[0] + } + + return parent + } + + _triggerCloseEvent(element) { + const closeEvent = $.Event(Event.CLOSE) + + $(element).trigger(closeEvent) + return closeEvent + } + + _removeElement(element) { + $(element).removeClass(ClassName.SHOW) + + if (!Util.supportsTransitionEnd() || + !$(element).hasClass(ClassName.FADE)) { + this._destroyElement(element) + return + } + + $(element) + .one(Util.TRANSITION_END, (event) => this._destroyElement(element, event)) + .emulateTransitionEnd(TRANSITION_DURATION) + } + + _destroyElement(element) { + $(element) + .detach() + .trigger(Event.CLOSED) + .remove() + } + + + // static + + static _jQueryInterface(config) { + return this.each(function () { + const $element = $(this) + let data = $element.data(DATA_KEY) + + if (!data) { + data = new Alert(this) + $element.data(DATA_KEY, data) + } + + if (config === 'close') { + data[config](this) + } + }) + } + + static _handleDismiss(alertInstance) { + return function (event) { + if (event) { + event.preventDefault() + } + + alertInstance.close(this) + } + } + + } + + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + $(document).on( + Event.CLICK_DATA_API, + Selector.DISMISS, + Alert._handleDismiss(new Alert()) + ) + + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Alert._jQueryInterface + $.fn[NAME].Constructor = Alert + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Alert._jQueryInterface + } + + return Alert + +})(jQuery) + +export default Alert diff --git a/templates/assets/bootstrap/js/src/button.js b/templates/assets/bootstrap/js/src/button.js new file mode 100644 index 0000000..76c5cdd --- /dev/null +++ b/templates/assets/bootstrap/js/src/button.js @@ -0,0 +1,176 @@ +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.6): button.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const Button = (($) => { + + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + const NAME = 'button' + const VERSION = '4.0.0-alpha.6' + const DATA_KEY = 'bs.button' + const EVENT_KEY = `.${DATA_KEY}` + const DATA_API_KEY = '.data-api' + const JQUERY_NO_CONFLICT = $.fn[NAME] + + const ClassName = { + ACTIVE : 'active', + BUTTON : 'btn', + FOCUS : 'focus' + } + + const Selector = { + DATA_TOGGLE_CARROT : '[data-toggle^="button"]', + DATA_TOGGLE : '[data-toggle="buttons"]', + INPUT : 'input', + ACTIVE : '.active', + BUTTON : '.btn' + } + + const Event = { + CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`, + FOCUS_BLUR_DATA_API : `focus${EVENT_KEY}${DATA_API_KEY} ` + + `blur${EVENT_KEY}${DATA_API_KEY}` + } + + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + class Button { + + constructor(element) { + this._element = element + } + + + // getters + + static get VERSION() { + return VERSION + } + + + // public + + toggle() { + let triggerChangeEvent = true + const rootElement = $(this._element).closest( + Selector.DATA_TOGGLE + )[0] + + if (rootElement) { + const input = $(this._element).find(Selector.INPUT)[0] + + if (input) { + if (input.type === 'radio') { + if (input.checked && + $(this._element).hasClass(ClassName.ACTIVE)) { + triggerChangeEvent = false + + } else { + const activeElement = $(rootElement).find(Selector.ACTIVE)[0] + + if (activeElement) { + $(activeElement).removeClass(ClassName.ACTIVE) + } + } + } + + if (triggerChangeEvent) { + input.checked = !$(this._element).hasClass(ClassName.ACTIVE) + $(input).trigger('change') + } + + input.focus() + } + + } + + this._element.setAttribute('aria-pressed', + !$(this._element).hasClass(ClassName.ACTIVE)) + + if (triggerChangeEvent) { + $(this._element).toggleClass(ClassName.ACTIVE) + } + } + + dispose() { + $.removeData(this._element, DATA_KEY) + this._element = null + } + + + // static + + static _jQueryInterface(config) { + return this.each(function () { + let data = $(this).data(DATA_KEY) + + if (!data) { + data = new Button(this) + $(this).data(DATA_KEY, data) + } + + if (config === 'toggle') { + data[config]() + } + }) + } + + } + + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + $(document) + .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => { + event.preventDefault() + + let button = event.target + + if (!$(button).hasClass(ClassName.BUTTON)) { + button = $(button).closest(Selector.BUTTON) + } + + Button._jQueryInterface.call($(button), 'toggle') + }) + .on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => { + const button = $(event.target).closest(Selector.BUTTON)[0] + $(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type)) + }) + + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Button._jQueryInterface + $.fn[NAME].Constructor = Button + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Button._jQueryInterface + } + + return Button + +})(jQuery) + +export default Button diff --git a/templates/assets/bootstrap/js/src/carousel.js b/templates/assets/bootstrap/js/src/carousel.js new file mode 100644 index 0000000..8a75cb2 --- /dev/null +++ b/templates/assets/bootstrap/js/src/carousel.js @@ -0,0 +1,497 @@ +import Util from './util' + + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.6): carousel.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const Carousel = (($) => { + + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + const NAME = 'carousel' + const VERSION = '4.0.0-alpha.6' + const DATA_KEY = 'bs.carousel' + const EVENT_KEY = `.${DATA_KEY}` + const DATA_API_KEY = '.data-api' + const JQUERY_NO_CONFLICT = $.fn[NAME] + const TRANSITION_DURATION = 600 + const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key + const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key + + const Default = { + interval : 5000, + keyboard : true, + slide : false, + pause : 'hover', + wrap : true + } + + const DefaultType = { + interval : '(number|boolean)', + keyboard : 'boolean', + slide : '(boolean|string)', + pause : '(string|boolean)', + wrap : 'boolean' + } + + const Direction = { + NEXT : 'next', + PREV : 'prev', + LEFT : 'left', + RIGHT : 'right' + } + + const Event = { + SLIDE : `slide${EVENT_KEY}`, + SLID : `slid${EVENT_KEY}`, + KEYDOWN : `keydown${EVENT_KEY}`, + MOUSEENTER : `mouseenter${EVENT_KEY}`, + MOUSELEAVE : `mouseleave${EVENT_KEY}`, + LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`, + CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}` + } + + const ClassName = { + CAROUSEL : 'carousel', + ACTIVE : 'active', + SLIDE : 'slide', + RIGHT : 'carousel-item-right', + LEFT : 'carousel-item-left', + NEXT : 'carousel-item-next', + PREV : 'carousel-item-prev', + ITEM : 'carousel-item' + } + + const Selector = { + ACTIVE : '.active', + ACTIVE_ITEM : '.active.carousel-item', + ITEM : '.carousel-item', + NEXT_PREV : '.carousel-item-next, .carousel-item-prev', + INDICATORS : '.carousel-indicators', + DATA_SLIDE : '[data-slide], [data-slide-to]', + DATA_RIDE : '[data-ride="carousel"]' + } + + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + class Carousel { + + constructor(element, config) { + this._items = null + this._interval = null + this._activeElement = null + + this._isPaused = false + this._isSliding = false + + this._config = this._getConfig(config) + this._element = $(element)[0] + this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0] + + this._addEventListeners() + } + + + // getters + + static get VERSION() { + return VERSION + } + + static get Default() { + return Default + } + + + // public + + next() { + if (this._isSliding) { + throw new Error('Carousel is sliding') + } + this._slide(Direction.NEXT) + } + + nextWhenVisible() { + // Don't call next when the page isn't visible + if (!document.hidden) { + this.next() + } + } + + prev() { + if (this._isSliding) { + throw new Error('Carousel is sliding') + } + this._slide(Direction.PREV) + } + + pause(event) { + if (!event) { + this._isPaused = true + } + + if ($(this._element).find(Selector.NEXT_PREV)[0] && + Util.supportsTransitionEnd()) { + Util.triggerTransitionEnd(this._element) + this.cycle(true) + } + + clearInterval(this._interval) + this._interval = null + } + + cycle(event) { + if (!event) { + this._isPaused = false + } + + if (this._interval) { + clearInterval(this._interval) + this._interval = null + } + + if (this._config.interval && !this._isPaused) { + this._interval = setInterval( + (document.visibilityState ? this.nextWhenVisible : this.next).bind(this), + this._config.interval + ) + } + } + + to(index) { + this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0] + + const activeIndex = this._getItemIndex(this._activeElement) + + if (index > this._items.length - 1 || index < 0) { + return + } + + if (this._isSliding) { + $(this._element).one(Event.SLID, () => this.to(index)) + return + } + + if (activeIndex === index) { + this.pause() + this.cycle() + return + } + + const direction = index > activeIndex ? + Direction.NEXT : + Direction.PREV + + this._slide(direction, this._items[index]) + } + + dispose() { + $(this._element).off(EVENT_KEY) + $.removeData(this._element, DATA_KEY) + + this._items = null + this._config = null + this._element = null + this._interval = null + this._isPaused = null + this._isSliding = null + this._activeElement = null + this._indicatorsElement = null + } + + + // private + + _getConfig(config) { + config = $.extend({}, Default, config) + Util.typeCheckConfig(NAME, config, DefaultType) + return config + } + + _addEventListeners() { + if (this._config.keyboard) { + $(this._element) + .on(Event.KEYDOWN, (event) => this._keydown(event)) + } + + if (this._config.pause === 'hover' && + !('ontouchstart' in document.documentElement)) { + $(this._element) + .on(Event.MOUSEENTER, (event) => this.pause(event)) + .on(Event.MOUSELEAVE, (event) => this.cycle(event)) + } + } + + _keydown(event) { + if (/input|textarea/i.test(event.target.tagName)) { + return + } + + switch (event.which) { + case ARROW_LEFT_KEYCODE: + event.preventDefault() + this.prev() + break + case ARROW_RIGHT_KEYCODE: + event.preventDefault() + this.next() + break + default: + return + } + } + + _getItemIndex(element) { + this._items = $.makeArray($(element).parent().find(Selector.ITEM)) + return this._items.indexOf(element) + } + + _getItemByDirection(direction, activeElement) { + const isNextDirection = direction === Direction.NEXT + const isPrevDirection = direction === Direction.PREV + const activeIndex = this._getItemIndex(activeElement) + const lastItemIndex = this._items.length - 1 + const isGoingToWrap = isPrevDirection && activeIndex === 0 || + isNextDirection && activeIndex === lastItemIndex + + if (isGoingToWrap && !this._config.wrap) { + return activeElement + } + + const delta = direction === Direction.PREV ? -1 : 1 + const itemIndex = (activeIndex + delta) % this._items.length + + return itemIndex === -1 ? + this._items[this._items.length - 1] : this._items[itemIndex] + } + + + _triggerSlideEvent(relatedTarget, eventDirectionName) { + const slideEvent = $.Event(Event.SLIDE, { + relatedTarget, + direction: eventDirectionName + }) + + $(this._element).trigger(slideEvent) + + return slideEvent + } + + _setActiveIndicatorElement(element) { + if (this._indicatorsElement) { + $(this._indicatorsElement) + .find(Selector.ACTIVE) + .removeClass(ClassName.ACTIVE) + + const nextIndicator = this._indicatorsElement.children[ + this._getItemIndex(element) + ] + + if (nextIndicator) { + $(nextIndicator).addClass(ClassName.ACTIVE) + } + } + } + + _slide(direction, element) { + const activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0] + const nextElement = element || activeElement && + this._getItemByDirection(direction, activeElement) + + const isCycling = Boolean(this._interval) + + let directionalClassName + let orderClassName + let eventDirectionName + + if (direction === Direction.NEXT) { + directionalClassName = ClassName.LEFT + orderClassName = ClassName.NEXT + eventDirectionName = Direction.LEFT + } else { + directionalClassName = ClassName.RIGHT + orderClassName = ClassName.PREV + eventDirectionName = Direction.RIGHT + } + + if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) { + this._isSliding = false + return + } + + const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName) + if (slideEvent.isDefaultPrevented()) { + return + } + + if (!activeElement || !nextElement) { + // some weirdness is happening, so we bail + return + } + + this._isSliding = true + + if (isCycling) { + this.pause() + } + + this._setActiveIndicatorElement(nextElement) + + const slidEvent = $.Event(Event.SLID, { + relatedTarget: nextElement, + direction: eventDirectionName + }) + + if (Util.supportsTransitionEnd() && + $(this._element).hasClass(ClassName.SLIDE)) { + + $(nextElement).addClass(orderClassName) + + Util.reflow(nextElement) + + $(activeElement).addClass(directionalClassName) + $(nextElement).addClass(directionalClassName) + + $(activeElement) + .one(Util.TRANSITION_END, () => { + $(nextElement) + .removeClass(`${directionalClassName} ${orderClassName}`) + .addClass(ClassName.ACTIVE) + + $(activeElement).removeClass(`${ClassName.ACTIVE} ${orderClassName} ${directionalClassName}`) + + this._isSliding = false + + setTimeout(() => $(this._element).trigger(slidEvent), 0) + + }) + .emulateTransitionEnd(TRANSITION_DURATION) + + } else { + $(activeElement).removeClass(ClassName.ACTIVE) + $(nextElement).addClass(ClassName.ACTIVE) + + this._isSliding = false + $(this._element).trigger(slidEvent) + } + + if (isCycling) { + this.cycle() + } + } + + + // static + + static _jQueryInterface(config) { + return this.each(function () { + let data = $(this).data(DATA_KEY) + const _config = $.extend({}, Default, $(this).data()) + + if (typeof config === 'object') { + $.extend(_config, config) + } + + const action = typeof config === 'string' ? config : _config.slide + + if (!data) { + data = new Carousel(this, _config) + $(this).data(DATA_KEY, data) + } + + if (typeof config === 'number') { + data.to(config) + } else if (typeof action === 'string') { + if (data[action] === undefined) { + throw new Error(`No method named "${action}"`) + } + data[action]() + } else if (_config.interval) { + data.pause() + data.cycle() + } + }) + } + + static _dataApiClickHandler(event) { + const selector = Util.getSelectorFromElement(this) + + if (!selector) { + return + } + + const target = $(selector)[0] + + if (!target || !$(target).hasClass(ClassName.CAROUSEL)) { + return + } + + const config = $.extend({}, $(target).data(), $(this).data()) + const slideIndex = this.getAttribute('data-slide-to') + + if (slideIndex) { + config.interval = false + } + + Carousel._jQueryInterface.call($(target), config) + + if (slideIndex) { + $(target).data(DATA_KEY).to(slideIndex) + } + + event.preventDefault() + } + + } + + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + $(document) + .on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler) + + $(window).on(Event.LOAD_DATA_API, () => { + $(Selector.DATA_RIDE).each(function () { + const $carousel = $(this) + Carousel._jQueryInterface.call($carousel, $carousel.data()) + }) + }) + + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Carousel._jQueryInterface + $.fn[NAME].Constructor = Carousel + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Carousel._jQueryInterface + } + + return Carousel + +})(jQuery) + +export default Carousel diff --git a/templates/assets/bootstrap/js/src/collapse.js b/templates/assets/bootstrap/js/src/collapse.js new file mode 100644 index 0000000..13c4450 --- /dev/null +++ b/templates/assets/bootstrap/js/src/collapse.js @@ -0,0 +1,393 @@ +import Util from './util' + + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.6): collapse.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const Collapse = (($) => { + + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + const NAME = 'collapse' + const VERSION = '4.0.0-alpha.6' + const DATA_KEY = 'bs.collapse' + const EVENT_KEY = `.${DATA_KEY}` + const DATA_API_KEY = '.data-api' + const JQUERY_NO_CONFLICT = $.fn[NAME] + const TRANSITION_DURATION = 600 + + const Default = { + toggle : true, + parent : '' + } + + const DefaultType = { + toggle : 'boolean', + parent : 'string' + } + + const Event = { + SHOW : `show${EVENT_KEY}`, + SHOWN : `shown${EVENT_KEY}`, + HIDE : `hide${EVENT_KEY}`, + HIDDEN : `hidden${EVENT_KEY}`, + CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}` + } + + const ClassName = { + SHOW : 'show', + COLLAPSE : 'collapse', + COLLAPSING : 'collapsing', + COLLAPSED : 'collapsed' + } + + const Dimension = { + WIDTH : 'width', + HEIGHT : 'height' + } + + const Selector = { + ACTIVES : '.card > .show, .card > .collapsing', + DATA_TOGGLE : '[data-toggle="collapse"]', + DATA_CHILDREN : 'data-children' + } + + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + class Collapse { + + constructor(element, config) { + this._isTransitioning = false + this._element = element + this._config = this._getConfig(config) + this._triggerArray = $.makeArray($( + `[data-toggle="collapse"][href="#${element.id}"],` + + `[data-toggle="collapse"][data-target="#${element.id}"]` + )) + this._parent = this._config.parent ? this._getParent() : null + + if (!this._config.parent) { + this._addAriaAndCollapsedClass(this._element, this._triggerArray) + } + + this._selectorActives = Selector.ACTIVES + if (this._parent) { + const childrenSelector = this._parent.hasAttribute(Selector.DATA_CHILDREN) ? this._parent.getAttribute(Selector.DATA_CHILDREN) : null + if (childrenSelector !== null) { + this._selectorActives = `${childrenSelector} > .show, ${childrenSelector} > .collapsing` + } + } + + if (this._config.toggle) { + this.toggle() + } + } + + + // getters + + static get VERSION() { + return VERSION + } + + static get Default() { + return Default + } + + + // public + + toggle() { + if ($(this._element).hasClass(ClassName.SHOW)) { + this.hide() + } else { + this.show() + } + } + + show() { + if (this._isTransitioning) { + throw new Error('Collapse is transitioning') + } + + if ($(this._element).hasClass(ClassName.SHOW)) { + return + } + + let actives + let activesData + + if (this._parent) { + actives = $.makeArray($(this._parent).find(this._selectorActives)) + if (!actives.length) { + actives = null + } + } + + if (actives) { + activesData = $(actives).data(DATA_KEY) + if (activesData && activesData._isTransitioning) { + return + } + } + + const startEvent = $.Event(Event.SHOW) + $(this._element).trigger(startEvent) + if (startEvent.isDefaultPrevented()) { + return + } + + if (actives) { + Collapse._jQueryInterface.call($(actives), 'hide') + if (!activesData) { + $(actives).data(DATA_KEY, null) + } + } + + const dimension = this._getDimension() + + $(this._element) + .removeClass(ClassName.COLLAPSE) + .addClass(ClassName.COLLAPSING) + + this._element.style[dimension] = 0 + this._element.setAttribute('aria-expanded', true) + + if (this._triggerArray.length) { + $(this._triggerArray) + .removeClass(ClassName.COLLAPSED) + .attr('aria-expanded', true) + } + + this.setTransitioning(true) + + const complete = () => { + $(this._element) + .removeClass(ClassName.COLLAPSING) + .addClass(ClassName.COLLAPSE) + .addClass(ClassName.SHOW) + + this._element.style[dimension] = '' + + this.setTransitioning(false) + + $(this._element).trigger(Event.SHOWN) + } + + if (!Util.supportsTransitionEnd()) { + complete() + return + } + + const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1) + const scrollSize = `scroll${capitalizedDimension}` + + $(this._element) + .one(Util.TRANSITION_END, complete) + .emulateTransitionEnd(TRANSITION_DURATION) + + this._element.style[dimension] = `${this._element[scrollSize]}px` + } + + hide() { + if (this._isTransitioning) { + throw new Error('Collapse is transitioning') + } + + if (!$(this._element).hasClass(ClassName.SHOW)) { + return + } + + const startEvent = $.Event(Event.HIDE) + $(this._element).trigger(startEvent) + if (startEvent.isDefaultPrevented()) { + return + } + + const dimension = this._getDimension() + + this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px` + + Util.reflow(this._element) + + $(this._element) + .addClass(ClassName.COLLAPSING) + .removeClass(ClassName.COLLAPSE) + .removeClass(ClassName.SHOW) + + this._element.setAttribute('aria-expanded', false) + + if (this._triggerArray.length) { + $(this._triggerArray) + .addClass(ClassName.COLLAPSED) + .attr('aria-expanded', false) + } + + this.setTransitioning(true) + + const complete = () => { + this.setTransitioning(false) + $(this._element) + .removeClass(ClassName.COLLAPSING) + .addClass(ClassName.COLLAPSE) + .trigger(Event.HIDDEN) + } + + this._element.style[dimension] = '' + + if (!Util.supportsTransitionEnd()) { + complete() + return + } + + $(this._element) + .one(Util.TRANSITION_END, complete) + .emulateTransitionEnd(TRANSITION_DURATION) + } + + setTransitioning(isTransitioning) { + this._isTransitioning = isTransitioning + } + + dispose() { + $.removeData(this._element, DATA_KEY) + + this._config = null + this._parent = null + this._element = null + this._triggerArray = null + this._isTransitioning = null + } + + + // private + + _getConfig(config) { + config = $.extend({}, Default, config) + config.toggle = Boolean(config.toggle) // coerce string values + Util.typeCheckConfig(NAME, config, DefaultType) + return config + } + + _getDimension() { + const hasWidth = $(this._element).hasClass(Dimension.WIDTH) + return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT + } + + _getParent() { + const parent = $(this._config.parent)[0] + const selector = + `[data-toggle="collapse"][data-parent="${this._config.parent}"]` + + $(parent).find(selector).each((i, element) => { + this._addAriaAndCollapsedClass( + Collapse._getTargetFromElement(element), + [element] + ) + }) + + return parent + } + + _addAriaAndCollapsedClass(element, triggerArray) { + if (element) { + const isOpen = $(element).hasClass(ClassName.SHOW) + element.setAttribute('aria-expanded', isOpen) + + if (triggerArray.length) { + $(triggerArray) + .toggleClass(ClassName.COLLAPSED, !isOpen) + .attr('aria-expanded', isOpen) + } + } + } + + + // static + + static _getTargetFromElement(element) { + const selector = Util.getSelectorFromElement(element) + return selector ? $(selector)[0] : null + } + + static _jQueryInterface(config) { + return this.each(function () { + const $this = $(this) + let data = $this.data(DATA_KEY) + const _config = $.extend( + {}, + Default, + $this.data(), + typeof config === 'object' && config + ) + + if (!data && _config.toggle && /show|hide/.test(config)) { + _config.toggle = false + } + + if (!data) { + data = new Collapse(this, _config) + $this.data(DATA_KEY, data) + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error(`No method named "${config}"`) + } + data[config]() + } + }) + } + + } + + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { + event.preventDefault() + + const target = Collapse._getTargetFromElement(this) + const data = $(target).data(DATA_KEY) + const config = data ? 'toggle' : $(this).data() + + Collapse._jQueryInterface.call($(target), config) + }) + + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Collapse._jQueryInterface + $.fn[NAME].Constructor = Collapse + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Collapse._jQueryInterface + } + + return Collapse + +})(jQuery) + +export default Collapse diff --git a/templates/assets/bootstrap/js/src/dropdown.js b/templates/assets/bootstrap/js/src/dropdown.js new file mode 100644 index 0000000..644273a --- /dev/null +++ b/templates/assets/bootstrap/js/src/dropdown.js @@ -0,0 +1,307 @@ +import Util from './util' + + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.6): dropdown.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const Dropdown = (($) => { + + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + const NAME = 'dropdown' + const VERSION = '4.0.0-alpha.6' + const DATA_KEY = 'bs.dropdown' + const EVENT_KEY = `.${DATA_KEY}` + const DATA_API_KEY = '.data-api' + const JQUERY_NO_CONFLICT = $.fn[NAME] + const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key + const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key + const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key + const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key + const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse) + const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}|${SPACE_KEYCODE}`) + + const Event = { + HIDE : `hide${EVENT_KEY}`, + HIDDEN : `hidden${EVENT_KEY}`, + SHOW : `show${EVENT_KEY}`, + SHOWN : `shown${EVENT_KEY}`, + CLICK : `click${EVENT_KEY}`, + CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`, + FOCUSIN_DATA_API : `focusin${EVENT_KEY}${DATA_API_KEY}`, + KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}` + } + + const ClassName = { + BACKDROP : 'dropdown-backdrop', + DISABLED : 'disabled', + SHOW : 'show' + } + + const Selector = { + BACKDROP : '.dropdown-backdrop', + DATA_TOGGLE : '[data-toggle="dropdown"]', + FORM_CHILD : '.dropdown form', + ROLE_MENU : '[role="menu"]', + ROLE_LISTBOX : '[role="listbox"]', + NAVBAR_NAV : '.navbar-nav', + VISIBLE_ITEMS : '[role="menu"] li:not(.disabled) a, ' + + '[role="listbox"] li:not(.disabled) a' + } + + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + class Dropdown { + + constructor(element) { + this._element = element + + this._addEventListeners() + } + + + // getters + + static get VERSION() { + return VERSION + } + + + // public + + toggle() { + if (this.disabled || $(this).hasClass(ClassName.DISABLED)) { + return false + } + + const parent = Dropdown._getParentFromElement(this) + const isActive = $(parent).hasClass(ClassName.SHOW) + + Dropdown._clearMenus() + + if (isActive) { + return false + } + + const relatedTarget = { + relatedTarget : this + } + const showEvent = $.Event(Event.SHOW, relatedTarget) + + $(parent).trigger(showEvent) + + if (showEvent.isDefaultPrevented()) { + return false + } + + // set the backdrop only if the dropdown menu will be opened + if ('ontouchstart' in document.documentElement && + !$(parent).closest(Selector.NAVBAR_NAV).length) { + + // if mobile we use a backdrop because click events don't delegate + const dropdown = document.createElement('div') + dropdown.className = ClassName.BACKDROP + $(dropdown).insertBefore(this) + $(dropdown).on('click', Dropdown._clearMenus) + } + + this.focus() + this.setAttribute('aria-expanded', true) + + $(parent).toggleClass(ClassName.SHOW) + $(parent).trigger($.Event(Event.SHOWN, relatedTarget)) + + return false + } + + dispose() { + $.removeData(this._element, DATA_KEY) + $(this._element).off(EVENT_KEY) + this._element = null + } + + + // private + + _addEventListeners() { + $(this._element).on(Event.CLICK, this.toggle) + } + + + // static + + static _jQueryInterface(config) { + return this.each(function () { + let data = $(this).data(DATA_KEY) + + if (!data) { + data = new Dropdown(this) + $(this).data(DATA_KEY, data) + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error(`No method named "${config}"`) + } + data[config].call(this) + } + }) + } + + static _clearMenus(event) { + if (event && event.which === RIGHT_MOUSE_BUTTON_WHICH) { + return + } + + const toggles = $.makeArray($(Selector.DATA_TOGGLE)) + + for (let i = 0; i < toggles.length; i++) { + const parent = Dropdown._getParentFromElement(toggles[i]) + const relatedTarget = { + relatedTarget : toggles[i] + } + + if (!$(parent).hasClass(ClassName.SHOW)) { + continue + } + + if (event && (event.type === 'click' && + /input|textarea/i.test(event.target.tagName) || event.type === 'focusin') + && $.contains(parent, event.target)) { + continue + } + + const hideEvent = $.Event(Event.HIDE, relatedTarget) + $(parent).trigger(hideEvent) + if (hideEvent.isDefaultPrevented()) { + continue + } + + // remove backdrop only if the dropdown menu will be hidden + const backdrop = $(parent).find(Selector.BACKDROP)[0] + if (backdrop) { + backdrop.parentNode.removeChild(backdrop) + } + + toggles[i].setAttribute('aria-expanded', 'false') + + $(parent) + .removeClass(ClassName.SHOW) + .trigger($.Event(Event.HIDDEN, relatedTarget)) + } + } + + static _getParentFromElement(element) { + let parent + const selector = Util.getSelectorFromElement(element) + + if (selector) { + parent = $(selector)[0] + } + + return parent || element.parentNode + } + + static _dataApiKeydownHandler(event) { + if (!REGEXP_KEYDOWN.test(event.which) || + /input|textarea/i.test(event.target.tagName)) { + return + } + + event.preventDefault() + event.stopPropagation() + + if (this.disabled || $(this).hasClass(ClassName.DISABLED)) { + return + } + + const parent = Dropdown._getParentFromElement(this) + const isActive = $(parent).hasClass(ClassName.SHOW) + + if (!isActive && event.which !== ESCAPE_KEYCODE || + isActive && event.which === ESCAPE_KEYCODE) { + + if (event.which === ESCAPE_KEYCODE) { + const toggle = $(parent).find(Selector.DATA_TOGGLE)[0] + $(toggle).trigger('focus') + } + + $(this).trigger('click') + return + } + + const items = $(parent).find(Selector.VISIBLE_ITEMS).get() + + if (!items.length) { + return + } + + let index = items.indexOf(event.target) + + if (event.which === ARROW_UP_KEYCODE && index > 0) { // up + index-- + } + + if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // down + index++ + } + + if (index < 0) { + index = 0 + } + + items[index].focus() + } + + } + + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + $(document) + .on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler) + .on(Event.KEYDOWN_DATA_API, Selector.ROLE_MENU, Dropdown._dataApiKeydownHandler) + .on(Event.KEYDOWN_DATA_API, Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler) + .on(`${Event.CLICK_DATA_API} ${Event.FOCUSIN_DATA_API}`, Dropdown._clearMenus) + .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, Dropdown.prototype.toggle) + .on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => { + e.stopPropagation() + }) + + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Dropdown._jQueryInterface + $.fn[NAME].Constructor = Dropdown + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Dropdown._jQueryInterface + } + + return Dropdown + +})(jQuery) + +export default Dropdown diff --git a/templates/assets/bootstrap/js/src/modal.js b/templates/assets/bootstrap/js/src/modal.js new file mode 100644 index 0000000..9263efd --- /dev/null +++ b/templates/assets/bootstrap/js/src/modal.js @@ -0,0 +1,545 @@ +import Util from './util' + + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.6): modal.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const Modal = (($) => { + + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + const NAME = 'modal' + const VERSION = '4.0.0-alpha.6' + const DATA_KEY = 'bs.modal' + const EVENT_KEY = `.${DATA_KEY}` + const DATA_API_KEY = '.data-api' + const JQUERY_NO_CONFLICT = $.fn[NAME] + const TRANSITION_DURATION = 300 + const BACKDROP_TRANSITION_DURATION = 150 + const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key + + const Default = { + backdrop : true, + keyboard : true, + focus : true, + show : true + } + + const DefaultType = { + backdrop : '(boolean|string)', + keyboard : 'boolean', + focus : 'boolean', + show : 'boolean' + } + + const Event = { + HIDE : `hide${EVENT_KEY}`, + HIDDEN : `hidden${EVENT_KEY}`, + SHOW : `show${EVENT_KEY}`, + SHOWN : `shown${EVENT_KEY}`, + FOCUSIN : `focusin${EVENT_KEY}`, + RESIZE : `resize${EVENT_KEY}`, + CLICK_DISMISS : `click.dismiss${EVENT_KEY}`, + KEYDOWN_DISMISS : `keydown.dismiss${EVENT_KEY}`, + MOUSEUP_DISMISS : `mouseup.dismiss${EVENT_KEY}`, + MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`, + CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}` + } + + const ClassName = { + SCROLLBAR_MEASURER : 'modal-scrollbar-measure', + BACKDROP : 'modal-backdrop', + OPEN : 'modal-open', + FADE : 'fade', + SHOW : 'show' + } + + const Selector = { + DIALOG : '.modal-dialog', + DATA_TOGGLE : '[data-toggle="modal"]', + DATA_DISMISS : '[data-dismiss="modal"]', + FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top' + } + + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + class Modal { + + constructor(element, config) { + this._config = this._getConfig(config) + this._element = element + this._dialog = $(element).find(Selector.DIALOG)[0] + this._backdrop = null + this._isShown = false + this._isBodyOverflowing = false + this._ignoreBackdropClick = false + this._isTransitioning = false + this._originalBodyPadding = 0 + this._scrollbarWidth = 0 + } + + + // getters + + static get VERSION() { + return VERSION + } + + static get Default() { + return Default + } + + + // public + + toggle(relatedTarget) { + return this._isShown ? this.hide() : this.show(relatedTarget) + } + + show(relatedTarget) { + if (this._isTransitioning) { + throw new Error('Modal is transitioning') + } + + if (Util.supportsTransitionEnd() && + $(this._element).hasClass(ClassName.FADE)) { + this._isTransitioning = true + } + const showEvent = $.Event(Event.SHOW, { + relatedTarget + }) + + $(this._element).trigger(showEvent) + + if (this._isShown || showEvent.isDefaultPrevented()) { + return + } + + this._isShown = true + + this._checkScrollbar() + this._setScrollbar() + + $(document.body).addClass(ClassName.OPEN) + + this._setEscapeEvent() + this._setResizeEvent() + + $(this._element).on( + Event.CLICK_DISMISS, + Selector.DATA_DISMISS, + (event) => this.hide(event) + ) + + $(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => { + $(this._element).one(Event.MOUSEUP_DISMISS, (event) => { + if ($(event.target).is(this._element)) { + this._ignoreBackdropClick = true + } + }) + }) + + this._showBackdrop(() => this._showElement(relatedTarget)) + } + + hide(event) { + if (event) { + event.preventDefault() + } + + if (this._isTransitioning) { + throw new Error('Modal is transitioning') + } + + const transition = Util.supportsTransitionEnd() && + $(this._element).hasClass(ClassName.FADE) + if (transition) { + this._isTransitioning = true + } + + const hideEvent = $.Event(Event.HIDE) + $(this._element).trigger(hideEvent) + + if (!this._isShown || hideEvent.isDefaultPrevented()) { + return + } + + this._isShown = false + + this._setEscapeEvent() + this._setResizeEvent() + + $(document).off(Event.FOCUSIN) + + $(this._element).removeClass(ClassName.SHOW) + + $(this._element).off(Event.CLICK_DISMISS) + $(this._dialog).off(Event.MOUSEDOWN_DISMISS) + + if (transition) { + $(this._element) + .one(Util.TRANSITION_END, (event) => this._hideModal(event)) + .emulateTransitionEnd(TRANSITION_DURATION) + } else { + this._hideModal() + } + } + + dispose() { + $.removeData(this._element, DATA_KEY) + + $(window, document, this._element, this._backdrop).off(EVENT_KEY) + + this._config = null + this._element = null + this._dialog = null + this._backdrop = null + this._isShown = null + this._isBodyOverflowing = null + this._ignoreBackdropClick = null + this._originalBodyPadding = null + this._scrollbarWidth = null + } + + + // private + + _getConfig(config) { + config = $.extend({}, Default, config) + Util.typeCheckConfig(NAME, config, DefaultType) + return config + } + + _showElement(relatedTarget) { + const transition = Util.supportsTransitionEnd() && + $(this._element).hasClass(ClassName.FADE) + + if (!this._element.parentNode || + this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { + // don't move modals dom position + document.body.appendChild(this._element) + } + + this._element.style.display = 'block' + this._element.removeAttribute('aria-hidden') + this._element.scrollTop = 0 + + if (transition) { + Util.reflow(this._element) + } + + $(this._element).addClass(ClassName.SHOW) + + if (this._config.focus) { + this._enforceFocus() + } + + const shownEvent = $.Event(Event.SHOWN, { + relatedTarget + }) + + const transitionComplete = () => { + if (this._config.focus) { + this._element.focus() + } + this._isTransitioning = false + $(this._element).trigger(shownEvent) + } + + if (transition) { + $(this._dialog) + .one(Util.TRANSITION_END, transitionComplete) + .emulateTransitionEnd(TRANSITION_DURATION) + } else { + transitionComplete() + } + } + + _enforceFocus() { + $(document) + .off(Event.FOCUSIN) // guard against infinite focus loop + .on(Event.FOCUSIN, (event) => { + if (document !== event.target && + this._element !== event.target && + !$(this._element).has(event.target).length) { + this._element.focus() + } + }) + } + + _setEscapeEvent() { + if (this._isShown && this._config.keyboard) { + $(this._element).on(Event.KEYDOWN_DISMISS, (event) => { + if (event.which === ESCAPE_KEYCODE) { + this.hide() + } + }) + + } else if (!this._isShown) { + $(this._element).off(Event.KEYDOWN_DISMISS) + } + } + + _setResizeEvent() { + if (this._isShown) { + $(window).on(Event.RESIZE, (event) => this._handleUpdate(event)) + } else { + $(window).off(Event.RESIZE) + } + } + + _hideModal() { + this._element.style.display = 'none' + this._element.setAttribute('aria-hidden', 'true') + this._isTransitioning = false + this._showBackdrop(() => { + $(document.body).removeClass(ClassName.OPEN) + this._resetAdjustments() + this._resetScrollbar() + $(this._element).trigger(Event.HIDDEN) + }) + } + + _removeBackdrop() { + if (this._backdrop) { + $(this._backdrop).remove() + this._backdrop = null + } + } + + _showBackdrop(callback) { + const animate = $(this._element).hasClass(ClassName.FADE) ? + ClassName.FADE : '' + + if (this._isShown && this._config.backdrop) { + const doAnimate = Util.supportsTransitionEnd() && animate + + this._backdrop = document.createElement('div') + this._backdrop.className = ClassName.BACKDROP + + if (animate) { + $(this._backdrop).addClass(animate) + } + + $(this._backdrop).appendTo(document.body) + + $(this._element).on(Event.CLICK_DISMISS, (event) => { + if (this._ignoreBackdropClick) { + this._ignoreBackdropClick = false + return + } + if (event.target !== event.currentTarget) { + return + } + if (this._config.backdrop === 'static') { + this._element.focus() + } else { + this.hide() + } + }) + + if (doAnimate) { + Util.reflow(this._backdrop) + } + + $(this._backdrop).addClass(ClassName.SHOW) + + if (!callback) { + return + } + + if (!doAnimate) { + callback() + return + } + + $(this._backdrop) + .one(Util.TRANSITION_END, callback) + .emulateTransitionEnd(BACKDROP_TRANSITION_DURATION) + + } else if (!this._isShown && this._backdrop) { + $(this._backdrop).removeClass(ClassName.SHOW) + + const callbackRemove = () => { + this._removeBackdrop() + if (callback) { + callback() + } + } + + if (Util.supportsTransitionEnd() && + $(this._element).hasClass(ClassName.FADE)) { + $(this._backdrop) + .one(Util.TRANSITION_END, callbackRemove) + .emulateTransitionEnd(BACKDROP_TRANSITION_DURATION) + } else { + callbackRemove() + } + + } else if (callback) { + callback() + } + } + + + // ---------------------------------------------------------------------- + // the following methods are used to handle overflowing modals + // todo (fat): these should probably be refactored out of modal.js + // ---------------------------------------------------------------------- + + _handleUpdate() { + this._adjustDialog() + } + + _adjustDialog() { + const isModalOverflowing = + this._element.scrollHeight > document.documentElement.clientHeight + + if (!this._isBodyOverflowing && isModalOverflowing) { + this._element.style.paddingLeft = `${this._scrollbarWidth}px` + } + + if (this._isBodyOverflowing && !isModalOverflowing) { + this._element.style.paddingRight = `${this._scrollbarWidth}px` + } + } + + _resetAdjustments() { + this._element.style.paddingLeft = '' + this._element.style.paddingRight = '' + } + + _checkScrollbar() { + this._isBodyOverflowing = document.body.clientWidth < window.innerWidth + this._scrollbarWidth = this._getScrollbarWidth() + } + + _setScrollbar() { + const bodyPadding = parseInt( + $(Selector.FIXED_CONTENT).css('padding-right') || 0, + 10 + ) + + this._originalBodyPadding = document.body.style.paddingRight || '' + + if (this._isBodyOverflowing) { + document.body.style.paddingRight = + `${bodyPadding + this._scrollbarWidth}px` + } + } + + _resetScrollbar() { + document.body.style.paddingRight = this._originalBodyPadding + } + + _getScrollbarWidth() { // thx d.walsh + const scrollDiv = document.createElement('div') + scrollDiv.className = ClassName.SCROLLBAR_MEASURER + document.body.appendChild(scrollDiv) + const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth + document.body.removeChild(scrollDiv) + return scrollbarWidth + } + + + // static + + static _jQueryInterface(config, relatedTarget) { + return this.each(function () { + let data = $(this).data(DATA_KEY) + const _config = $.extend( + {}, + Modal.Default, + $(this).data(), + typeof config === 'object' && config + ) + + if (!data) { + data = new Modal(this, _config) + $(this).data(DATA_KEY, data) + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error(`No method named "${config}"`) + } + data[config](relatedTarget) + } else if (_config.show) { + data.show(relatedTarget) + } + }) + } + + } + + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { + let target + const selector = Util.getSelectorFromElement(this) + + if (selector) { + target = $(selector)[0] + } + + const config = $(target).data(DATA_KEY) ? + 'toggle' : $.extend({}, $(target).data(), $(this).data()) + + if (this.tagName === 'A' || this.tagName === 'AREA') { + event.preventDefault() + } + + const $target = $(target).one(Event.SHOW, (showEvent) => { + if (showEvent.isDefaultPrevented()) { + // only register focus restorer if modal will actually get shown + return + } + + $target.one(Event.HIDDEN, () => { + if ($(this).is(':visible')) { + this.focus() + } + }) + }) + + Modal._jQueryInterface.call($(target), config, this) + }) + + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Modal._jQueryInterface + $.fn[NAME].Constructor = Modal + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Modal._jQueryInterface + } + + return Modal + +})(jQuery) + +export default Modal diff --git a/templates/assets/bootstrap/js/src/popover.js b/templates/assets/bootstrap/js/src/popover.js new file mode 100644 index 0000000..b68b479 --- /dev/null +++ b/templates/assets/bootstrap/js/src/popover.js @@ -0,0 +1,179 @@ +import Tooltip from './tooltip' + + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.6): popover.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const Popover = (($) => { + + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + const NAME = 'popover' + const VERSION = '4.0.0-alpha.6' + const DATA_KEY = 'bs.popover' + const EVENT_KEY = `.${DATA_KEY}` + const JQUERY_NO_CONFLICT = $.fn[NAME] + + const Default = $.extend({}, Tooltip.Default, { + placement : 'right', + trigger : 'click', + content : '', + template : '<div class="popover" role="tooltip">' + + '<h3 class="popover-title"></h3>' + + '<div class="popover-content"></div></div>' + }) + + const DefaultType = $.extend({}, Tooltip.DefaultType, { + content : '(string|element|function)' + }) + + const ClassName = { + FADE : 'fade', + SHOW : 'show' + } + + const Selector = { + TITLE : '.popover-title', + CONTENT : '.popover-content' + } + + const Event = { + HIDE : `hide${EVENT_KEY}`, + HIDDEN : `hidden${EVENT_KEY}`, + SHOW : `show${EVENT_KEY}`, + SHOWN : `shown${EVENT_KEY}`, + INSERTED : `inserted${EVENT_KEY}`, + CLICK : `click${EVENT_KEY}`, + FOCUSIN : `focusin${EVENT_KEY}`, + FOCUSOUT : `focusout${EVENT_KEY}`, + MOUSEENTER : `mouseenter${EVENT_KEY}`, + MOUSELEAVE : `mouseleave${EVENT_KEY}` + } + + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + class Popover extends Tooltip { + + + // getters + + static get VERSION() { + return VERSION + } + + static get Default() { + return Default + } + + static get NAME() { + return NAME + } + + static get DATA_KEY() { + return DATA_KEY + } + + static get Event() { + return Event + } + + static get EVENT_KEY() { + return EVENT_KEY + } + + static get DefaultType() { + return DefaultType + } + + + // overrides + + isWithContent() { + return this.getTitle() || this._getContent() + } + + getTipElement() { + return this.tip = this.tip || $(this.config.template)[0] + } + + setContent() { + const $tip = $(this.getTipElement()) + + // we use append for html objects to maintain js events + this.setElementContent($tip.find(Selector.TITLE), this.getTitle()) + this.setElementContent($tip.find(Selector.CONTENT), this._getContent()) + + $tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`) + + this.cleanupTether() + } + + // private + + _getContent() { + return this.element.getAttribute('data-content') + || (typeof this.config.content === 'function' ? + this.config.content.call(this.element) : + this.config.content) + } + + + // static + + static _jQueryInterface(config) { + return this.each(function () { + let data = $(this).data(DATA_KEY) + const _config = typeof config === 'object' ? config : null + + if (!data && /destroy|hide/.test(config)) { + return + } + + if (!data) { + data = new Popover(this, _config) + $(this).data(DATA_KEY, data) + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error(`No method named "${config}"`) + } + data[config]() + } + }) + } + } + + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Popover._jQueryInterface + $.fn[NAME].Constructor = Popover + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Popover._jQueryInterface + } + + return Popover + +})(jQuery) + +export default Popover diff --git a/templates/assets/bootstrap/js/src/scrollspy.js b/templates/assets/bootstrap/js/src/scrollspy.js new file mode 100644 index 0000000..15541b8 --- /dev/null +++ b/templates/assets/bootstrap/js/src/scrollspy.js @@ -0,0 +1,335 @@ +import Util from './util' + + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.6): scrollspy.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const ScrollSpy = (($) => { + + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + const NAME = 'scrollspy' + const VERSION = '4.0.0-alpha.6' + const DATA_KEY = 'bs.scrollspy' + const EVENT_KEY = `.${DATA_KEY}` + const DATA_API_KEY = '.data-api' + const JQUERY_NO_CONFLICT = $.fn[NAME] + + const Default = { + offset : 10, + method : 'auto', + target : '' + } + + const DefaultType = { + offset : 'number', + method : 'string', + target : '(string|element)' + } + + const Event = { + ACTIVATE : `activate${EVENT_KEY}`, + SCROLL : `scroll${EVENT_KEY}`, + LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}` + } + + const ClassName = { + DROPDOWN_ITEM : 'dropdown-item', + DROPDOWN_MENU : 'dropdown-menu', + NAV_LINK : 'nav-link', + NAV : 'nav', + ACTIVE : 'active' + } + + const Selector = { + DATA_SPY : '[data-spy="scroll"]', + ACTIVE : '.active', + LIST_ITEM : '.list-item', + LI : 'li', + LI_DROPDOWN : 'li.dropdown', + NAV_LINKS : '.nav-link', + DROPDOWN : '.dropdown', + DROPDOWN_ITEMS : '.dropdown-item', + DROPDOWN_TOGGLE : '.dropdown-toggle' + } + + const OffsetMethod = { + OFFSET : 'offset', + POSITION : 'position' + } + + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + class ScrollSpy { + + constructor(element, config) { + this._element = element + this._scrollElement = element.tagName === 'BODY' ? window : element + this._config = this._getConfig(config) + this._selector = `${this._config.target} ${Selector.NAV_LINKS},` + + `${this._config.target} ${Selector.DROPDOWN_ITEMS}` + this._offsets = [] + this._targets = [] + this._activeTarget = null + this._scrollHeight = 0 + + $(this._scrollElement).on(Event.SCROLL, (event) => this._process(event)) + + this.refresh() + this._process() + } + + + // getters + + static get VERSION() { + return VERSION + } + + static get Default() { + return Default + } + + + // public + + refresh() { + const autoMethod = this._scrollElement !== this._scrollElement.window ? + OffsetMethod.POSITION : OffsetMethod.OFFSET + + const offsetMethod = this._config.method === 'auto' ? + autoMethod : this._config.method + + const offsetBase = offsetMethod === OffsetMethod.POSITION ? + this._getScrollTop() : 0 + + this._offsets = [] + this._targets = [] + + this._scrollHeight = this._getScrollHeight() + + const targets = $.makeArray($(this._selector)) + + targets + .map((element) => { + let target + const targetSelector = Util.getSelectorFromElement(element) + + if (targetSelector) { + target = $(targetSelector)[0] + } + + if (target) { + const targetBCR = target.getBoundingClientRect() + if (targetBCR.width || targetBCR.height) { + // todo (fat): remove sketch reliance on jQuery position/offset + return [ + $(target)[offsetMethod]().top + offsetBase, + targetSelector + ] + } + } + return null + }) + .filter((item) => item) + .sort((a, b) => a[0] - b[0]) + .forEach((item) => { + this._offsets.push(item[0]) + this._targets.push(item[1]) + }) + } + + dispose() { + $.removeData(this._element, DATA_KEY) + $(this._scrollElement).off(EVENT_KEY) + + this._element = null + this._scrollElement = null + this._config = null + this._selector = null + this._offsets = null + this._targets = null + this._activeTarget = null + this._scrollHeight = null + } + + + // private + + _getConfig(config) { + config = $.extend({}, Default, config) + + if (typeof config.target !== 'string') { + let id = $(config.target).attr('id') + if (!id) { + id = Util.getUID(NAME) + $(config.target).attr('id', id) + } + config.target = `#${id}` + } + + Util.typeCheckConfig(NAME, config, DefaultType) + + return config + } + + _getScrollTop() { + return this._scrollElement === window ? + this._scrollElement.pageYOffset : this._scrollElement.scrollTop + } + + _getScrollHeight() { + return this._scrollElement.scrollHeight || Math.max( + document.body.scrollHeight, + document.documentElement.scrollHeight + ) + } + + _getOffsetHeight() { + return this._scrollElement === window ? + window.innerHeight : this._scrollElement.getBoundingClientRect().height + } + + _process() { + const scrollTop = this._getScrollTop() + this._config.offset + const scrollHeight = this._getScrollHeight() + const maxScroll = this._config.offset + + scrollHeight + - this._getOffsetHeight() + + if (this._scrollHeight !== scrollHeight) { + this.refresh() + } + + if (scrollTop >= maxScroll) { + const target = this._targets[this._targets.length - 1] + + if (this._activeTarget !== target) { + this._activate(target) + } + return + } + + if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) { + this._activeTarget = null + this._clear() + return + } + + for (let i = this._offsets.length; i--;) { + const isActiveTarget = this._activeTarget !== this._targets[i] + && scrollTop >= this._offsets[i] + && (this._offsets[i + 1] === undefined || + scrollTop < this._offsets[i + 1]) + + if (isActiveTarget) { + this._activate(this._targets[i]) + } + } + } + + _activate(target) { + this._activeTarget = target + + this._clear() + + let queries = this._selector.split(',') + queries = queries.map((selector) => { + return `${selector}[data-target="${target}"],` + + `${selector}[href="${target}"]` + }) + + const $link = $(queries.join(',')) + + if ($link.hasClass(ClassName.DROPDOWN_ITEM)) { + $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE) + $link.addClass(ClassName.ACTIVE) + } else { + // todo (fat) this is kinda sus... + // recursively add actives to tested nav-links + $link.parents(Selector.LI).find(`> ${Selector.NAV_LINKS}`).addClass(ClassName.ACTIVE) + } + + $(this._scrollElement).trigger(Event.ACTIVATE, { + relatedTarget: target + }) + } + + _clear() { + $(this._selector).filter(Selector.ACTIVE).removeClass(ClassName.ACTIVE) + } + + + // static + + static _jQueryInterface(config) { + return this.each(function () { + let data = $(this).data(DATA_KEY) + const _config = typeof config === 'object' && config + + if (!data) { + data = new ScrollSpy(this, _config) + $(this).data(DATA_KEY, data) + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error(`No method named "${config}"`) + } + data[config]() + } + }) + } + + + } + + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + $(window).on(Event.LOAD_DATA_API, () => { + const scrollSpys = $.makeArray($(Selector.DATA_SPY)) + + for (let i = scrollSpys.length; i--;) { + const $spy = $(scrollSpys[i]) + ScrollSpy._jQueryInterface.call($spy, $spy.data()) + } + }) + + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = ScrollSpy._jQueryInterface + $.fn[NAME].Constructor = ScrollSpy + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT + return ScrollSpy._jQueryInterface + } + + return ScrollSpy + +})(jQuery) + +export default ScrollSpy diff --git a/templates/assets/bootstrap/js/src/tab.js b/templates/assets/bootstrap/js/src/tab.js new file mode 100644 index 0000000..d5669b7 --- /dev/null +++ b/templates/assets/bootstrap/js/src/tab.js @@ -0,0 +1,284 @@ +import Util from './util' + + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.6): tab.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const Tab = (($) => { + + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + const NAME = 'tab' + const VERSION = '4.0.0-alpha.6' + const DATA_KEY = 'bs.tab' + const EVENT_KEY = `.${DATA_KEY}` + const DATA_API_KEY = '.data-api' + const JQUERY_NO_CONFLICT = $.fn[NAME] + const TRANSITION_DURATION = 150 + + const Event = { + HIDE : `hide${EVENT_KEY}`, + HIDDEN : `hidden${EVENT_KEY}`, + SHOW : `show${EVENT_KEY}`, + SHOWN : `shown${EVENT_KEY}`, + CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}` + } + + const ClassName = { + DROPDOWN_MENU : 'dropdown-menu', + ACTIVE : 'active', + DISABLED : 'disabled', + FADE : 'fade', + SHOW : 'show' + } + + const Selector = { + A : 'a', + LI : 'li', + DROPDOWN : '.dropdown', + LIST : 'ul:not(.dropdown-menu), ol:not(.dropdown-menu), nav:not(.dropdown-menu), .list-group:not(.dropdown-menu)', + FADE_CHILD : '> .nav-item .fade, > .list-group-item .fade, > .fade', + ACTIVE : '.active', + ACTIVE_CHILD : '> .nav-item > .active, > .list-group-item > .active, > .active', + DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"]', + DROPDOWN_TOGGLE : '.dropdown-toggle', + DROPDOWN_ACTIVE_CHILD : '> .dropdown-menu .active' + } + + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + class Tab { + + constructor(element) { + this._element = element + } + + + // getters + + static get VERSION() { + return VERSION + } + + + // public + + show() { + if (this._element.parentNode && + this._element.parentNode.nodeType === Node.ELEMENT_NODE && + $(this._element).hasClass(ClassName.ACTIVE) || + $(this._element).hasClass(ClassName.DISABLED)) { + return + } + + let target + let previous + const listElement = $(this._element).closest(Selector.LIST)[0] + const selector = Util.getSelectorFromElement(this._element) + + if (listElement) { + previous = $.makeArray($(listElement).find(Selector.ACTIVE)) + previous = previous[previous.length - 1] + } + + const hideEvent = $.Event(Event.HIDE, { + relatedTarget: this._element + }) + + const showEvent = $.Event(Event.SHOW, { + relatedTarget: previous + }) + + if (previous) { + $(previous).trigger(hideEvent) + } + + $(this._element).trigger(showEvent) + + if (showEvent.isDefaultPrevented() || + hideEvent.isDefaultPrevented()) { + return + } + + if (selector) { + target = $(selector)[0] + } + + this._activate( + this._element, + listElement + ) + + const complete = () => { + const hiddenEvent = $.Event(Event.HIDDEN, { + relatedTarget: this._element + }) + + const shownEvent = $.Event(Event.SHOWN, { + relatedTarget: previous + }) + + $(previous).trigger(hiddenEvent) + $(this._element).trigger(shownEvent) + } + + if (target) { + this._activate(target, target.parentNode, complete) + } else { + complete() + } + } + + dispose() { + $.removeClass(this._element, DATA_KEY) + this._element = null + } + + + // private + + _activate(element, container, callback) { + const active = $(container).find(Selector.ACTIVE_CHILD)[0] + const isTransitioning = callback + && Util.supportsTransitionEnd() + && (active && $(active).hasClass(ClassName.FADE) + || Boolean($(container).find(Selector.FADE_CHILD)[0])) + + const complete = () => this._transitionComplete( + element, + active, + isTransitioning, + callback + ) + + if (active && isTransitioning) { + $(active) + .one(Util.TRANSITION_END, complete) + .emulateTransitionEnd(TRANSITION_DURATION) + + } else { + complete() + } + + if (active) { + $(active).removeClass(ClassName.SHOW) + } + } + + _transitionComplete(element, active, isTransitioning, callback) { + if (active) { + $(active).removeClass(ClassName.ACTIVE) + if ($(active).hasClass('list-group-item')) { + $(active).find('a.nav-link').removeClass(ClassName.ACTIVE) + } + + const dropdownChild = $(active.parentNode).find( + Selector.DROPDOWN_ACTIVE_CHILD + )[0] + + if (dropdownChild) { + $(dropdownChild).removeClass(ClassName.ACTIVE) + } + + active.setAttribute('aria-expanded', false) + } + + $(element).addClass(ClassName.ACTIVE) + if ($(element.parentNode).hasClass('list-group-item')) { + $(element.parentNode).addClass(ClassName.ACTIVE) + } + element.setAttribute('aria-expanded', true) + + if (isTransitioning) { + Util.reflow(element) + $(element).addClass(ClassName.SHOW) + } else { + $(element).removeClass(ClassName.FADE) + } + + if (element.parentNode && + $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) { + + const dropdownElement = $(element).closest(Selector.DROPDOWN)[0] + if (dropdownElement) { + $(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE) + } + + element.setAttribute('aria-expanded', true) + } + + if (callback) { + callback() + } + } + + + // static + + static _jQueryInterface(config) { + return this.each(function () { + const $this = $(this) + let data = $this.data(DATA_KEY) + + if (!data) { + data = new Tab(this) + $this.data(DATA_KEY, data) + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error(`No method named "${config}"`) + } + data[config]() + } + }) + } + + } + + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + $(document) + .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { + event.preventDefault() + Tab._jQueryInterface.call($(this), 'show') + }) + + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Tab._jQueryInterface + $.fn[NAME].Constructor = Tab + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Tab._jQueryInterface + } + + return Tab + +})(jQuery) + +export default Tab diff --git a/templates/assets/bootstrap/js/src/tooltip.js b/templates/assets/bootstrap/js/src/tooltip.js new file mode 100644 index 0000000..e750dce --- /dev/null +++ b/templates/assets/bootstrap/js/src/tooltip.js @@ -0,0 +1,675 @@ +/* global Tether */ + +import Util from './util' + + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.6): tooltip.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const Tooltip = (($) => { + + /** + * Check for Tether dependency + * Tether - http://tether.io/ + */ + if (typeof Tether === 'undefined') { + throw new Error('Bootstrap tooltips require Tether (http://tether.io/)') + } + + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + const NAME = 'tooltip' + const VERSION = '4.0.0-alpha.6' + const DATA_KEY = 'bs.tooltip' + const EVENT_KEY = `.${DATA_KEY}` + const JQUERY_NO_CONFLICT = $.fn[NAME] + const TRANSITION_DURATION = 150 + const CLASS_PREFIX = 'bs-tether' + + const Default = { + animation : true, + template : '<div class="tooltip" role="tooltip">' + + '<div class="tooltip-inner"></div></div>', + trigger : 'hover focus', + title : '', + delay : 0, + html : false, + selector : false, + placement : 'top', + offset : '0 0', + constraints : [], + container : false + } + + const DefaultType = { + animation : 'boolean', + template : 'string', + title : '(string|element|function)', + trigger : 'string', + delay : '(number|object)', + html : 'boolean', + selector : '(string|boolean)', + placement : '(string|function)', + offset : 'string', + constraints : 'array', + container : '(string|element|boolean)' + } + + const AttachmentMap = { + TOP : 'bottom center', + RIGHT : 'middle left', + BOTTOM : 'top center', + LEFT : 'middle right' + } + + const HoverState = { + SHOW : 'show', + OUT : 'out' + } + + const Event = { + HIDE : `hide${EVENT_KEY}`, + HIDDEN : `hidden${EVENT_KEY}`, + SHOW : `show${EVENT_KEY}`, + SHOWN : `shown${EVENT_KEY}`, + INSERTED : `inserted${EVENT_KEY}`, + CLICK : `click${EVENT_KEY}`, + FOCUSIN : `focusin${EVENT_KEY}`, + FOCUSOUT : `focusout${EVENT_KEY}`, + MOUSEENTER : `mouseenter${EVENT_KEY}`, + MOUSELEAVE : `mouseleave${EVENT_KEY}` + } + + const ClassName = { + FADE : 'fade', + SHOW : 'show' + } + + const Selector = { + TOOLTIP : '.tooltip', + TOOLTIP_INNER : '.tooltip-inner' + } + + const TetherClass = { + element : false, + enabled : false + } + + const Trigger = { + HOVER : 'hover', + FOCUS : 'focus', + CLICK : 'click', + MANUAL : 'manual' + } + + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + class Tooltip { + + constructor(element, config) { + + // private + this._isEnabled = true + this._timeout = 0 + this._hoverState = '' + this._activeTrigger = {} + this._isTransitioning = false + this._tether = null + + // protected + this.element = element + this.config = this._getConfig(config) + this.tip = null + + this._setListeners() + + } + + + // getters + + static get VERSION() { + return VERSION + } + + static get Default() { + return Default + } + + static get NAME() { + return NAME + } + + static get DATA_KEY() { + return DATA_KEY + } + + static get Event() { + return Event + } + + static get EVENT_KEY() { + return EVENT_KEY + } + + static get DefaultType() { + return DefaultType + } + + + // public + + enable() { + this._isEnabled = true + } + + disable() { + this._isEnabled = false + } + + toggleEnabled() { + this._isEnabled = !this._isEnabled + } + + toggle(event) { + if (event) { + const dataKey = this.constructor.DATA_KEY + let context = $(event.currentTarget).data(dataKey) + + if (!context) { + context = new this.constructor( + event.currentTarget, + this._getDelegateConfig() + ) + $(event.currentTarget).data(dataKey, context) + } + + context._activeTrigger.click = !context._activeTrigger.click + + if (context._isWithActiveTrigger()) { + context._enter(null, context) + } else { + context._leave(null, context) + } + + } else { + + if ($(this.getTipElement()).hasClass(ClassName.SHOW)) { + this._leave(null, this) + return + } + + this._enter(null, this) + } + } + + dispose() { + clearTimeout(this._timeout) + + this.cleanupTether() + + $.removeData(this.element, this.constructor.DATA_KEY) + + $(this.element).off(this.constructor.EVENT_KEY) + $(this.element).closest('.modal').off('hide.bs.modal') + + if (this.tip) { + $(this.tip).remove() + } + + this._isEnabled = null + this._timeout = null + this._hoverState = null + this._activeTrigger = null + this._tether = null + + this.element = null + this.config = null + this.tip = null + } + + show() { + if ($(this.element).css('display') === 'none') { + throw new Error('Please use show on visible elements') + } + + const showEvent = $.Event(this.constructor.Event.SHOW) + if (this.isWithContent() && this._isEnabled) { + if (this._isTransitioning) { + throw new Error('Tooltip is transitioning') + } + $(this.element).trigger(showEvent) + + const isInTheDom = $.contains( + this.element.ownerDocument.documentElement, + this.element + ) + + if (showEvent.isDefaultPrevented() || !isInTheDom) { + return + } + + const tip = this.getTipElement() + const tipId = Util.getUID(this.constructor.NAME) + + tip.setAttribute('id', tipId) + this.element.setAttribute('aria-describedby', tipId) + + this.setContent() + + if (this.config.animation) { + $(tip).addClass(ClassName.FADE) + } + + const placement = typeof this.config.placement === 'function' ? + this.config.placement.call(this, tip, this.element) : + this.config.placement + + const attachment = this._getAttachment(placement) + + const container = this.config.container === false ? document.body : $(this.config.container) + + $(tip) + .data(this.constructor.DATA_KEY, this) + .appendTo(container) + + $(this.element).trigger(this.constructor.Event.INSERTED) + + this._tether = new Tether({ + attachment, + element : tip, + target : this.element, + classes : TetherClass, + classPrefix : CLASS_PREFIX, + offset : this.config.offset, + constraints : this.config.constraints, + addTargetClasses: false + }) + + Util.reflow(tip) + this._tether.position() + + $(tip).addClass(ClassName.SHOW) + + const complete = () => { + const prevHoverState = this._hoverState + this._hoverState = null + this._isTransitioning = false + + $(this.element).trigger(this.constructor.Event.SHOWN) + + if (prevHoverState === HoverState.OUT) { + this._leave(null, this) + } + } + + if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) { + this._isTransitioning = true + $(this.tip) + .one(Util.TRANSITION_END, complete) + .emulateTransitionEnd(Tooltip._TRANSITION_DURATION) + return + } + + complete() + } + } + + hide(callback) { + const tip = this.getTipElement() + const hideEvent = $.Event(this.constructor.Event.HIDE) + if (this._isTransitioning) { + throw new Error('Tooltip is transitioning') + } + const complete = () => { + if (this._hoverState !== HoverState.SHOW && tip.parentNode) { + tip.parentNode.removeChild(tip) + } + + this.element.removeAttribute('aria-describedby') + $(this.element).trigger(this.constructor.Event.HIDDEN) + this._isTransitioning = false + this.cleanupTether() + + if (callback) { + callback() + } + } + + $(this.element).trigger(hideEvent) + + if (hideEvent.isDefaultPrevented()) { + return + } + + $(tip).removeClass(ClassName.SHOW) + + this._activeTrigger[Trigger.CLICK] = false + this._activeTrigger[Trigger.FOCUS] = false + this._activeTrigger[Trigger.HOVER] = false + + if (Util.supportsTransitionEnd() && + $(this.tip).hasClass(ClassName.FADE)) { + this._isTransitioning = true + $(tip) + .one(Util.TRANSITION_END, complete) + .emulateTransitionEnd(TRANSITION_DURATION) + + } else { + complete() + } + + this._hoverState = '' + } + + + // protected + + isWithContent() { + return Boolean(this.getTitle()) + } + + getTipElement() { + return this.tip = this.tip || $(this.config.template)[0] + } + + setContent() { + const $tip = $(this.getTipElement()) + + this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle()) + + $tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`) + + this.cleanupTether() + } + + setElementContent($element, content) { + const html = this.config.html + if (typeof content === 'object' && (content.nodeType || content.jquery)) { + // content is a DOM node or a jQuery + if (html) { + if (!$(content).parent().is($element)) { + $element.empty().append(content) + } + } else { + $element.text($(content).text()) + } + } else { + $element[html ? 'html' : 'text'](content) + } + } + + getTitle() { + let title = this.element.getAttribute('data-original-title') + + if (!title) { + title = typeof this.config.title === 'function' ? + this.config.title.call(this.element) : + this.config.title + } + + return title + } + + cleanupTether() { + if (this._tether) { + this._tether.destroy() + } + } + + + // private + + _getAttachment(placement) { + return AttachmentMap[placement.toUpperCase()] + } + + _setListeners() { + const triggers = this.config.trigger.split(' ') + + triggers.forEach((trigger) => { + if (trigger === 'click') { + $(this.element).on( + this.constructor.Event.CLICK, + this.config.selector, + (event) => this.toggle(event) + ) + + } else if (trigger !== Trigger.MANUAL) { + const eventIn = trigger === Trigger.HOVER ? + this.constructor.Event.MOUSEENTER : + this.constructor.Event.FOCUSIN + const eventOut = trigger === Trigger.HOVER ? + this.constructor.Event.MOUSELEAVE : + this.constructor.Event.FOCUSOUT + + $(this.element) + .on( + eventIn, + this.config.selector, + (event) => this._enter(event) + ) + .on( + eventOut, + this.config.selector, + (event) => this._leave(event) + ) + } + + $(this.element).closest('.modal').on( + 'hide.bs.modal', + () => this.hide() + ) + }) + + if (this.config.selector) { + this.config = $.extend({}, this.config, { + trigger : 'manual', + selector : '' + }) + } else { + this._fixTitle() + } + } + + _fixTitle() { + const titleType = typeof this.element.getAttribute('data-original-title') + if (this.element.getAttribute('title') || + titleType !== 'string') { + this.element.setAttribute( + 'data-original-title', + this.element.getAttribute('title') || '' + ) + this.element.setAttribute('title', '') + } + } + + _enter(event, context) { + const dataKey = this.constructor.DATA_KEY + + context = context || $(event.currentTarget).data(dataKey) + + if (!context) { + context = new this.constructor( + event.currentTarget, + this._getDelegateConfig() + ) + $(event.currentTarget).data(dataKey, context) + } + + if (event) { + context._activeTrigger[ + event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER + ] = true + } + + if ($(context.getTipElement()).hasClass(ClassName.SHOW) || + context._hoverState === HoverState.SHOW) { + context._hoverState = HoverState.SHOW + return + } + + clearTimeout(context._timeout) + + context._hoverState = HoverState.SHOW + + if (!context.config.delay || !context.config.delay.show) { + context.show() + return + } + + context._timeout = setTimeout(() => { + if (context._hoverState === HoverState.SHOW) { + context.show() + } + }, context.config.delay.show) + } + + _leave(event, context) { + const dataKey = this.constructor.DATA_KEY + + context = context || $(event.currentTarget).data(dataKey) + + if (!context) { + context = new this.constructor( + event.currentTarget, + this._getDelegateConfig() + ) + $(event.currentTarget).data(dataKey, context) + } + + if (event) { + context._activeTrigger[ + event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER + ] = false + } + + if (context._isWithActiveTrigger()) { + return + } + + clearTimeout(context._timeout) + + context._hoverState = HoverState.OUT + + if (!context.config.delay || !context.config.delay.hide) { + context.hide() + return + } + + context._timeout = setTimeout(() => { + if (context._hoverState === HoverState.OUT) { + context.hide() + } + }, context.config.delay.hide) + } + + _isWithActiveTrigger() { + for (const trigger in this._activeTrigger) { + if (this._activeTrigger[trigger]) { + return true + } + } + + return false + } + + _getConfig(config) { + config = $.extend( + {}, + this.constructor.Default, + $(this.element).data(), + config + ) + + if (config.delay && typeof config.delay === 'number') { + config.delay = { + show : config.delay, + hide : config.delay + } + } + + Util.typeCheckConfig( + NAME, + config, + this.constructor.DefaultType + ) + + return config + } + + _getDelegateConfig() { + const config = {} + + if (this.config) { + for (const key in this.config) { + if (this.constructor.Default[key] !== this.config[key]) { + config[key] = this.config[key] + } + } + } + + return config + } + + + // static + + static _jQueryInterface(config) { + return this.each(function () { + let data = $(this).data(DATA_KEY) + const _config = typeof config === 'object' && config + + if (!data && /dispose|hide/.test(config)) { + return + } + + if (!data) { + data = new Tooltip(this, _config) + $(this).data(DATA_KEY, data) + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error(`No method named "${config}"`) + } + data[config]() + } + }) + } + + } + + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Tooltip._jQueryInterface + $.fn[NAME].Constructor = Tooltip + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Tooltip._jQueryInterface + } + + return Tooltip + +})(jQuery) + +export default Tooltip diff --git a/templates/assets/bootstrap/js/src/util.js b/templates/assets/bootstrap/js/src/util.js new file mode 100644 index 0000000..3c0d022 --- /dev/null +++ b/templates/assets/bootstrap/js/src/util.js @@ -0,0 +1,164 @@ +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.6): util.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const Util = (($) => { + + + /** + * ------------------------------------------------------------------------ + * Private TransitionEnd Helpers + * ------------------------------------------------------------------------ + */ + + let transition = false + + const MAX_UID = 1000000 + + const TransitionEndEvent = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + // shoutout AngusCroll (https://goo.gl/pxwQGp) + function toType(obj) { + return {}.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase() + } + + function isElement(obj) { + return (obj[0] || obj).nodeType + } + + function getSpecialTransitionEndEvent() { + return { + bindType: transition.end, + delegateType: transition.end, + handle(event) { + if ($(event.target).is(this)) { + return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params + } + return undefined + } + } + } + + function transitionEndTest() { + if (window.QUnit) { + return false + } + + const el = document.createElement('bootstrap') + + for (const name in TransitionEndEvent) { + if (el.style[name] !== undefined) { + return { + end: TransitionEndEvent[name] + } + } + } + + return false + } + + function transitionEndEmulator(duration) { + let called = false + + $(this).one(Util.TRANSITION_END, () => { + called = true + }) + + setTimeout(() => { + if (!called) { + Util.triggerTransitionEnd(this) + } + }, duration) + + return this + } + + function setTransitionEndSupport() { + transition = transitionEndTest() + + $.fn.emulateTransitionEnd = transitionEndEmulator + + if (Util.supportsTransitionEnd()) { + $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent() + } + } + + + /** + * -------------------------------------------------------------------------- + * Public Util Api + * -------------------------------------------------------------------------- + */ + + const Util = { + + TRANSITION_END: 'bsTransitionEnd', + + getUID(prefix) { + do { + // eslint-disable-next-line no-bitwise + prefix += ~~(Math.random() * MAX_UID) // "~~" acts like a faster Math.floor() here + } while (document.getElementById(prefix)) + return prefix + }, + + getSelectorFromElement(element) { + let selector = element.getAttribute('data-target') + if (!selector || selector === '#') { + selector = element.getAttribute('href') || '' + } + + try { + const $selector = $(selector) + return $selector.length > 0 ? selector : null + } catch (error) { + return null + } + }, + + reflow(element) { + return element.offsetHeight + }, + + triggerTransitionEnd(element) { + $(element).trigger(transition.end) + }, + + supportsTransitionEnd() { + return Boolean(transition) + }, + + typeCheckConfig(componentName, config, configTypes) { + for (const property in configTypes) { + if (configTypes.hasOwnProperty(property)) { + const expectedTypes = configTypes[property] + const value = config[property] + const valueType = value && isElement(value) ? + 'element' : toType(value) + + if (!new RegExp(expectedTypes).test(valueType)) { + throw new Error( + `${componentName.toUpperCase()}: ` + + `Option "${property}" provided type "${valueType}" ` + + `but expected type "${expectedTypes}".`) + } + } + } + } + } + + setTransitionEndSupport() + + return Util + +})(jQuery) + +export default Util diff --git a/templates/assets/bootstrap/nuget/MyGet.ps1 b/templates/assets/bootstrap/nuget/MyGet.ps1 new file mode 100644 index 0000000..71110b5 --- /dev/null +++ b/templates/assets/bootstrap/nuget/MyGet.ps1 @@ -0,0 +1,18 @@ +# set env vars usually set by MyGet (enable for local testing) +#$env:SourcesPath = '..' +#$env:NuGet = "./nuget.exe" #https://dist.nuget.org/win-x86-commandline/latest/nuget.exe + +$nuget = $env:NuGet + +# parse the version number out of package.json +$bsversionParts = ((Get-Content $env:SourcesPath\package.json) -join "`n" | ConvertFrom-Json).version.split('-', 2) # split the version on the '-' +$bsversion = $bsversionParts[0] + +if ($bsversionParts.Length -gt 1) +{ + $bsversion += '-' + $bsversionParts[1].replace('.', '').replace('-', '_') # strip out invalid chars from the PreRelease part +} + +# create packages +& $nuget pack "$env:SourcesPath\nuget\bootstrap.nuspec" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion +& $nuget pack "$env:SourcesPath\nuget\bootstrap.sass.nuspec" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion diff --git a/templates/assets/bootstrap/nuget/bootstrap.nuspec b/templates/assets/bootstrap/nuget/bootstrap.nuspec new file mode 100644 index 0000000..bbb4582 --- /dev/null +++ b/templates/assets/bootstrap/nuget/bootstrap.nuspec @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> + <metadata> + <id>bootstrap</id> + <version>4.0.0</version> + <title>Bootstrap CSS</title> + <authors>The Bootstrap Authors, Twitter Inc.</authors> + <owners>bootstrap</owners> + <description>The most popular front-end framework for developing responsive, mobile first projects on the web.</description> + <releaseNotes>https://blog.getbootstrap.com</releaseNotes> + <summary>Bootstrap framework in CSS. Includes fonts and JavaScript</summary> + <language>en-us</language> + <projectUrl>https://getbootstrap.com</projectUrl> + <iconUrl>https://getbootstrap.com/apple-touch-icon.png</iconUrl> + <licenseUrl>https://github.com/twbs/bootstrap/blob/master/LICENSE</licenseUrl> + <copyright>Copyright 2017</copyright> + <requireLicenseAcceptance>false</requireLicenseAcceptance> + <dependencies> + <dependency id="jQuery" version="[1.9.1,4)" /> + </dependencies> + <tags>css mobile-first responsive front-end framework web</tags> + </metadata> + <files> + <file src="dist\css\*.*" target="content\Content" /> + <file src="dist\js\bootstrap*.js" target="content\Scripts" /> + </files> +</package> diff --git a/templates/assets/bootstrap/nuget/bootstrap.sass.nuspec b/templates/assets/bootstrap/nuget/bootstrap.sass.nuspec new file mode 100644 index 0000000..aba443c --- /dev/null +++ b/templates/assets/bootstrap/nuget/bootstrap.sass.nuspec @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> + <metadata> + <id>bootstrap.sass</id> + <version>4.0.0</version> + <title>Bootstrap Sass</title> + <authors>The Bootstrap Authors, Twitter Inc.</authors> + <owners>bootstrap</owners> + <description>The most popular front-end framework for developing responsive, mobile first projects on the web.</description> + <releaseNotes>https://blog.getbootstrap.com</releaseNotes> + <summary>Bootstrap framework in Sass. Includes fonts and JavaScript</summary> + <language>en-us</language> + <projectUrl>https://getbootstrap.com</projectUrl> + <iconUrl>https://getbootstrap.com/apple-touch-icon.png</iconUrl> + <licenseUrl>https://github.com/twbs/bootstrap/blob/master/LICENSE</licenseUrl> + <copyright>Copyright 2017</copyright> + <requireLicenseAcceptance>false</requireLicenseAcceptance> + <dependencies> + <dependency id="jQuery" version="[1.9.1,4)" /> + </dependencies> + <tags>css sass mobile-first responsive front-end framework web</tags> + </metadata> + <files> + <file src="scss\**\*.scss" target="content\Content\bootstrap" /> + <file src="dist\js\bootstrap*.js" target="content\Scripts" /> + </files> +</package> diff --git a/templates/assets/bootstrap/package.js b/templates/assets/bootstrap/package.js new file mode 100644 index 0000000..ce21bad --- /dev/null +++ b/templates/assets/bootstrap/package.js @@ -0,0 +1,19 @@ +// package metadata file for Meteor.js + +/* global Package:true */ + +Package.describe({ + name: 'twbs:bootstrap', // https://atmospherejs.com/twbs/bootstrap + summary: 'The most popular front-end framework for developing responsive, mobile first projects on the web.', + version: '4.0.0-alpha.6', + git: 'https://github.com/twbs/bootstrap.git' +}); + +Package.onUse(function (api) { + api.versionsFrom('METEOR@1.0'); + api.use('jquery', 'client'); + api.addFiles([ + 'dist/css/bootstrap.css', + 'dist/js/bootstrap.js' + ], 'client'); +}); diff --git a/templates/assets/bootstrap/package.json b/templates/assets/bootstrap/package.json new file mode 100644 index 0000000..d11ffbf --- /dev/null +++ b/templates/assets/bootstrap/package.json @@ -0,0 +1,114 @@ +{ + "name": "bootstrap", + "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", + "version": "4.0.0-alpha.6", + "keywords": [ + "css", + "sass", + "mobile-first", + "responsive", + "front-end", + "framework", + "web" + ], + "homepage": "https://getbootstrap.com", + "author": "The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)", + "contributors": [ + "Twitter, Inc." + ], + "scripts": { + "change-version": "node grunt/change-version.js", + "clean-css": "cleancss --level 1 --source-map --output dist/css/bootstrap.min.css dist/css/bootstrap.css && cleancss --level 1 --source-map --output dist/css/bootstrap-grid.min.css dist/css/bootstrap-grid.css && cleancss --level 1 --source-map --output dist/css/bootstrap-reboot.min.css dist/css/bootstrap-reboot.css", + "clean-css-docs": "cleancss --level 1 --source-map --output docs/assets/css/docs.min.css docs/assets/css/docs.min.css", + "eslint": "eslint --ignore-path .eslintignore js && eslint --config js/tests/.eslintrc.json --env node grunt Gruntfile.js && eslint --config js/tests/.eslintrc.json docs/assets/js/src docs/assets/js/ie-emulation-modes-warning.js docs/assets/js/ie10-viewport-bug-workaround.js", + "htmlhint": "htmlhint --config docs/.htmlhintrc _gh_pages/", + "htmllint": "htmllint --rc docs/.htmllintrc _gh_pages/**/*.html js/tests/visual/*.html", + "jekyll": "bundle exec jekyll build", + "jekyll-github": "shx echo 'github: true' > $npm_config_tmp/twbsjekyll.yml && npm run jekyll -- --config _config.yml,$npm_config_tmp/twbsjekyll.yml && shx rm $npm_config_tmp/twbsjekyll.yml", + "postcss": "postcss --config grunt/ --replace dist/css/*.css", + "postcss-docs": "postcss --config grunt/ --replace docs/assets/css/docs.min.css && postcss --config grunt/ --replace docs/examples/**/*.css", + "sass": "node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap.scss dist/css/bootstrap.css && node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap-grid.scss dist/css/bootstrap-grid.css && node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap-reboot.scss dist/css/bootstrap-reboot.css", + "sass-docs": "node-sass --output-style expanded --source-map true --precision 6 docs/assets/scss/docs.scss docs/assets/css/docs.min.css", + "scss-lint": "bundle exec scss-lint --config scss/.scss-lint.yml scss/*.scss", + "scss-lint-docs": "bundle exec scss-lint --config scss/.scss-lint.yml --exclude docs/assets/scss/docs.scss docs/assets/scss/*.scss", + "uglify": "uglifyjs --compress warnings=false --mangle --comments '/^!/' --output dist/js/bootstrap.min.js dist/js/bootstrap.js", + "uglify-docs": "uglifyjs --compress warnings=false --mangle --comments '/^!/' --output docs/assets/js/docs.min.js docs/assets/js/vendor/anchor.min.js docs/assets/js/vendor/clipboard.min.js docs/assets/js/vendor/holder.min.js docs/assets/js/src/application.js", + "update-shrinkwrap": "npm shrinkwrap --dev && shx mv ./npm-shrinkwrap.json ./grunt/npm-shrinkwrap.json", + "test": "npm run eslint && grunt test" + }, + "style": "dist/css/bootstrap.css", + "sass": "scss/bootstrap.scss", + "main": "dist/js/bootstrap", + "repository": { + "type": "git", + "url": "https://github.com/twbs/bootstrap.git" + }, + "bugs": { + "url": "https://github.com/twbs/bootstrap/issues" + }, + "license": "MIT", + "dependencies": { + "jquery": ">=1.9.1", + "tether": "^1.4.0" + }, + "devDependencies": { + "autoprefixer": "^6.7.7", + "babel-eslint": "^7.1.1", + "babel-plugin-transform-es2015-modules-strip": "^0.1.0", + "babel-preset-es2015": "^6.24.0", + "clean-css-cli": "^4.0.9", + "eslint": "^3.18.0", + "grunt": "^1.0.1", + "grunt-babel": "^6.0.0", + "grunt-build-control": "^0.7.1", + "grunt-contrib-clean": "^1.0.0", + "grunt-contrib-compress": "^1.4.1", + "grunt-contrib-concat": "^1.0.1", + "grunt-contrib-connect": "^1.0.2", + "grunt-contrib-copy": "^1.0.0", + "grunt-contrib-qunit": "^1.3.0", + "grunt-contrib-watch": "^1.0.0", + "grunt-exec": "^2.0.0", + "grunt-saucelabs": "^9.0.0", + "grunt-stamp": "^0.3.0", + "htmlhint": "^0.9.13", + "htmllint-cli": "^0.0.6", + "is-travis": "^1.0.0", + "load-grunt-tasks": "^3.5.2", + "node-sass": "^4.5.0", + "postcss-cli": "^3.0.0", + "postcss-flexbugs-fixes": "^2.1.0", + "shelljs": "^0.7.7", + "shx": "^0.2.2", + "time-grunt": "^1.4.0", + "uglify-js": "^2.8.14" + }, + "engines": { + "node": ">=4" + }, + "files": [ + "dist", + "grunt", + "js/**/*.js", + "scss/**/*.scss", + "Gruntfile.js", + "LICENSE" + ], + "jspm": { + "main": "js/bootstrap", + "directories": { + "lib": "dist" + }, + "shim": { + "js/bootstrap": { + "deps": [ + "jquery" + ], + "exports": "$" + } + }, + "dependencies": { + "jquery": "3" + } + } +} diff --git a/templates/assets/bootstrap/sache.json b/templates/assets/bootstrap/sache.json new file mode 100644 index 0000000..cd1a8c4 --- /dev/null +++ b/templates/assets/bootstrap/sache.json @@ -0,0 +1,5 @@ +{ + "name": "bootstrap", + "description": "The most popular HTML, CSS, and JavaScript framework for developing responsive, mobile first projects on the web.", + "tags": ["bootstrap", "grid", "typography", "buttons", "ui", "responsive-web-design"] +} diff --git a/templates/assets/bootstrap/scss/.scss-lint.yml b/templates/assets/bootstrap/scss/.scss-lint.yml new file mode 100644 index 0000000..845001e --- /dev/null +++ b/templates/assets/bootstrap/scss/.scss-lint.yml @@ -0,0 +1,536 @@ +# Default application configuration that all configurations inherit from. +scss_files: + - "**/*.scss" + - "docs/assets/scss/**/*.scss" + +plugin_directories: ['.scss-linters'] + +# List of gem names to load custom linters from (make sure they are already +# installed) +plugin_gems: [] + +# Default severity of all linters. +severity: warning + +linters: + BangFormat: + enabled: true + space_before_bang: true + space_after_bang: false + + BemDepth: + enabled: false + max_elements: 1 + + BorderZero: + enabled: true + convention: zero # or `none` + + ChainedClasses: + enabled: false + + ColorKeyword: + enabled: true + + ColorVariable: + enabled: false + + Comment: + enabled: true + exclude: + - bootstrap.scss + style: silent + + DebugStatement: + enabled: true + + DeclarationOrder: + enabled: false + + DisableLinterReason: + enabled: false + + DuplicateProperty: + enabled: true + + ElsePlacement: + enabled: true + style: same_line # or 'new_line' + + EmptyLineBetweenBlocks: + enabled: false + ignore_single_line_blocks: true + + EmptyRule: + enabled: true + + ExtendDirective: + enabled: false + + FinalNewline: + enabled: true + present: true + + HexLength: + enabled: true + style: short # or 'long' + + HexNotation: + enabled: true + style: lowercase # or 'uppercase' + + HexValidation: + enabled: true + + IdSelector: + enabled: true + + ImportantRule: + enabled: false + + ImportPath: + enabled: true + leading_underscore: false + filename_extension: false + + Indentation: + enabled: true + allow_non_nested_indentation: false + character: space # or 'tab' + width: 2 + + LeadingZero: + enabled: true + style: exclude_zero # or 'include_zero' + + MergeableSelector: + enabled: false + force_nesting: true + + NameFormat: + enabled: true + allow_leading_underscore: true + convention: hyphenated_lowercase # or 'camel_case', or 'snake_case', or a regex pattern + + NestingDepth: + enabled: true + max_depth: 4 + ignore_parent_selectors: false + + PlaceholderInExtend: + enabled: false + + PropertyCount: + enabled: false + include_nested: false + max_properties: 10 + + PropertySortOrder: + enabled: true + ignore_unspecified: false + min_properties: 2 + separate_groups: false + order: + - position + - top + - right + - bottom + - left + - z-index + - -webkit-box-sizing + - -moz-box-sizing + - box-sizing + - display + - flex + - flex-align + - flex-basis + - flex-direction + - flex-wrap + - flex-flow + - flex-grow + - flex-order + - flex-pack + - align-items + - align-self + - justify-content + - float + - width + - min-width + - max-width + - height + - min-height + - max-height + - padding + - padding-top + - padding-right + - padding-bottom + - padding-left + - margin + - margin-top + - margin-right + - margin-bottom + - margin-left + - overflow + - overflow-x + - overflow-y + - -webkit-overflow-scrolling + - -ms-overflow-x + - -ms-overflow-y + - -ms-overflow-style + - clip + - clear + - font + - font-family + - font-size + - font-style + - font-weight + - font-variant + - font-size-adjust + - font-stretch + - font-effect + - font-emphasize + - font-emphasize-position + - font-emphasize-style + - font-smooth + - -webkit-hyphens + - -moz-hyphens + - hyphens + - line-height + - color + - text-align + - -webkit-text-align-last + - -moz-text-align-last + - -ms-text-align-last + - text-align-last + - text-emphasis + - text-emphasis-color + - text-emphasis-style + - text-emphasis-position + - text-decoration + - text-indent + - text-justify + - text-outline + - -ms-text-overflow + - text-overflow + - text-overflow-ellipsis + - text-overflow-mode + - text-shadow + - text-transform + - text-wrap + - -webkit-text-size-adjust + - -ms-text-size-adjust + - letter-spacing + - -ms-word-break + - word-break + - word-spacing + - -ms-word-wrap + - word-wrap + - overflow-wrap + - -moz-tab-size + - -o-tab-size + - tab-size + - white-space + - vertical-align + - list-style + - list-style-position + - list-style-type + - list-style-image + - pointer-events + - -ms-touch-action + - touch-action + - cursor + - visibility + - zoom + - table-layout + - empty-cells + - caption-side + - border-spacing + - border-collapse + - content + - quotes + - counter-reset + - counter-increment + - resize + - -webkit-user-select + - -moz-user-select + - -ms-user-select + - -o-user-select + - user-select + - nav-index + - nav-up + - nav-right + - nav-down + - nav-left + - background + - background-color + - background-image + - -ms-filter:\\'progid:DXImageTransform.Microsoft.gradient + - filter:progid:DXImageTransform.Microsoft.gradient + - filter:progid:DXImageTransform.Microsoft.AlphaImageLoader + - filter + - background-repeat + - background-attachment + - background-position + - background-position-x + - background-position-y + - -webkit-background-clip + - -moz-background-clip + - background-clip + - background-origin + - -webkit-background-size + - -moz-background-size + - -o-background-size + - background-size + - border + - border-color + - border-style + - border-width + - border-top + - border-top-color + - border-top-style + - border-top-width + - border-right + - border-right-color + - border-right-style + - border-right-width + - border-bottom + - border-bottom-color + - border-bottom-style + - border-bottom-width + - border-left + - border-left-color + - border-left-style + - border-left-width + - border-radius + - border-top-left-radius + - border-top-right-radius + - border-bottom-right-radius + - border-bottom-left-radius + - -webkit-border-image + - -moz-border-image + - -o-border-image + - border-image + - -webkit-border-image-source + - -moz-border-image-source + - -o-border-image-source + - border-image-source + - -webkit-border-image-slice + - -moz-border-image-slice + - -o-border-image-slice + - border-image-slice + - -webkit-border-image-width + - -moz-border-image-width + - -o-border-image-width + - border-image-width + - -webkit-border-image-outset + - -moz-border-image-outset + - -o-border-image-outset + - border-image-outset + - -webkit-border-image-repeat + - -moz-border-image-repeat + - -o-border-image-repeat + - border-image-repeat + - outline + - outline-width + - outline-style + - outline-color + - outline-offset + - -webkit-box-shadow + - -moz-box-shadow + - box-shadow + - filter:progid:DXImageTransform.Microsoft.Alpha(Opacity + - -ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha + - opacity + - -ms-interpolation-mode + - -webkit-transition + - -moz-transition + - -ms-transition + - -o-transition + - transition + - -webkit-transition-delay + - -moz-transition-delay + - -ms-transition-delay + - -o-transition-delay + - transition-delay + - -webkit-transition-timing-function + - -moz-transition-timing-function + - -ms-transition-timing-function + - -o-transition-timing-function + - transition-timing-function + - -webkit-transition-duration + - -moz-transition-duration + - -ms-transition-duration + - -o-transition-duration + - transition-duration + - -webkit-transition-property + - -moz-transition-property + - -ms-transition-property + - -o-transition-property + - transition-property + - -webkit-transform + - -moz-transform + - -ms-transform + - -o-transform + - transform + - -webkit-transform-origin + - -moz-transform-origin + - -ms-transform-origin + - -o-transform-origin + - transform-origin + - -webkit-animation + - -moz-animation + - -ms-animation + - -o-animation + - animation + - -webkit-animation-name + - -moz-animation-name + - -ms-animation-name + - -o-animation-name + - animation-name + - -webkit-animation-duration + - -moz-animation-duration + - -ms-animation-duration + - -o-animation-duration + - animation-duration + - -webkit-animation-play-state + - -moz-animation-play-state + - -ms-animation-play-state + - -o-animation-play-state + - animation-play-state + - -webkit-animation-timing-function + - -moz-animation-timing-function + - -ms-animation-timing-function + - -o-animation-timing-function + - animation-timing-function + - -webkit-animation-delay + - -moz-animation-delay + - -ms-animation-delay + - -o-animation-delay + - animation-delay + - -webkit-animation-iteration-count + - -moz-animation-iteration-count + - -ms-animation-iteration-count + - -o-animation-iteration-count + - animation-iteration-count + - -webkit-animation-direction + - -moz-animation-direction + - -ms-animation-direction + - -o-animation-direction + + + PropertySpelling: + enabled: true + extra_properties: [] + disabled_properties: [] + + PropertyUnits: + enabled: true + global: [ + 'ch', 'em', 'ex', 'rem', # Font-relative lengths + 'cm', 'in', 'mm', 'pc', 'pt', 'px', 'q', # Absolute lengths + 'vh', 'vw', 'vmin', 'vmax', # Viewport-percentage lengths + 'deg', 'grad', 'rad', 'turn', # Angle + 'ms', 's', # Duration + 'Hz', 'kHz', # Frequency + 'dpi', 'dpcm', 'dppx', # Resolution + '%'] # Other + properties: {} + + PseudoElement: + enabled: true + + QualifyingElement: + enabled: true + allow_element_with_attribute: false + allow_element_with_class: false + allow_element_with_id: false + + SelectorDepth: + enabled: true + max_depth: 4 + + SelectorFormat: + enabled: false + convention: hyphenated_lowercase # or 'strict_BEM', or 'hyphenated_BEM', or 'snake_case', or 'camel_case', or a regex pattern + + Shorthand: + enabled: true + allowed_shorthands: [1, 2, 3, 4] + + SingleLinePerProperty: + enabled: false + allow_single_line_rule_sets: true + + SingleLinePerSelector: + enabled: false + + SpaceAfterComma: + enabled: false + style: one_space # or 'no_space', or 'at_least_one_space' + + SpaceAfterPropertyColon: + enabled: true + style: at_least_one_space # or 'no_space', or 'at_least_one_space', or 'aligned' + + SpaceAfterPropertyName: + enabled: true + + SpaceAfterVariableName: + enabled: true + + SpaceAroundOperator: + enabled: true + style: one_space # or 'at_least_one_space', or 'no_space' + + SpaceBeforeBrace: + enabled: true + style: space # or 'new_line' + allow_single_line_padding: true + + SpaceBetweenParens: + enabled: true + spaces: 0 + + StringQuotes: + enabled: true + style: double_quotes # or double_quotes + + TrailingSemicolon: + enabled: true + + TrailingWhitespace: + enabled: true + + TrailingZero: + enabled: false + + TransitionAll: + enabled: false + + UnnecessaryMantissa: + enabled: true + + UnnecessaryParentReference: + enabled: true + + UrlFormat: + enabled: true + + UrlQuotes: + enabled: true + + VariableForProperty: + enabled: false + properties: [] + + VendorPrefix: + enabled: true + identifier_list: base + additional_identifiers: [] + excluded_identifiers: [] + + ZeroUnit: + enabled: true + + Compass::*: + enabled: false diff --git a/templates/assets/bootstrap/scss/_alert.scss b/templates/assets/bootstrap/scss/_alert.scss new file mode 100644 index 0000000..d9b4e9b --- /dev/null +++ b/templates/assets/bootstrap/scss/_alert.scss @@ -0,0 +1,55 @@ +// +// Base styles +// + +.alert { + padding: $alert-padding-y $alert-padding-x; + margin-bottom: $alert-margin-bottom; + border: $alert-border-width solid transparent; + @include border-radius($alert-border-radius); +} + +// Headings for larger alerts +.alert-heading { + // Specified to prevent conflicts of changing $headings-color + color: inherit; +} + +// Provide class for links that match alerts +.alert-link { + font-weight: $alert-link-font-weight; +} + + +// Dismissible alerts +// +// Expand the right padding and account for the close button's positioning. + +.alert-dismissible { + // Adjust close link position + .close { + position: relative; + top: -$alert-padding-y; + right: -$alert-padding-x; + padding: $alert-padding-y $alert-padding-x; + color: inherit; + } +} + + +// Alternate styles +// +// Generate contextual modifier classes for colorizing the alert. + +.alert-success { + @include alert-variant($alert-success-bg, $alert-success-border, $alert-success-text); +} +.alert-info { + @include alert-variant($alert-info-bg, $alert-info-border, $alert-info-text); +} +.alert-warning { + @include alert-variant($alert-warning-bg, $alert-warning-border, $alert-warning-text); +} +.alert-danger { + @include alert-variant($alert-danger-bg, $alert-danger-border, $alert-danger-text); +} diff --git a/templates/assets/bootstrap/scss/_badge.scss b/templates/assets/bootstrap/scss/_badge.scss new file mode 100644 index 0000000..175b19d --- /dev/null +++ b/templates/assets/bootstrap/scss/_badge.scss @@ -0,0 +1,76 @@ +// Base class +// +// Requires one of the contextual, color modifier classes for `color` and +// `background-color`. + +.badge { + display: inline-block; + padding: $badge-padding-y $badge-padding-x; + font-size: $badge-font-size; + font-weight: $badge-font-weight; + line-height: 1; + color: $badge-color; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + @include border-radius(); + + // Empty badges collapse automatically + &:empty { + display: none; + } +} + +// Quick fix for badges in buttons +.btn .badge { + position: relative; + top: -1px; +} + +// scss-lint:disable QualifyingElement +// Add hover effects, but only for links +a.badge { + @include hover-focus { + color: $badge-link-hover-color; + text-decoration: none; + } +} +// scss-lint:enable QualifyingElement + +// Pill badges +// +// Make them extra rounded with a modifier to replace v3's badges. + +.badge-pill { + padding-right: $badge-pill-padding-x; + padding-left: $badge-pill-padding-x; + @include border-radius($badge-pill-border-radius); +} + +// Colors +// +// Contextual variations (linked badges get darker on :hover). + +.badge-default { + @include badge-variant($badge-default-bg); +} + +.badge-primary { + @include badge-variant($badge-primary-bg); +} + +.badge-success { + @include badge-variant($badge-success-bg); +} + +.badge-info { + @include badge-variant($badge-info-bg); +} + +.badge-warning { + @include badge-variant($badge-warning-bg); +} + +.badge-danger { + @include badge-variant($badge-danger-bg); +} diff --git a/templates/assets/bootstrap/scss/_breadcrumb.scss b/templates/assets/bootstrap/scss/_breadcrumb.scss new file mode 100644 index 0000000..2bc0e20 --- /dev/null +++ b/templates/assets/bootstrap/scss/_breadcrumb.scss @@ -0,0 +1,38 @@ +.breadcrumb { + padding: $breadcrumb-padding-y $breadcrumb-padding-x; + margin-bottom: 1rem; + list-style: none; + background-color: $breadcrumb-bg; + @include border-radius($border-radius); + @include clearfix; +} + +.breadcrumb-item { + float: left; + + // The separator between breadcrumbs (by default, a forward-slash: "/") + + .breadcrumb-item::before { + display: inline-block; // Suppress underlining of the separator in modern browsers + padding-right: $breadcrumb-item-padding; + padding-left: $breadcrumb-item-padding; + color: $breadcrumb-divider-color; + content: "#{$breadcrumb-divider}"; + } + + // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built + // without `<ul>`s. The `::before` pseudo-element generates an element + // *within* the .breadcrumb-item and thereby inherits the `text-decoration`. + // + // To trick IE into suppressing the underline, we give the pseudo-element an + // underline and then immediately remove it. + + .breadcrumb-item:hover::before { + text-decoration: underline; + } + + .breadcrumb-item:hover::before { + text-decoration: none; + } + + &.active { + color: $breadcrumb-active-color; + } +} diff --git a/templates/assets/bootstrap/scss/_button-group.scss b/templates/assets/bootstrap/scss/_button-group.scss new file mode 100644 index 0000000..facecd3 --- /dev/null +++ b/templates/assets/bootstrap/scss/_button-group.scss @@ -0,0 +1,204 @@ +// scss-lint:disable QualifyingElement + +// Make the div behave like a button +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-flex; + vertical-align: middle; // match .btn alignment given font-size hack above + + > .btn { + position: relative; + flex: 0 1 auto; + margin-bottom: 0; + + // Bring the hover, focused, and "active" buttons to the fron to overlay + // the borders properly + @include hover { + z-index: 2; + } + &:focus, + &:active, + &.active { + z-index: 2; + } + } + + // Prevent double borders when buttons are next to each other + .btn + .btn, + .btn + .btn-group, + .btn-group + .btn, + .btn-group + .btn-group { + margin-left: -$input-btn-border-width; + } +} + +// Optional: Group multiple button groups together for a toolbar +.btn-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; + + .input-group { + width: auto; + } +} + +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} + +// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match +.btn-group > .btn:first-child { + margin-left: 0; + + &:not(:last-child):not(.dropdown-toggle) { + @include border-right-radius(0); + } +} +// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + @include border-left-radius(0); +} + +// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group) +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) { + > .btn:last-child, + > .dropdown-toggle { + @include border-right-radius(0); + } +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + @include border-left-radius(0); +} + +// On active and open, don't show outline +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + + +// Sizing +// +// Remix the default button sizing classes into new ones for easier manipulation. + +.btn-group-sm > .btn { @extend .btn-sm; } +.btn-group-lg > .btn { @extend .btn-lg; } + + +// +// Split button dropdowns +// + +.btn + .dropdown-toggle-split { + padding-right: $btn-padding-x * .75; + padding-left: $btn-padding-x * .75; + + &::after { + margin-left: 0; + } +} + +.btn-sm + .dropdown-toggle-split { + padding-right: $btn-padding-x-sm * .75; + padding-left: $btn-padding-x-sm * .75; +} + +.btn-lg + .dropdown-toggle-split { + padding-right: $btn-padding-x-lg * .75; + padding-left: $btn-padding-x-lg * .75; +} + + +// The clickable button for toggling the menu +// Remove the gradient and set the same inset shadow as the :active state +.btn-group.open .dropdown-toggle { + @include box-shadow($btn-active-box-shadow); + + // Show no shadow for `.btn-link` since it has no other button styles. + &.btn-link { + @include box-shadow(none); + } +} + + +// +// Vertical button groups +// + +.btn-group-vertical { + display: inline-flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + + .btn, + .btn-group { + width: 100%; + } + + > .btn + .btn, + > .btn + .btn-group, + > .btn-group + .btn, + > .btn-group + .btn-group { + margin-top: -$input-btn-border-width; + margin-left: 0; + } +} + +.btn-group-vertical > .btn { + &:not(:first-child):not(:last-child) { + border-radius: 0; + } + &:first-child:not(:last-child) { + @include border-bottom-radius(0); + } + &:last-child:not(:first-child) { + @include border-top-radius(0); + } +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) { + > .btn:last-child, + > .dropdown-toggle { + @include border-bottom-radius(0); + } +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + @include border-top-radius(0); +} + + +// Checkbox and radio options +// +// In order to support the browser's form validation feedback, powered by the +// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use +// `display: none;` or `visibility: hidden;` as that also hides the popover. +// Simply visually hiding the inputs via `opacity` would leave them clickable in +// certain cases which is prevented by using `clip` and `pointer-events`. +// This way, we ensure a DOM element is visible to position the popover from. +// +// See https://github.com/twbs/bootstrap/pull/12794 and +// https://github.com/twbs/bootstrap/pull/14559 for more information. + +[data-toggle="buttons"] { + > .btn, + > .btn-group > .btn { + input[type="radio"], + input[type="checkbox"] { + position: absolute; + clip: rect(0,0,0,0); + pointer-events: none; + } + } +} diff --git a/templates/assets/bootstrap/scss/_buttons.scss b/templates/assets/bootstrap/scss/_buttons.scss new file mode 100644 index 0000000..2964a52 --- /dev/null +++ b/templates/assets/bootstrap/scss/_buttons.scss @@ -0,0 +1,170 @@ +// scss-lint:disable QualifyingElement + +// +// Base styles +// + +.btn { + display: inline-block; + font-weight: $btn-font-weight; + line-height: $btn-line-height; + text-align: center; + white-space: nowrap; + vertical-align: middle; + user-select: none; + border: $input-btn-border-width solid transparent; + @include button-size($btn-padding-y, $btn-padding-x, $font-size-base, $btn-border-radius); + @include transition($btn-transition); + + // Share hover and focus styles + @include hover-focus { + text-decoration: none; + } + &:focus, + &.focus { + outline: 0; + box-shadow: $btn-focus-box-shadow; + } + + // Disabled comes first so active can properly restyle + &.disabled, + &:disabled { + cursor: $cursor-disabled; + opacity: .65; + @include box-shadow(none); + } + + &:active, + &.active { + background-image: none; + @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow); + } +} + +// Future-proof disabling of clicks on `<a>` elements +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} + + +// +// Alternate buttons +// + +.btn-primary { + @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border); +} +.btn-secondary { + @include button-variant($btn-secondary-color, $btn-secondary-bg, $btn-secondary-border); +} +.btn-info { + @include button-variant($btn-info-color, $btn-info-bg, $btn-info-border); +} +.btn-success { + @include button-variant($btn-success-color, $btn-success-bg, $btn-success-border); +} +.btn-warning { + @include button-variant($btn-warning-color, $btn-warning-bg, $btn-warning-border); +} +.btn-danger { + @include button-variant($btn-danger-color, $btn-danger-bg, $btn-danger-border); +} + +// Remove all backgrounds +.btn-outline-primary { + @include button-outline-variant($btn-primary-bg, $btn-primary-color); +} +.btn-outline-secondary { + @include button-outline-variant($btn-secondary-border, $btn-secondary-color); +} +.btn-outline-info { + @include button-outline-variant($btn-info-bg, $btn-info-color); +} +.btn-outline-success { + @include button-outline-variant($btn-success-bg, $btn-success-color); +} +.btn-outline-warning { + @include button-outline-variant($btn-warning-bg, $btn-warning-color); +} +.btn-outline-danger { + @include button-outline-variant($btn-danger-bg, $btn-danger-color); +} + + +// +// Link buttons +// + +// Make a button look and behave like a link +.btn-link { + font-weight: $font-weight-normal; + color: $link-color; + border-radius: 0; + + &, + &:active, + &.active, + &:disabled { + background-color: transparent; + @include box-shadow(none); + } + &, + &:focus, + &:active { + border-color: transparent; + } + @include hover { + border-color: transparent; + } + @include hover-focus { + color: $link-hover-color; + text-decoration: $link-hover-decoration; + background-color: transparent; + } + &:disabled { + color: $btn-link-disabled-color; + + @include hover-focus { + text-decoration: none; + } + } +} + + +// +// Button Sizes +// + +.btn-lg { + // line-height: ensure even-numbered height of button next to large input + @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $font-size-lg, $btn-border-radius-lg); +} +.btn-sm { + // line-height: ensure proper height of button next to small input + @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $font-size-sm, $btn-border-radius-sm); +} + + +// +// Block button +// + +.btn-block { + display: block; + width: 100%; +} + +// Vertically space out multiple block buttons +.btn-block + .btn-block { + margin-top: $btn-block-spacing-y; +} + +// Specificity overrides +input[type="submit"], +input[type="reset"], +input[type="button"] { + &.btn-block { + width: 100%; + } +} diff --git a/templates/assets/bootstrap/scss/_card.scss b/templates/assets/bootstrap/scss/_card.scss new file mode 100644 index 0000000..9fe70e8 --- /dev/null +++ b/templates/assets/bootstrap/scss/_card.scss @@ -0,0 +1,276 @@ +// +// Base styles +// + +.card { + position: relative; + display: flex; + flex-direction: column; + background-color: $card-bg; + border: $card-border-width solid $card-border-color; + @include border-radius($card-border-radius); +} + +.card-block { + // Enable `flex-grow: 1` for decks and groups so that card blocks take up + // as much space as possible, ensuring footers are aligned to the bottom. + flex: 1 1 auto; + padding: $card-spacer-x; +} + +.card-title { + margin-bottom: $card-spacer-y; +} + +.card-subtitle { + margin-top: -($card-spacer-y / 2); + margin-bottom: 0; +} + +.card-text:last-child { + margin-bottom: 0; +} + +.card-link { + @include hover { + text-decoration: none; + } + + + .card-link { + margin-left: $card-spacer-x; + } +} + +.card { + > .list-group:first-child { + .list-group-item:first-child { + @include border-top-radius($card-border-radius); + } + } + + > .list-group:last-child { + .list-group-item:last-child { + @include border-bottom-radius($card-border-radius); + } + } +} + + +// +// Optional textual caps +// + +.card-header { + padding: $card-spacer-y $card-spacer-x; + margin-bottom: 0; // Removes the default margin-bottom of <hN> + background-color: $card-cap-bg; + border-bottom: $card-border-width solid $card-border-color; + + &:first-child { + @include border-radius($card-border-radius-inner $card-border-radius-inner 0 0); + } +} + +.card-footer { + padding: $card-spacer-y $card-spacer-x; + background-color: $card-cap-bg; + border-top: $card-border-width solid $card-border-color; + + &:last-child { + @include border-radius(0 0 $card-border-radius-inner $card-border-radius-inner); + } +} + + +// +// Header navs +// + +.card-header-tabs { + margin-right: -($card-spacer-x / 2); + margin-bottom: -$card-spacer-y; + margin-left: -($card-spacer-x / 2); + border-bottom: 0; +} + +.card-header-pills { + margin-right: -($card-spacer-x / 2); + margin-left: -($card-spacer-x / 2); +} + + +// +// Background variations +// + +.card-primary { + @include card-variant($brand-primary, $brand-primary); +} +.card-success { + @include card-variant($brand-success, $brand-success); +} +.card-info { + @include card-variant($brand-info, $brand-info); +} +.card-warning { + @include card-variant($brand-warning, $brand-warning); +} +.card-danger { + @include card-variant($brand-danger, $brand-danger); +} + +// Remove all backgrounds +.card-outline-primary { + @include card-outline-variant($btn-primary-bg); +} +.card-outline-secondary { + @include card-outline-variant($btn-secondary-border); +} +.card-outline-info { + @include card-outline-variant($btn-info-bg); +} +.card-outline-success { + @include card-outline-variant($btn-success-bg); +} +.card-outline-warning { + @include card-outline-variant($btn-warning-bg); +} +.card-outline-danger { + @include card-outline-variant($btn-danger-bg); +} + +// +// Inverse text within a card for use with dark backgrounds +// + +.card-inverse { + @include card-inverse; +} + +// +// Blockquote +// + +.card-blockquote { + padding: 0; + margin-bottom: 0; + border-left: 0; +} + +// Card image +.card-img { + // margin: -1.325rem; + @include border-radius($card-border-radius-inner); +} +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: $card-img-overlay-padding; +} + + + +// Card image caps +.card-img-top { + @include border-top-radius($card-border-radius-inner); +} +.card-img-bottom { + @include border-bottom-radius($card-border-radius-inner); +} + + +// Card deck + +@include media-breakpoint-up(sm) { + .card-deck { + display: flex; + flex-flow: row wrap; + + .card { + display: flex; + flex: 1 0 0; + flex-direction: column; + + // Selectively apply horizontal margins to cards to avoid doing the + // negative margin dance like our grid. This differs from the grid + // due to the use of margins as gutters instead of padding. + &:not(:first-child) { margin-left: $card-deck-margin; } + &:not(:last-child) { margin-right: $card-deck-margin; } + } + } +} + + +// +// Card groups +// + +@include media-breakpoint-up(sm) { + .card-group { + display: flex; + flex-flow: row wrap; + + .card { + flex: 1 0 0; + + + .card { + margin-left: 0; + border-left: 0; + } + + // Handle rounded corners + @if $enable-rounded { + &:first-child { + @include border-right-radius(0); + + .card-img-top { + border-top-right-radius: 0; + } + .card-img-bottom { + border-bottom-right-radius: 0; + } + } + &:last-child { + @include border-left-radius(0); + + .card-img-top { + border-top-left-radius: 0; + } + .card-img-bottom { + border-bottom-left-radius: 0; + } + } + + &:not(:first-child):not(:last-child) { + border-radius: 0; + + .card-img-top, + .card-img-bottom { + border-radius: 0; + } + } + } + } + } +} + + +// +// Columns +// + +@include media-breakpoint-up(sm) { + .card-columns { + column-count: $card-columns-count; + column-gap: $card-columns-gap; + + .card { + display: inline-block; // Don't let them vertically span multiple columns + width: 100%; // Don't let their width change + margin-bottom: $card-columns-margin; + } + } +} diff --git a/templates/assets/bootstrap/scss/_carousel.scss b/templates/assets/bootstrap/scss/_carousel.scss new file mode 100644 index 0000000..1b6e450 --- /dev/null +++ b/templates/assets/bootstrap/scss/_carousel.scss @@ -0,0 +1,177 @@ +// Wrapper for the slide container and indicators +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-item { + position: relative; + display: none; + width: 100%; + + @include if-supports-3d-transforms() { + @include transition($carousel-transition); + backface-visibility: hidden; + perspective: 1000px; + } +} + +.carousel-item.active, +.carousel-item-next, +.carousel-item-prev { + display: flex; +} + +.carousel-item-next, +.carousel-item-prev { + position: absolute; + top: 0; +} + +// CSS3 transforms when supported by the browser +@include if-supports-3d-transforms() { + .carousel-item-next.carousel-item-left, + .carousel-item-prev.carousel-item-right { + transform: translate3d(0, 0, 0); + } + + .carousel-item-next, + .active.carousel-item-right { + transform: translate3d(100%, 0, 0); + } + + .carousel-item-prev, + .active.carousel-item-left { + transform: translate3d(-100%, 0, 0); + } +} + + +// +// Left/right controls for nav +// + +.carousel-control-prev, +.carousel-control-next { + position: absolute; + top: 0; + bottom: 0; + // Use flex for alignment (1-3) + display: flex; // 1. allow flex styles + align-items: center; // 2. vertically center contents + justify-content: center; // 3. horizontally center contents + width: $carousel-control-width; + color: $carousel-control-color; + text-align: center; + opacity: $carousel-control-opacity; + // We can't have a transition here because WebKit cancels the carousel + // animation if you trip this while in the middle of another animation. + + // Hover/focus state + @include hover-focus { + color: $carousel-control-color; + text-decoration: none; + outline: 0; + opacity: .9; + } +} +.carousel-control-prev { + left: 0; +} +.carousel-control-next { + right: 0; +} + +// Icons for within +.carousel-control-prev-icon, +.carousel-control-next-icon { + display: inline-block; + width: $carousel-control-icon-width; + height: $carousel-control-icon-width; + background: transparent no-repeat center center; + background-size: 100% 100%; +} +.carousel-control-prev-icon { + background-image: $carousel-control-prev-icon-bg; +} +.carousel-control-next-icon { + background-image: $carousel-control-next-icon-bg; +} + + +// Optional indicator pips +// +// Add an ordered list with the following class and add a list item for each +// slide your carousel holds. + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 10px; + left: 0; + z-index: 15; + display: flex; + justify-content: center; + padding-left: 0; // override <ol> default + // Use the .carousel-control's width as margin so we don't overlay those + margin-right: $carousel-control-width; + margin-left: $carousel-control-width; + list-style: none; + + li { + position: relative; + flex: 1 0 auto; + max-width: $carousel-indicator-width; + height: $carousel-indicator-height; + margin-right: $carousel-indicator-spacer; + margin-left: $carousel-indicator-spacer; + text-indent: -999px; + background-color: rgba($carousel-indicator-active-bg, .5); + + // Use pseudo classes to increase the hit area by 10px on top and bottom. + &::before { + position: absolute; + top: -10px; + left: 0; + display: inline-block; + width: 100%; + height: 10px; + content: ""; + } + &::after { + position: absolute; + bottom: -10px; + left: 0; + display: inline-block; + width: 100%; + height: 10px; + content: ""; + } + } + + .active { + background-color: $carousel-indicator-active-bg; + } +} + + +// Optional captions +// +// + +.carousel-caption { + position: absolute; + right: ((100% - $carousel-caption-width) / 2); + bottom: 20px; + left: ((100% - $carousel-caption-width) / 2); + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: $carousel-caption-color; + text-align: center; +} diff --git a/templates/assets/bootstrap/scss/_close.scss b/templates/assets/bootstrap/scss/_close.scss new file mode 100644 index 0000000..f181490 --- /dev/null +++ b/templates/assets/bootstrap/scss/_close.scss @@ -0,0 +1,29 @@ +.close { + float: right; + font-size: $close-font-size; + font-weight: $close-font-weight; + line-height: 1; + color: $close-color; + text-shadow: $close-text-shadow; + opacity: .5; + + @include hover-focus { + color: $close-color; + text-decoration: none; + opacity: .75; + } +} + +// Additional properties for button version +// iOS requires the button element instead of an anchor tag. +// If you want the anchor version, it requires `href="#"`. +// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile + +// scss-lint:disable QualifyingElement +button.close { + padding: 0; + background: transparent; + border: 0; + -webkit-appearance: none; +} +// scss-lint:enable QualifyingElement diff --git a/templates/assets/bootstrap/scss/_code.scss b/templates/assets/bootstrap/scss/_code.scss new file mode 100644 index 0000000..759da15 --- /dev/null +++ b/templates/assets/bootstrap/scss/_code.scss @@ -0,0 +1,64 @@ +// Inline and block code styles +code, +kbd, +pre, +samp { + font-family: $font-family-monospace; +} + +// Inline code +code { + padding: $code-padding-y $code-padding-x; + font-size: $code-font-size; + color: $code-color; + background-color: $code-bg; + @include border-radius($border-radius); + + // Streamline the style when inside anchors to avoid broken underline and more + a > & { + padding: 0; + color: inherit; + background-color: inherit; + } +} + +// User input typically entered via keyboard +kbd { + padding: $code-padding-y $code-padding-x; + font-size: $code-font-size; + color: $kbd-color; + background-color: $kbd-bg; + @include border-radius($border-radius-sm); + @include box-shadow($kbd-box-shadow); + + kbd { + padding: 0; + font-size: 100%; + font-weight: $nested-kbd-font-weight; + @include box-shadow(none); + } +} + +// Blocks of code +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + font-size: $code-font-size; + color: $pre-color; + + // Account for some code outputs that place code tags in pre tags + code { + padding: 0; + font-size: inherit; + color: inherit; + background-color: transparent; + border-radius: 0; + } +} + +// Enable scrollable blocks of code +.pre-scrollable { + max-height: $pre-scrollable-max-height; + overflow-y: scroll; +} diff --git a/templates/assets/bootstrap/scss/_custom-forms.scss b/templates/assets/bootstrap/scss/_custom-forms.scss new file mode 100644 index 0000000..d303c48 --- /dev/null +++ b/templates/assets/bootstrap/scss/_custom-forms.scss @@ -0,0 +1,258 @@ +// scss-lint:disable PropertyCount, VendorPrefix + +// Embedded icons from Open Iconic. +// Released under MIT and copyright 2014 Waybury. +// https://useiconic.com/open + + +// Checkboxes and radios +// +// Base class takes care of all the key behavioral aspects. + +.custom-control { + position: relative; + display: inline-flex; + min-height: (1rem * $line-height-base); + padding-left: $custom-control-gutter; + margin-right: $custom-control-spacer-x; +} + +.custom-control-input { + position: absolute; + z-index: -1; // Put the input behind the label so it doesn't overlay text + opacity: 0; + + &:checked ~ .custom-control-indicator { + color: $custom-control-checked-indicator-color; + background-color: $custom-control-checked-indicator-bg; + @include box-shadow($custom-control-checked-indicator-box-shadow); + } + + &:focus ~ .custom-control-indicator { + // the mixin is not used here to make sure there is feedback + box-shadow: $custom-control-focus-indicator-box-shadow; + } + + &:active ~ .custom-control-indicator { + color: $custom-control-active-indicator-color; + background-color: $custom-control-active-indicator-bg; + @include box-shadow($custom-control-active-indicator-box-shadow); + } + + &:disabled { + ~ .custom-control-indicator { + cursor: $custom-control-disabled-cursor; + background-color: $custom-control-disabled-indicator-bg; + } + + ~ .custom-control-description { + color: $custom-control-disabled-description-color; + cursor: $custom-control-disabled-cursor; + } + } +} + +// Custom indicator +// +// Generates a shadow element to create our makeshift checkbox/radio background. + +.custom-control-indicator { + position: absolute; + top: (($line-height-base - $custom-control-indicator-size) / 2); + left: 0; + display: block; + width: $custom-control-indicator-size; + height: $custom-control-indicator-size; + pointer-events: none; + user-select: none; + background-color: $custom-control-indicator-bg; + background-repeat: no-repeat; + background-position: center center; + background-size: $custom-control-indicator-bg-size; + @include box-shadow($custom-control-indicator-box-shadow); +} + +// Checkboxes +// +// Tweak just a few things for checkboxes. + +.custom-checkbox { + .custom-control-indicator { + @include border-radius($custom-checkbox-radius); + } + + .custom-control-input:checked ~ .custom-control-indicator { + background-image: $custom-checkbox-checked-icon; + } + + .custom-control-input:indeterminate ~ .custom-control-indicator { + background-color: $custom-checkbox-indeterminate-bg; + background-image: $custom-checkbox-indeterminate-icon; + @include box-shadow($custom-checkbox-indeterminate-box-shadow); + } +} + +// Radios +// +// Tweak just a few things for radios. + +.custom-radio { + .custom-control-indicator { + border-radius: $custom-radio-radius; + } + + .custom-control-input:checked ~ .custom-control-indicator { + background-image: $custom-radio-checked-icon; + } +} + + +// Layout options +// +// By default radios and checkboxes are `inline-block` with no additional spacing +// set. Use these optional classes to tweak the layout. + +.custom-controls-stacked { + display: flex; + flex-direction: column; + + .custom-control { + margin-bottom: $custom-control-spacer-y; + + + .custom-control { + margin-left: 0; + } + } +} + + +// Select +// +// Replaces the browser default select with a custom one, mostly pulled from +// http://primercss.io. +// + +.custom-select { + display: inline-block; + max-width: 100%; + $select-border-width: ($custom-select-border-width * 2); + height: calc(#{$input-height} + #{$select-border-width}); + padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x; + line-height: $custom-select-line-height; + color: $custom-select-color; + vertical-align: middle; + background: $custom-select-bg $custom-select-indicator no-repeat right $custom-select-padding-x center; + background-size: $custom-select-bg-size; + border: $custom-select-border-width solid $custom-select-border-color; + @include border-radius($custom-select-border-radius); + appearance: none; + + &:focus { + border-color: $custom-select-focus-border-color; + outline: none; + @include box-shadow($custom-select-focus-box-shadow); + + &::-ms-value { + // For visual consistency with other platforms/browsers, + // supress the default white text on blue background highlight given to + // the selected option text when the (still closed) <select> receives focus + // in IE and (under certain conditions) Edge. + // See https://github.com/twbs/bootstrap/issues/19398. + color: $input-color; + background-color: $input-bg; + } + } + + &:disabled { + color: $custom-select-disabled-color; + cursor: $cursor-disabled; + background-color: $custom-select-disabled-bg; + } + + // Hides the default caret in IE11 + &::-ms-expand { + opacity: 0; + } +} + +.custom-select-sm { + padding-top: $custom-select-padding-y; + padding-bottom: $custom-select-padding-y; + font-size: $custom-select-sm-font-size; + + // &:not([multiple]) { + // height: 26px; + // min-height: 26px; + // } +} + + +// File +// +// Custom file input. + +.custom-file { + position: relative; + display: inline-block; + max-width: 100%; + height: $custom-file-height; + margin-bottom: 0; +} + +.custom-file-input { + min-width: $custom-file-width; + max-width: 100%; + height: $custom-file-height; + margin: 0; + opacity: 0; + + &:focus ~ .custom-file-control { + @include box-shadow($custom-file-focus-box-shadow); + } +} + +.custom-file-control { + position: absolute; + top: 0; + right: 0; + left: 0; + z-index: 5; + height: $custom-file-height; + padding: $custom-file-padding-x $custom-file-padding-y; + line-height: $custom-file-line-height; + color: $custom-file-color; + pointer-events: none; + user-select: none; + background-color: $custom-file-bg; + border: $custom-file-border-width solid $custom-file-border-color; + @include border-radius($custom-file-border-radius); + @include box-shadow($custom-file-box-shadow); + + @each $lang, $text in map-get($custom-file-text, placeholder) { + &:lang(#{$lang}):empty::after { + content: $text; + } + } + + &::before { + position: absolute; + top: -$custom-file-border-width; + right: -$custom-file-border-width; + bottom: -$custom-file-border-width; + z-index: 6; + display: block; + height: $custom-file-height; + padding: $custom-file-padding-x $custom-file-padding-y; + line-height: $custom-file-line-height; + color: $custom-file-button-color; + background-color: $custom-file-button-bg; + border: $custom-file-border-width solid $custom-file-border-color; + @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0); + } + + @each $lang, $text in map-get($custom-file-text, button-label) { + &:lang(#{$lang})::before { + content: $text; + } + } +} diff --git a/templates/assets/bootstrap/scss/_custom.scss b/templates/assets/bootstrap/scss/_custom.scss new file mode 100644 index 0000000..88ccf20 --- /dev/null +++ b/templates/assets/bootstrap/scss/_custom.scss @@ -0,0 +1,4 @@ +// Bootstrap overrides +// +// Copy variables from `_variables.scss` to this file to override default values +// without modifying source files. diff --git a/templates/assets/bootstrap/scss/_dropdown.scss b/templates/assets/bootstrap/scss/_dropdown.scss new file mode 100644 index 0000000..404483e --- /dev/null +++ b/templates/assets/bootstrap/scss/_dropdown.scss @@ -0,0 +1,156 @@ +// The dropdown wrapper (`<div>`) +.dropup, +.dropdown { + position: relative; +} + +.dropdown-toggle { + // Generate the caret automatically + &::after { + display: inline-block; + width: 0; + height: 0; + margin-left: $caret-width; + vertical-align: middle; + content: ""; + border-top: $caret-width solid; + border-right: $caret-width solid transparent; + border-left: $caret-width solid transparent; + } +} + +.dropup { + .dropdown-toggle { + &::after { + border-top: 0; + border-bottom: $caret-width solid; + } + } +} + +// The dropdown menu +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: $zindex-dropdown; + display: none; // none by default, but block on "open" of the menu + float: left; + min-width: $dropdown-min-width; + padding: $dropdown-padding-y 0; + margin: $dropdown-margin-top 0 0; // override default ul + font-size: $font-size-base; // Redeclare because nesting can cause inheritance issues + color: $body-color; + text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) + list-style: none; + background-color: $dropdown-bg; + background-clip: padding-box; + border: $dropdown-border-width solid $dropdown-border-color; + @include border-radius($border-radius); + @include box-shadow($dropdown-box-shadow); +} + +// Dividers (basically an `<hr>`) within the dropdown +.dropdown-divider { + @include nav-divider($dropdown-divider-bg); +} + +// Links, buttons, and more within the dropdown menu +// +// `<button>`-specific styles are denoted with `// For <button>s` +.dropdown-item { + display: block; + width: 100%; // For `<button>`s + padding: 3px $dropdown-item-padding-x; + clear: both; + font-weight: $font-weight-normal; + color: $dropdown-link-color; + text-align: inherit; // For `<button>`s + white-space: nowrap; // prevent links from randomly breaking onto new lines + background: none; // For `<button>`s + border: 0; // For `<button>`s + + @include hover-focus { + color: $dropdown-link-hover-color; + text-decoration: none; + background-color: $dropdown-link-hover-bg; + } + + &.active, + &:active { + color: $dropdown-link-active-color; + text-decoration: none; + background-color: $dropdown-link-active-bg; + } + + &.disabled, + &:disabled { + color: $dropdown-link-disabled-color; + cursor: $cursor-disabled; + background-color: transparent; + // Remove CSS gradients if they're enabled + @if $enable-gradients { + background-image: none; + } + } +} + +// Open state for the dropdown +.show { + // Show the menu + > .dropdown-menu { + display: block; + } + + // Remove the outline when :focus is triggered + > a { + outline: 0; + } +} + +// Menu positioning +// +// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown +// menu with the parent. +.dropdown-menu-right { + right: 0; + left: auto; // Reset the default from `.dropdown-menu` +} + +.dropdown-menu-left { + right: auto; + left: 0; +} + +// Dropdown section headers +.dropdown-header { + display: block; + padding: $dropdown-padding-y $dropdown-item-padding-x; + margin-bottom: 0; // for use with heading elements + font-size: $font-size-sm; + color: $dropdown-header-color; + white-space: nowrap; // as with > li > a +} + +// Backdrop to catch body clicks on mobile, etc. +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: $zindex-dropdown-backdrop; +} + +// Allow for dropdowns to go bottom up (aka, dropup-menu) +// +// Just add .dropup after the standard .dropdown class and you're set. + +.dropup { + // Different positioning for bottom up menu + .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: $dropdown-margin-top; + } +} diff --git a/templates/assets/bootstrap/scss/_forms.scss b/templates/assets/bootstrap/scss/_forms.scss new file mode 100644 index 0000000..4ec9f6e --- /dev/null +++ b/templates/assets/bootstrap/scss/_forms.scss @@ -0,0 +1,387 @@ +// scss-lint:disable QualifyingElement, VendorPrefix + +// +// Textual form controls +// + +.form-control { + display: block; + width: 100%; + // // Make inputs at least the height of their button counterpart (base line-height + padding + border) + // height: $input-height; + padding: $input-padding-y $input-padding-x; + font-size: $font-size-base; + line-height: $input-line-height; + color: $input-color; + background-color: $input-bg; + // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214. + background-image: none; + background-clip: padding-box; + border: $input-btn-border-width solid $input-border-color; + + // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS. + @if $enable-rounded { + // Manually use the if/else instead of the mixin to account for iOS override + border-radius: $input-border-radius; + } @else { + // Otherwise undo the iOS default + border-radius: 0; + } + + @include box-shadow($input-box-shadow); + @include transition($input-transition); + + // Unstyle the caret on `<select>`s in IE10+. + &::-ms-expand { + background-color: transparent; + border: 0; + } + + // Customize the `:focus` state to imitate native WebKit styles. + @include form-control-focus(); + + // Placeholder + &::placeholder { + color: $input-color-placeholder; + // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526. + opacity: 1; + } + + // Disabled and read-only inputs + // + // HTML5 says that controls under a fieldset > legend:first-child won't be + // disabled if the fieldset is disabled. Due to implementation difficulty, we + // don't honor that edge case; we style them as disabled anyway. + &:disabled, + &[readonly] { + background-color: $input-bg-disabled; + // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655. + opacity: 1; + } + + &:disabled { + cursor: $cursor-disabled; + } +} + +select.form-control { + &:not([size]):not([multiple]) { + $select-border-width: ($border-width * 2); + height: calc(#{$input-height} + #{$select-border-width}); + } + + &:focus::-ms-value { + // Suppress the nested default white text on blue background highlight given to + // the selected option text when the (still closed) <select> receives focus + // in IE and (under certain conditions) Edge, as it looks bad and cannot be made to + // match the appearance of the native widget. + // See https://github.com/twbs/bootstrap/issues/19398. + color: $input-color; + background-color: $input-bg; + } +} + +// Make file inputs better match text inputs by forcing them to new lines. +.form-control-file, +.form-control-range { + display: block; +} + + +// +// Labels +// + +// For use with horizontal and inline forms, when you need the label text to +// align with the form controls. +.col-form-label { + padding-top: calc(#{$input-padding-y} - #{$input-btn-border-width} * 2); + padding-bottom: calc(#{$input-padding-y} - #{$input-btn-border-width} * 2); + margin-bottom: 0; // Override the `<label>` default +} + +.col-form-label-lg { + padding-top: calc(#{$input-padding-y-lg} - #{$input-btn-border-width} * 2); + padding-bottom: calc(#{$input-padding-y-lg} - #{$input-btn-border-width} * 2); + font-size: $font-size-lg; +} + +.col-form-label-sm { + padding-top: calc(#{$input-padding-y-sm} - #{$input-btn-border-width} * 2); + padding-bottom: calc(#{$input-padding-y-sm} - #{$input-btn-border-width} * 2); + font-size: $font-size-sm; +} + + +// +// Legends +// + +// For use with horizontal and inline forms, when you need the legend text to +// be the same size as regular labels, and to align with the form controls. +.col-form-legend { + padding-top: $input-padding-y; + padding-bottom: $input-padding-y; + margin-bottom: 0; + font-size: $font-size-base; +} + + +// Static form control text +// +// Apply class to an element to make any string of text align with labels in a +// horizontal form layout. + +.form-control-static { + padding-top: $input-padding-y; + padding-bottom: $input-padding-y; + margin-bottom: 0; // match inputs if this class comes on inputs with default margins + line-height: $input-line-height; + border: solid transparent; + border-width: $input-btn-border-width 0; + + &.form-control-sm, + &.form-control-lg { + padding-right: 0; + padding-left: 0; + } +} + + +// Form control sizing +// +// Build on `.form-control` with modifier classes to decrease or increase the +// height and font-size of form controls. +// +// The `.form-group-* form-control` variations are sadly duplicated to avoid the +// issue documented in https://github.com/twbs/bootstrap/issues/15074. + +.form-control-sm { + padding: $input-padding-y-sm $input-padding-x-sm; + font-size: $font-size-sm; + @include border-radius($input-border-radius-sm); +} + +select.form-control-sm { + &:not([size]):not([multiple]) { + height: $input-height-sm; + } +} + +.form-control-lg { + padding: $input-padding-y-lg $input-padding-x-lg; + font-size: $font-size-lg; + @include border-radius($input-border-radius-lg); +} + +select.form-control-lg { + &:not([size]):not([multiple]) { + height: $input-height-lg; + } +} + + +// Form groups +// +// Designed to help with the organization and spacing of vertical forms. For +// horizontal forms, use the predefined grid classes. + +.form-group { + margin-bottom: $form-group-margin-bottom; +} + +.form-text { + display: block; + margin-top: $form-text-margin-top; +} + + +// Checkboxes and radios +// +// Indent the labels to position radios/checkboxes as hanging controls. + +.form-check { + position: relative; + display: block; + margin-bottom: $form-check-margin-bottom; + + &.disabled { + .form-check-label { + color: $text-muted; + cursor: $cursor-disabled; + } + } +} + +.form-check-label { + padding-left: $form-check-input-gutter; + margin-bottom: 0; // Override default `<label>` bottom margin +} + +.form-check-input { + position: absolute; + margin-top: $form-check-input-margin-y; + margin-left: -$form-check-input-gutter; + + &:only-child { + position: static; + } +} + +// Radios and checkboxes on same line +.form-check-inline { + display: inline-block; + + .form-check-label { + vertical-align: middle; + } + + + .form-check-inline { + margin-left: $form-check-inline-margin-x; + } +} + + +// Form control feedback states +// +// Apply contextual and semantic states to individual form controls. + +.form-control-feedback { + margin-top: $form-feedback-margin-top; +} + +.form-control-success, +.form-control-warning, +.form-control-danger { + padding-right: ($input-padding-x * 3); + background-repeat: no-repeat; + background-position: center right ($input-height / 4); + background-size: ($input-height / 2) ($input-height / 2); +} + +// Form validation states +.has-success { + @include form-control-validation($brand-success); + + .form-control-success { + background-image: $form-icon-success; + } +} + +.has-warning { + @include form-control-validation($brand-warning); + + .form-control-warning { + background-image: $form-icon-warning; + } +} + +.has-danger { + @include form-control-validation($brand-danger); + + .form-control-danger { + background-image: $form-icon-danger; + } +} + + +// Inline forms +// +// Make forms appear inline(-block) by adding the `.form-inline` class. Inline +// forms begin stacked on extra small (mobile) devices and then go inline when +// viewports reach <768px. +// +// Requires wrapping inputs and labels with `.form-group` for proper display of +// default HTML form controls and our custom form controls (e.g., input groups). + +.form-inline { + display: flex; + flex-flow: row wrap; + align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height) + + // Because we use flex, the initial sizing of checkboxes is collapsed and + // doesn't occupy the full-width (which is what we want for xs grid tier), + // so we force that here. + .form-check { + width: 100%; + } + + // Kick in the inline + @include media-breakpoint-up(sm) { + label { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 0; + } + + // Inline-block all the things for "inline" + .form-group { + display: flex; + flex: 0 0 auto; + flex-flow: row wrap; + align-items: center; + margin-bottom: 0; + } + + // Allow folks to *not* use `.form-group` + .form-control { + display: inline-block; + width: auto; // Prevent labels from stacking above inputs in `.form-group` + vertical-align: middle; + } + + // Make static controls behave like regular ones + .form-control-static { + display: inline-block; + } + + .input-group { + width: auto; + } + + .form-control-label { + margin-bottom: 0; + vertical-align: middle; + } + + // Remove default margin on radios/checkboxes that were used for stacking, and + // then undo the floating of radios and checkboxes to match. + .form-check { + display: flex; + align-items: center; + justify-content: center; + width: auto; + margin-top: 0; + margin-bottom: 0; + } + .form-check-label { + padding-left: 0; + } + .form-check-input { + position: relative; + margin-top: 0; + margin-right: $form-check-input-margin-x; + margin-left: 0; + } + + // Custom form controls + .custom-control { + display: flex; + align-items: center; + justify-content: center; + padding-left: 0; + } + .custom-control-indicator { + position: static; + display: inline-block; + margin-right: $form-check-input-margin-x; // Flexbox alignment means we lose our HTML space here, so we compensate. + vertical-align: text-bottom; + } + + // Re-override the feedback icon. + .has-feedback .form-control-feedback { + top: 0; + } + } +} diff --git a/templates/assets/bootstrap/scss/_grid.scss b/templates/assets/bootstrap/scss/_grid.scss new file mode 100644 index 0000000..8c7a9ee --- /dev/null +++ b/templates/assets/bootstrap/scss/_grid.scss @@ -0,0 +1,52 @@ +// Container widths +// +// Set the container width, and override it for fixed navbars in media queries. + +@if $enable-grid-classes { + .container { + @include make-container(); + @include make-container-max-widths(); + } +} + +// Fluid container +// +// Utilizes the mixin meant for fixed width containers, but without any defined +// width for fluid, full width layouts. + +@if $enable-grid-classes { + .container-fluid { + @include make-container(); + } +} + +// Row +// +// Rows contain and clear the floats of your columns. + +@if $enable-grid-classes { + .row { + @include make-row(); + } + + // Remove the negative margin from default .row, then the horizontal padding + // from all immediate children columns (to prevent runaway style inheritance). + .no-gutters { + margin-right: 0; + margin-left: 0; + + > .col, + > [class*="col-"] { + padding-right: 0; + padding-left: 0; + } + } +} + +// Columns +// +// Common styles for small and large grid columns + +@if $enable-grid-classes { + @include make-grid-columns(); +} diff --git a/templates/assets/bootstrap/scss/_images.scss b/templates/assets/bootstrap/scss/_images.scss new file mode 100644 index 0000000..50c5610 --- /dev/null +++ b/templates/assets/bootstrap/scss/_images.scss @@ -0,0 +1,43 @@ +// Responsive images (ensure images don't scale beyond their parents) +// +// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s. +// We previously tried the "images are responsive by default" approach in Bootstrap v2, +// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps) +// which weren't expecting the images within themselves to be involuntarily resized. +// See also https://github.com/twbs/bootstrap/issues/18178 +.img-fluid { + @include img-fluid; +} + + +// Image thumbnails +.img-thumbnail { + padding: $thumbnail-padding; + background-color: $thumbnail-bg; + border: $thumbnail-border-width solid $thumbnail-border-color; + @include border-radius($thumbnail-border-radius); + @include transition($thumbnail-transition); + @include box-shadow($thumbnail-box-shadow); + + // Keep them at most 100% wide + @include img-fluid; +} + +// +// Figures +// + +.figure { + // Ensures the caption's text aligns with the image. + display: inline-block; +} + +.figure-img { + margin-bottom: ($spacer / 2); + line-height: 1; +} + +.figure-caption { + font-size: $figure-caption-font-size; + color: $figure-caption-color; +} diff --git a/templates/assets/bootstrap/scss/_input-group.scss b/templates/assets/bootstrap/scss/_input-group.scss new file mode 100644 index 0000000..49cdf28 --- /dev/null +++ b/templates/assets/bootstrap/scss/_input-group.scss @@ -0,0 +1,175 @@ +// +// Base styles +// + +.input-group { + position: relative; + display: flex; + width: 100%; + + .form-control { + // Ensure that the input is always above the *appended* addon button for + // proper border colors. + position: relative; + z-index: 2; + flex: 1 1 auto; + // Add width 1% and flex-basis auto to ensure that button will not wrap out + // the column. Applies to IE Edge+ and Firefox. Chrome does not require this. + width: 1%; + margin-bottom: 0; + + // Bring the "active" form control to the front + @include hover-focus-active { + z-index: 3; + } + } +} + +.input-group-addon, +.input-group-btn, +.input-group .form-control { + // Vertically centers the content of the addons within the input group + display: flex; + align-items: center; + + &:not(:first-child):not(:last-child) { + @include border-radius(0); + } +} + +.input-group-addon, +.input-group-btn { + white-space: nowrap; + vertical-align: middle; // Match the inputs +} + + +// Sizing options +// +// Remix the default form control sizing classes into new ones for easier +// manipulation. + +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + @extend .form-control-lg; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + @extend .form-control-sm; +} + + +// +// Text input groups +// + +.input-group-addon { + padding: $input-padding-y $input-padding-x; + margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom + font-size: $font-size-base; // Match inputs + font-weight: $font-weight-normal; + line-height: $input-line-height; + color: $input-color; + text-align: center; + background-color: $input-group-addon-bg; + border: $input-btn-border-width solid $input-group-addon-border-color; + @include border-radius($input-border-radius); + + // Sizing + &.form-control-sm { + padding: $input-padding-y-sm $input-padding-x-sm; + font-size: $font-size-sm; + @include border-radius($input-border-radius-sm); + } + &.form-control-lg { + padding: $input-padding-y-lg $input-padding-x-lg; + font-size: $font-size-lg; + @include border-radius($input-border-radius-lg); + } + + // scss-lint:disable QualifyingElement + // Nuke default margins from checkboxes and radios to vertically center within. + input[type="radio"], + input[type="checkbox"] { + margin-top: 0; + } + // scss-lint:enable QualifyingElement +} + + +// +// Reset rounded corners +// + +.input-group .form-control:not(:last-child), +.input-group-addon:not(:last-child), +.input-group-btn:not(:last-child) > .btn, +.input-group-btn:not(:last-child) > .btn-group > .btn, +.input-group-btn:not(:last-child) > .dropdown-toggle, +.input-group-btn:not(:first-child) > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:not(:first-child) > .btn-group:not(:last-child) > .btn { + @include border-right-radius(0); +} +.input-group-addon:not(:last-child) { + border-right: 0; +} +.input-group .form-control:not(:first-child), +.input-group-addon:not(:first-child), +.input-group-btn:not(:first-child) > .btn, +.input-group-btn:not(:first-child) > .btn-group > .btn, +.input-group-btn:not(:first-child) > .dropdown-toggle, +.input-group-btn:not(:last-child) > .btn:not(:first-child), +.input-group-btn:not(:last-child) > .btn-group:not(:first-child) > .btn { + @include border-left-radius(0); +} +.form-control + .input-group-addon:not(:first-child) { + border-left: 0; +} + +// +// Button input groups +// + +.input-group-btn { + position: relative; + // Jankily prevent input button groups from wrapping with `white-space` and + // `font-size` in combination with `inline-block` on buttons. + font-size: 0; + white-space: nowrap; + + // Negative margin for spacing, position for bringing hovered/focused/actived + // element above the siblings. + > .btn { + position: relative; + + + .btn { + margin-left: (-$input-btn-border-width); + } + + // Bring the "active" button to the front + @include hover-focus-active { + z-index: 3; + } + } + + // Negative margin to only have a single, shared border between the two + &:not(:last-child) { + > .btn, + > .btn-group { + margin-right: (-$input-btn-border-width); + } + } + &:not(:first-child) { + > .btn, + > .btn-group { + z-index: 2; + margin-left: (-$input-btn-border-width); + // Because specificity + @include hover-focus-active { + z-index: 3; + } + } + } +} diff --git a/templates/assets/bootstrap/scss/_jumbotron.scss b/templates/assets/bootstrap/scss/_jumbotron.scss new file mode 100644 index 0000000..b12d465 --- /dev/null +++ b/templates/assets/bootstrap/scss/_jumbotron.scss @@ -0,0 +1,20 @@ +.jumbotron { + padding: $jumbotron-padding ($jumbotron-padding / 2); + margin-bottom: $jumbotron-padding; + background-color: $jumbotron-bg; + @include border-radius($border-radius-lg); + + @include media-breakpoint-up(sm) { + padding: ($jumbotron-padding * 2) $jumbotron-padding; + } +} + +.jumbotron-hr { + border-top-color: darken($jumbotron-bg, 10%); +} + +.jumbotron-fluid { + padding-right: 0; + padding-left: 0; + @include border-radius(0); +} diff --git a/templates/assets/bootstrap/scss/_list-group.scss b/templates/assets/bootstrap/scss/_list-group.scss new file mode 100644 index 0000000..c4b5e2f --- /dev/null +++ b/templates/assets/bootstrap/scss/_list-group.scss @@ -0,0 +1,116 @@ +// Base class +// +// Easily usable on <ul>, <ol>, or <div>. + +.list-group { + display: flex; + flex-direction: column; + + // No need to set list-style: none; since .list-group-item is block level + padding-left: 0; // reset padding because ul and ol + margin-bottom: 0; +} + + +// Interactive list items +// +// Use anchor or button elements instead of `li`s or `div`s to create interactive +// list items. Includes an extra `.active` modifier class for selected items. + +.list-group-item-action { + width: 100%; // For `<button>`s (anchors become 100% by default though) + color: $list-group-link-color; + text-align: inherit; // For `<button>`s (anchors inherit) + + // Hover state + @include hover-focus { + color: $list-group-link-hover-color; + text-decoration: none; + background-color: $list-group-hover-bg; + } + + &:active { + color: $list-group-link-active-color; + background-color: $list-group-link-active-bg; + } +} + + +// Individual list items +// +// Use on `li`s or `div`s within the `.list-group` parent. + +.list-group-item { + position: relative; + display: block; + padding: $list-group-item-padding-y $list-group-item-padding-x; + // Place the border on the list items and negative margin up for better styling + margin-bottom: -$list-group-border-width; + background-color: $list-group-bg; + border: $list-group-border-width solid $list-group-border-color; + + &:first-child { + @include border-top-radius($list-group-border-radius); + } + + &:last-child { + margin-bottom: 0; + @include border-bottom-radius($list-group-border-radius); + } + + @include hover-focus { + text-decoration: none; + } + + &.disabled, + &:disabled { + color: $list-group-disabled-color; + cursor: $cursor-disabled; + background-color: $list-group-disabled-bg; + } + + // Include both here for `<a>`s and `<button>`s + &.active { + z-index: 2; // Place active items above their siblings for proper border styling + color: $list-group-active-color; + background-color: $list-group-active-bg; + border-color: $list-group-active-border; + } +} + + +// Flush list items +// +// Remove borders and border-radius to keep list group items edge-to-edge. Most +// useful within other components (e.g., cards). + +.list-group-flush { + .list-group-item { + border-right: 0; + border-left: 0; + border-radius: 0; + } + + &:first-child { + .list-group-item:first-child { + border-top: 0; + } + } + + &:last-child { + .list-group-item:last-child { + border-bottom: 0; + } + } +} + + +// Contextual variants +// +// Add modifier classes to change text and background color on individual items. +// Organizationally, this must come after the `:hover` states. + +@include list-group-item-variant(success, $state-success-bg, $state-success-text); +@include list-group-item-variant(info, $state-info-bg, $state-info-text); +@include list-group-item-variant(warning, $state-warning-bg, $state-warning-text); +@include list-group-item-variant(danger, $state-danger-bg, $state-danger-text); diff --git a/templates/assets/bootstrap/scss/_media.scss b/templates/assets/bootstrap/scss/_media.scss new file mode 100644 index 0000000..b573052 --- /dev/null +++ b/templates/assets/bootstrap/scss/_media.scss @@ -0,0 +1,8 @@ +.media { + display: flex; + align-items: flex-start; +} + +.media-body { + flex: 1; +} diff --git a/templates/assets/bootstrap/scss/_mixins.scss b/templates/assets/bootstrap/scss/_mixins.scss new file mode 100644 index 0000000..13aad24 --- /dev/null +++ b/templates/assets/bootstrap/scss/_mixins.scss @@ -0,0 +1,43 @@ +// Toggles +// +// Used in conjunction with global variables to enable certain theme features. + +// Utilities +@import "mixins/breakpoints"; +@import "mixins/hover"; +@import "mixins/image"; +@import "mixins/badge"; +@import "mixins/resize"; +@import "mixins/screen-reader"; +@import "mixins/size"; +@import "mixins/reset-text"; +@import "mixins/text-emphasis"; +@import "mixins/text-hide"; +@import "mixins/text-truncate"; +@import "mixins/transforms"; +@import "mixins/visibility"; + +// // Components +@import "mixins/alert"; +@import "mixins/buttons"; +@import "mixins/cards"; +@import "mixins/pagination"; +@import "mixins/lists"; +@import "mixins/list-group"; +@import "mixins/nav-divider"; +@import "mixins/forms"; +@import "mixins/table-row"; + +// // Skins +@import "mixins/background-variant"; +@import "mixins/border-radius"; +@import "mixins/box-shadow"; +@import "mixins/gradients"; +@import "mixins/transition"; + +// // Layout +@import "mixins/clearfix"; +// @import "mixins/navbar-align"; +@import "mixins/grid-framework"; +@import "mixins/grid"; +@import "mixins/float"; diff --git a/templates/assets/bootstrap/scss/_modal.scss b/templates/assets/bootstrap/scss/_modal.scss new file mode 100644 index 0000000..9d2a867 --- /dev/null +++ b/templates/assets/bootstrap/scss/_modal.scss @@ -0,0 +1,142 @@ +// .modal-open - body class for killing the scroll +// .modal - container to scroll within +// .modal-dialog - positioning shell for the actual modal +// .modal-content - actual modal w/ bg and corners and stuff + + +// Kill the scroll on the body +.modal-open { + overflow: hidden; +} + +// Container that the modal scrolls within +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: $zindex-modal; + display: none; + overflow: hidden; + // Prevent Chrome on Windows from adding a focus outline. For details, see + // https://github.com/twbs/bootstrap/pull/10951. + outline: 0; + // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a + // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342 + // See also https://github.com/twbs/bootstrap/issues/17695 + + // When fading in the modal, animate it to slide down + &.fade .modal-dialog { + @include transition($modal-transition); + transform: translate(0, -25%); + } + &.show .modal-dialog { transform: translate(0, 0); } +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} + +// Shell div to position the modal with bottom padding +.modal-dialog { + position: relative; + width: auto; + margin: $modal-dialog-margin; +} + +// Actual modal +.modal-content { + position: relative; + display: flex; + flex-direction: column; + background-color: $modal-content-bg; + background-clip: padding-box; + border: $modal-content-border-width solid $modal-content-border-color; + @include border-radius($border-radius-lg); + @include box-shadow($modal-content-xs-box-shadow); + // Remove focus outline from opened modal + outline: 0; +} + +// Modal background +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: $zindex-modal-backdrop; + background-color: $modal-backdrop-bg; + + // Fade for backdrop + &.fade { opacity: 0; } + &.show { opacity: $modal-backdrop-opacity; } +} + +// Modal header +// Top section of the modal w/ title and dismiss +.modal-header { + display: flex; + align-items: center; // vertically center it + justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends + padding: $modal-header-padding; + border-bottom: $modal-header-border-width solid $modal-header-border-color; +} + +// Title text within header +.modal-title { + margin-bottom: 0; + line-height: $modal-title-line-height; +} + +// Modal body +// Where all modal content resides (sibling of .modal-header and .modal-footer) +.modal-body { + position: relative; + // Enable `flex-grow: 1` so that the body take up as much space as possible + // when should there be a fixed height on `.modal-dialog`. + flex: 1 1 auto; + padding: $modal-inner-padding; +} + +// Footer (for actions) +.modal-footer { + display: flex; + align-items: center; // vertically center + justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items + padding: $modal-inner-padding; + border-top: $modal-footer-border-width solid $modal-footer-border-color; + + // Easily place margin between footer elements + > :not(:first-child) { margin-left: .25rem; } + > :not(:last-child) { margin-right: .25rem; } +} + +// Measure scrollbar width for padding body during modal show/hide +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} + +// Scale up the modal +@include media-breakpoint-up(sm) { + // Automatically set modal's width for larger viewports + .modal-dialog { + max-width: $modal-md; + margin: $modal-dialog-sm-up-margin-y auto; + } + + .modal-content { + @include box-shadow($modal-content-sm-up-box-shadow); + } + + .modal-sm { max-width: $modal-sm; } +} + +@include media-breakpoint-up(lg) { + .modal-lg { max-width: $modal-lg; } +} diff --git a/templates/assets/bootstrap/scss/_nav.scss b/templates/assets/bootstrap/scss/_nav.scss new file mode 100644 index 0000000..731f1b7 --- /dev/null +++ b/templates/assets/bootstrap/scss/_nav.scss @@ -0,0 +1,120 @@ +// Base class +// +// Kickstart any navigation component with a set of style resets. Works with +// `<nav>`s or `<ul>`s. + +.nav { + display: flex; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav-link { + display: block; + padding: $nav-link-padding; + + @include hover-focus { + text-decoration: none; + } + + // Disabled state lightens text and removes hover/tab effects + &.disabled { + color: $nav-disabled-link-color; + cursor: $cursor-disabled; + } +} + + +// +// Tabs +// + +.nav-tabs { + border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color; + + .nav-item { + margin-bottom: -$nav-tabs-border-width; + } + + .nav-link { + border: $nav-tabs-border-width solid transparent; + @include border-top-radius($nav-tabs-border-radius); + + @include hover-focus { + border-color: $nav-tabs-link-hover-border-color $nav-tabs-link-hover-border-color $nav-tabs-border-color; + } + + &.disabled { + color: $nav-disabled-link-color; + background-color: transparent; + border-color: transparent; + } + } + + .nav-link.active, + .nav-item.show .nav-link { + color: $nav-tabs-active-link-color; + background-color: $nav-tabs-active-link-bg; + border-color: $nav-tabs-active-link-border-color $nav-tabs-active-link-border-color $nav-tabs-active-link-bg; + } + + .dropdown-menu { + // Make dropdown border overlap tab border + margin-top: -$nav-tabs-border-width; + // Remove the top rounded corners here since there is a hard edge above the menu + @include border-top-radius(0); + } +} + + +// +// Pills +// + +.nav-pills { + .nav-link { + @include border-radius($nav-pills-border-radius); + } + + .nav-link.active, + .nav-item.show .nav-link { + color: $nav-pills-active-link-color; + background-color: $nav-pills-active-link-bg; + } +} + + +// +// Justified variants +// + +.nav-fill { + .nav-item { + flex: 1 1 auto; + text-align: center; + } +} + +.nav-justified { + .nav-item { + flex-basis: 0; + flex-grow: 1; + text-align: center; + } +} + + +// Tabbable tabs +// +// Hide tabbable panes to start, show them when `.active` + +.tab-content { + > .tab-pane { + display: none; + } + > .active { + display: block; + } +} diff --git a/templates/assets/bootstrap/scss/_navbar.scss b/templates/assets/bootstrap/scss/_navbar.scss new file mode 100644 index 0000000..6c31017 --- /dev/null +++ b/templates/assets/bootstrap/scss/_navbar.scss @@ -0,0 +1,276 @@ +// Contents +// +// Navbar +// Navbar brand +// Navbar nav +// Navbar text +// Navbar divider +// Responsive navbar +// Navbar position +// Navbar themes + + +// Navbar +// +// Provide a static navbar from which we expand to create full-width, fixed, and +// other navbar variations. + +.navbar { + position: relative; + display: flex; + flex-direction: column; + padding: $navbar-padding-y $navbar-padding-x; + + @include media-breakpoint-down(nth(map-keys($grid-breakpoints), 1)) { + > .container { + margin-right: 0; + margin-left: 0; + } + } +} + + +// Navbar brand +// +// Used for brand, project, or site names. + +.navbar-brand { + display: inline-block; + align-self: flex-start; + padding-top: .25rem; + padding-bottom: .25rem; + margin-right: $navbar-padding-x; + font-size: $font-size-lg; + line-height: inherit; + white-space: nowrap; + + @include hover-focus { + text-decoration: none; + } +} + + +// Navbar nav +// +// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`). + +.navbar-nav { + display: flex; + flex-direction: column; // cannot use `inherit` to get the `.navbar`s value + padding-left: 0; + margin-bottom: 0; + list-style: none; + + .nav-link { + padding-right: 0; + padding-left: 0; + } +} + + +// Navbar text +// +// + +.navbar-text { + display: inline-block; + padding-top: .425rem; + padding-bottom: .425rem; +} + + +// Responsive navbar +// +// Custom styles for responsive collapsing and toggling of navbar contents. +// Powered by the collapse Bootstrap JavaScript plugin. + +// Button for toggling the navbar when in its collapsed state +.navbar-toggler { + align-self: flex-start; // Prevent toggler from growing to full width when it's the only visible navbar child + padding: $navbar-toggler-padding-y $navbar-toggler-padding-x; + font-size: $navbar-toggler-font-size; + line-height: 1; + background: transparent; // remove default button style + border: $border-width solid transparent; // remove default button style + @include border-radius($navbar-toggler-border-radius); + + @include hover-focus { + text-decoration: none; + } +} + +// Keep as a separate element so folks can easily override it with another icon +// or image file as needed. +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + content: ""; + background: no-repeat center center; + background-size: 100% 100%; +} + +// Use `position` on the toggler to prevent it from being auto placed as a flex +// item and allow easy placement. +.navbar-toggler-left { + position: absolute; + left: $navbar-padding-x; +} +.navbar-toggler-right { + position: absolute; + right: $navbar-padding-x; +} + +// Generate series of `.navbar-toggleable-*` responsive classes for configuring +// where your navbar collapses. +.navbar-toggleable { + @each $breakpoint in map-keys($grid-breakpoints) { + $next: breakpoint-next($breakpoint, $grid-breakpoints); + $infix: breakpoint-infix($breakpoint, $grid-breakpoints); + + &#{$infix} { + @include media-breakpoint-down($breakpoint) { + .navbar-nav { + .dropdown-menu { + position: static; + float: none; + } + } + + > .container { + padding-right: 0; + padding-left: 0; + } + } + + @include media-breakpoint-up($next) { + flex-direction: row; + flex-wrap: nowrap; + align-items: center; + + .navbar-nav { + flex-direction: row; + + .nav-link { + padding-right: .5rem; + padding-left: .5rem; + } + } + + // For nesting containers, have to redeclare for alignment purposes + > .container { + display: flex; + flex-wrap: nowrap; + align-items: center; + } + + // scss-lint:disable ImportantRule + .navbar-collapse { + display: flex !important; + width: 100%; + } + // scss-lint:enable ImportantRule + + .navbar-toggler { + display: none; + } + } + } + } +} + + +// Navbar themes +// +// Styles for switching between navbars with light or dark background. + +// Dark links against a light background +.navbar-light { + .navbar-brand, + .navbar-toggler { + color: $navbar-light-active-color; + + @include hover-focus { + color: $navbar-light-active-color; + } + } + + .navbar-nav { + .nav-link { + color: $navbar-light-color; + + @include hover-focus { + color: $navbar-light-hover-color; + } + + &.disabled { + color: $navbar-light-disabled-color; + } + } + + .open > .nav-link, + .active > .nav-link, + .nav-link.open, + .nav-link.active { + color: $navbar-light-active-color; + } + } + + .navbar-toggler { + border-color: $navbar-light-toggler-border; + } + + .navbar-toggler-icon { + background-image: $navbar-light-toggler-bg; + } + + .navbar-text { + color: $navbar-light-color; + } +} + +// White links against a dark background +.navbar-inverse { + .navbar-brand, + .navbar-toggler { + color: $navbar-inverse-active-color; + + @include hover-focus { + color: $navbar-inverse-active-color; + } + } + + .navbar-nav { + .nav-link { + color: $navbar-inverse-color; + + @include hover-focus { + color: $navbar-inverse-hover-color; + } + + &.disabled { + color: $navbar-inverse-disabled-color; + } + } + + .open > .nav-link, + .active > .nav-link, + .nav-link.open, + .nav-link.active { + color: $navbar-inverse-active-color; + } + } + + .navbar-toggler { + border-color: $navbar-inverse-toggler-border; + } + + .navbar-toggler-icon { + background-image: $navbar-inverse-toggler-bg; + } + + .navbar-text { + color: $navbar-inverse-color; + } +} diff --git a/templates/assets/bootstrap/scss/_pagination.scss b/templates/assets/bootstrap/scss/_pagination.scss new file mode 100644 index 0000000..24aa028 --- /dev/null +++ b/templates/assets/bootstrap/scss/_pagination.scss @@ -0,0 +1,67 @@ +.pagination { + display: flex; + // 1-2: Disable browser default list styles + padding-left: 0; // 1 + list-style: none; // 2 + @include border-radius(); +} + +.page-item { + &:first-child { + .page-link { + margin-left: 0; + @include border-left-radius($border-radius); + } + } + &:last-child { + .page-link { + @include border-right-radius($border-radius); + } + } + + &.active .page-link { + z-index: 2; + color: $pagination-active-color; + background-color: $pagination-active-bg; + border-color: $pagination-active-border; + } + + &.disabled .page-link { + color: $pagination-disabled-color; + pointer-events: none; + cursor: $cursor-disabled; // While `pointer-events: none` removes the cursor in modern browsers, we provide a disabled cursor as a fallback. + background-color: $pagination-disabled-bg; + border-color: $pagination-disabled-border; + } +} + +.page-link { + position: relative; + display: block; + padding: $pagination-padding-y $pagination-padding-x; + margin-left: -1px; + line-height: $pagination-line-height; + color: $pagination-color; + background-color: $pagination-bg; + border: $pagination-border-width solid $pagination-border-color; + + @include hover-focus { + color: $pagination-hover-color; + text-decoration: none; + background-color: $pagination-hover-bg; + border-color: $pagination-hover-border; + } +} + + +// +// Sizing +// + +.pagination-lg { + @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg); +} + +.pagination-sm { + @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm); +} diff --git a/templates/assets/bootstrap/scss/_popover.scss b/templates/assets/bootstrap/scss/_popover.scss new file mode 100644 index 0000000..1b63634 --- /dev/null +++ b/templates/assets/bootstrap/scss/_popover.scss @@ -0,0 +1,171 @@ +.popover { + position: absolute; + top: 0; + left: 0; + z-index: $zindex-popover; + display: block; + max-width: $popover-max-width; + padding: $popover-inner-padding; + // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element. + // So reset our font and text properties to avoid inheriting weird values. + @include reset-text(); + font-size: $font-size-sm; + // Allow breaking very long words so they don't overflow the popover's bounds + word-wrap: break-word; + background-color: $popover-bg; + background-clip: padding-box; + border: $popover-border-width solid $popover-border-color; + @include border-radius($border-radius-lg); + @include box-shadow($popover-box-shadow); + + + // Popover directions + + &.popover-top, + &.bs-tether-element-attached-bottom { + margin-top: -$popover-arrow-width; + + &::before, + &::after { + left: 50%; + border-bottom-width: 0; + } + + &::before { + bottom: -$popover-arrow-outer-width; + margin-left: -$popover-arrow-outer-width; + border-top-color: $popover-arrow-outer-color; + } + + &::after { + bottom: -($popover-arrow-outer-width - 1); + margin-left: -$popover-arrow-width; + border-top-color: $popover-arrow-color; + } + } + + &.popover-right, + &.bs-tether-element-attached-left { + margin-left: $popover-arrow-width; + + &::before, + &::after { + top: 50%; + border-left-width: 0; + } + + &::before { + left: -$popover-arrow-outer-width; + margin-top: -$popover-arrow-outer-width; + border-right-color: $popover-arrow-outer-color; + } + + &::after { + left: -($popover-arrow-outer-width - 1); + margin-top: -($popover-arrow-outer-width - 1); + border-right-color: $popover-arrow-color; + } + } + + &.popover-bottom, + &.bs-tether-element-attached-top { + margin-top: $popover-arrow-width; + + &::before, + &::after { + left: 50%; + border-top-width: 0; + } + + &::before { + top: -$popover-arrow-outer-width; + margin-left: -$popover-arrow-outer-width; + border-bottom-color: $popover-arrow-outer-color; + } + + &::after { + top: -($popover-arrow-outer-width - 1); + margin-left: -$popover-arrow-width; + border-bottom-color: $popover-title-bg; + } + + // This will remove the popover-title's border just below the arrow + .popover-title::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 20px; + margin-left: -10px; + content: ""; + border-bottom: 1px solid $popover-title-bg; + } + } + + &.popover-left, + &.bs-tether-element-attached-right { + margin-left: -$popover-arrow-width; + + &::before, + &::after { + top: 50%; + border-right-width: 0; + } + + &::before { + right: -$popover-arrow-outer-width; + margin-top: -$popover-arrow-outer-width; + border-left-color: $popover-arrow-outer-color; + } + + &::after { + right: -($popover-arrow-outer-width - 1); + margin-top: -($popover-arrow-outer-width - 1); + border-left-color: $popover-arrow-color; + } + } +} + + +// Offset the popover to account for the popover arrow +.popover-title { + padding: $popover-title-padding-y $popover-title-padding-x; + margin-bottom: 0; // Reset the default from Reboot + font-size: $font-size-base; + background-color: $popover-title-bg; + border-bottom: $popover-border-width solid darken($popover-title-bg, 5%); + $offset-border-width: calc(#{$border-radius-lg} - #{$popover-border-width}); + @include border-top-radius($offset-border-width); + + &:empty { + display: none; + } +} + +.popover-content { + padding: $popover-content-padding-y $popover-content-padding-x; +} + + +// Arrows +// +// .popover-arrow is outer, .popover-arrow::after is inner + +.popover::before, +.popover::after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover::before { + content: ""; + border-width: $popover-arrow-outer-width; +} +.popover::after { + content: ""; + border-width: $popover-arrow-width; +} diff --git a/templates/assets/bootstrap/scss/_print.scss b/templates/assets/bootstrap/scss/_print.scss new file mode 100644 index 0000000..e20219a --- /dev/null +++ b/templates/assets/bootstrap/scss/_print.scss @@ -0,0 +1,119 @@ +// scss-lint:disable QualifyingElement + +// Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css + +// ========================================================================== +// Print styles. +// Inlined to avoid the additional HTTP request: +// http://www.phpied.com/delay-loading-your-print-css/ +// ========================================================================== + +@if $enable-print-styles { + @media print { + *, + *::before, + *::after, + p::first-letter, + div::first-letter, + blockquote::first-letter, + li::first-letter, + p::first-line, + div::first-line, + blockquote::first-line, + li::first-line { + // Bootstrap specific; comment out `color` and `background` + //color: #000 !important; // Black prints faster: + // http://www.sanbeiji.com/archives/953 + text-shadow: none !important; + //background: transparent !important; + box-shadow: none !important; + } + + a, + a:visited { + text-decoration: underline; + } + + // Bootstrap specific; comment the following selector out + //a[href]::after { + // content: " (" attr(href) ")"; + //} + + abbr[title]::after { + content: " (" attr(title) ")"; + } + + // Bootstrap specific; comment the following selector out + // + // Don't show links that are fragment identifiers, + // or use the `javascript:` pseudo protocol + // + + //a[href^="#"]::after, + //a[href^="javascript:"]::after { + // content: ""; + //} + + pre { + white-space: pre-wrap !important; + } + pre, + blockquote { + border: $border-width solid #999; // Bootstrap custom code; using `$border-width` instead of 1px + page-break-inside: avoid; + } + + // + // Printing Tables: + // http://css-discuss.incutio.com/wiki/Printing_Tables + // + + thead { + display: table-header-group; + } + + tr, + img { + page-break-inside: avoid; + } + + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + + h2, + h3 { + page-break-after: avoid; + } + + // Bootstrap specific changes start + + // Bootstrap components + .navbar { + display: none; + } + .badge { + border: $border-width solid #000; + } + + .table { + border-collapse: collapse !important; + + td, + th { + background-color: #fff !important; + } + } + .table-bordered { + th, + td { + border: 1px solid #ddd !important; + } + } + + // Bootstrap specific changes end + } +} diff --git a/templates/assets/bootstrap/scss/_progress.scss b/templates/assets/bootstrap/scss/_progress.scss new file mode 100644 index 0000000..ccca51e --- /dev/null +++ b/templates/assets/bootstrap/scss/_progress.scss @@ -0,0 +1,30 @@ +@keyframes progress-bar-stripes { + from { background-position: $progress-height 0; } + to { background-position: 0 0; } +} + +.progress { + display: flex; + overflow: hidden; // force rounded corners by cropping it + font-size: $progress-font-size; + line-height: $progress-height; + text-align: center; + background-color: $progress-bg; + @include border-radius($progress-border-radius); +} + +.progress-bar { + height: $progress-height; + line-height: $progress-height; + color: $progress-bar-color; + background-color: $progress-bar-bg; +} + +.progress-bar-striped { + @include gradient-striped(); + background-size: $progress-height $progress-height; +} + +.progress-bar-animated { + animation: progress-bar-stripes $progress-bar-animation-timing; +} diff --git a/templates/assets/bootstrap/scss/_reboot.scss b/templates/assets/bootstrap/scss/_reboot.scss new file mode 100644 index 0000000..c52e6f8 --- /dev/null +++ b/templates/assets/bootstrap/scss/_reboot.scss @@ -0,0 +1,484 @@ +// scss-lint:disable QualifyingElement, DuplicateProperty, VendorPrefix + +// Reboot +// +// Normalization of HTML elements, manually forked from Normalize.css to remove +// styles targeting irrelevant browsers while applying new styles. +// +// Normalize is licensed MIT. https://github.com/necolas/normalize.css + + +// Document +// +// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`. +// 2. Change the default font family in all browsers. +// 3. Correct the line height in all browsers. +// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS. +// 5. Setting @viewport causes scrollbars to overlap content in IE11 and Edge, so +// we force a non-overlapping, non-auto-hiding scrollbar to counteract. +// 6. Change the default tap highlight to be completely transparent in iOS. + +html { + box-sizing: border-box; // 1 + font-family: sans-serif; // 2 + line-height: 1.15; // 3 + -webkit-text-size-adjust: 100%; // 4 + -ms-text-size-adjust: 100%; // 4 + -ms-overflow-style: scrollbar; // 5 + -webkit-tap-highlight-color: rgba(0,0,0,0); // 6 +} + +*, +*::before, +*::after { + box-sizing: inherit; // 1 +} + +// IE10+ doesn't honor `<meta name="viewport">` in some cases. +@at-root { + @-ms-viewport { width: device-width; } +} + + +// Body +// +// 1. Remove the margin in all browsers. +// 2. As a best practice, apply a default `background-color`. + +body { + margin: 0; // 1 + font-family: $font-family-base; + font-size: $font-size-base; + font-weight: $font-weight-base; + line-height: $line-height-base; + color: $body-color; + background-color: $body-bg; // 2 +} + +// Suppress the focus outline on elements that cannot be accessed via keyboard. +// This prevents an unwanted focus outline from appearing around elements that +// might still respond to pointer events. +// +// Credit: https://github.com/suitcss/base +[tabindex="-1"]:focus { + outline: none !important; +} + + +// Content grouping +// +// 1. Add the correct box sizing in Firefox. +// 2. Show the overflow in Edge and IE. + +hr { + box-sizing: content-box; // 1 + height: 0; // 1 + overflow: visible; // 2 +} + + +// +// Typography +// + +// Remove top margins from headings +// +// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top +// margin for easier control within type scales as it avoids margin collapsing. +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: .5rem; +} + +// Reset margins on paragraphs +// +// Similarly, the top margin on `<p>`s get reset. However, we also reset the +// bottom margin to use `rem` units instead of `em`. +p { + margin-top: 0; + margin-bottom: 1rem; +} + +// Abbreviations +// +// 1. Remove the bottom border in Firefox 39-. +// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. +// 3. Add explicit cursor to indicate changed behavior. +// 4. Duplicate behavior to the data-* attribute for our tooltip plugin + +abbr[title], +abbr[data-original-title] { // 4 + text-decoration: underline; // 2 + text-decoration: underline dotted; // 2 + cursor: help; // 3 + border-bottom: 0; // 1 +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} + +ol, +ul, +dl { + margin-top: 0; + margin-bottom: 1rem; +} + +ol ol, +ul ul, +ol ul, +ul ol { + margin-bottom: 0; +} + +dt { + font-weight: $dt-font-weight; +} + +dd { + margin-bottom: .5rem; + margin-left: 0; // Undo browser default +} + +blockquote { + margin: 0 0 1rem; +} + +dfn { + font-style: italic; // Add the correct font style in Android 4.3- +} + +b, +strong { + font-weight: bolder; // Add the correct font weight in Chrome, Edge, and Safari +} + +small { + font-size: 80%; // Add the correct font size in all browsers +} + +// +// Prevent `sub` and `sup` elements from affecting the line height in +// all browsers. +// + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sub { bottom: -.25em; } +sup { top: -.5em; } + + +// +// Links +// + +a { + color: $link-color; + text-decoration: $link-decoration; + background-color: transparent; // Remove the gray background on active links in IE 10. + -webkit-text-decoration-skip: objects; // Remove gaps in links underline in iOS 8+ and Safari 8+. + + @include hover { + color: $link-hover-color; + text-decoration: $link-hover-decoration; + } +} + +// And undo these styles for placeholder links/named anchors (without href) +// which have not been made explicitly keyboard-focusable (without tabindex). +// It would be more straightforward to just use a[href] in previous block, but that +// causes specificity issues in many other styles that are too complex to fix. +// See https://github.com/twbs/bootstrap/issues/19402 + +a:not([href]):not([tabindex]) { + color: inherit; + text-decoration: none; + + @include hover-focus { + color: inherit; + text-decoration: none; + } + + &:focus { + outline: 0; + } +} + + +// +// Code +// + +pre, +code, +kbd, +samp { + font-family: monospace, monospace; // Correct the inheritance and scaling of font size in all browsers. + font-size: 1em; // Correct the odd `em` font sizing in all browsers. +} + +pre { + // Remove browser default top margin + margin-top: 0; + // Reset browser default of `1em` to use `rem`s + margin-bottom: 1rem; + // Don't allow content to break outside + overflow: auto; +} + + +// +// Figures +// + +figure { + // Apply a consistent margin strategy (matches our type styles). + margin: 0 0 1rem; +} + + +// +// Images and content +// + +img { + vertical-align: middle; + border-style: none; // Remove the border on images inside links in IE 10-. +} + +svg:not(:root) { + overflow: hidden; // Hide the overflow in IE +} + + +// Avoid 300ms click delay on touch devices that support the `touch-action` CSS property. +// +// In particular, unlike most other browsers, IE11+Edge on Windows 10 on touch devices and IE Mobile 10-11 +// DON'T remove the click delay when `<meta name="viewport" content="width=device-width">` is present. +// However, they DO support removing the click delay via `touch-action: manipulation`. +// See: +// * https://v4-alpha.getbootstrap.com/content/reboot/#click-delay-optimization-for-touch +// * http://caniuse.com/#feat=css-touch-action +// * https://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay + +a, +area, +button, +[role="button"], +input, +label, +select, +summary, +textarea { + touch-action: manipulation; +} + + +// +// Tables +// + +table { + border-collapse: collapse; // Prevent double borders +} + +caption { + padding-top: $table-cell-padding; + padding-bottom: $table-cell-padding; + color: $text-muted; + text-align: left; + caption-side: bottom; +} + +th { + // Matches default `<td>` alignment + text-align: left; +} + + +// +// Forms +// + +label { + // Allow labels to use `margin` for spacing. + display: inline-block; + margin-bottom: .5rem; +} + +// Work around a Firefox/IE bug where the transparent `button` background +// results in a loss of the default `button` focus styles. +// +// Credit: https://github.com/suitcss/base/ +button:focus { + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; // Remove the margin in Firefox and Safari + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +input { + overflow: visible; // Show the overflow in Edge +} + +button, +select { + text-transform: none; // Remove the inheritance of text transform in Firefox +} + +// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` +// controls in Android 4. +// 2. Correct the inability to style clickable types in iOS and Safari. +button, +html [type="button"], // 1 +[type="reset"], +[type="submit"] { + -webkit-appearance: button; // 2 +} + +// Remove inner border and padding from Firefox, but don't restore the outline like Normalize. +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + padding: 0; + border-style: none; +} + +input[type="radio"], +input[type="checkbox"] { + box-sizing: border-box; // 1. Add the correct box sizing in IE 10- + padding: 0; // 2. Remove the padding in IE 10- + + // Apply a disabled cursor for radios and checkboxes. + // + // Note: Neither radios nor checkboxes can be readonly. + &:disabled { + cursor: $cursor-disabled; + } +} + + +input[type="date"], +input[type="time"], +input[type="datetime-local"], +input[type="month"] { + // Remove the default appearance of temporal inputs to avoid a Mobile Safari + // bug where setting a custom line-height prevents text from being vertically + // centered within the input. + // See https://bugs.webkit.org/show_bug.cgi?id=139848 + // and https://github.com/twbs/bootstrap/issues/11266 + -webkit-appearance: listbox; +} + +textarea { + overflow: auto; // Remove the default vertical scrollbar in IE. + // Textareas should really only resize vertically so they don't break their (horizontal) containers. + resize: vertical; +} + +fieldset { + // Browsers set a default `min-width: min-content;` on fieldsets, + // unlike e.g. `<div>`s, which have `min-width: 0;` by default. + // So we reset that to ensure fieldsets behave more like a standard block element. + // See https://github.com/twbs/bootstrap/issues/12359 + // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements + min-width: 0; + // Reset the default outline behavior of fieldsets so they don't affect page layout. + padding: 0; + margin: 0; + border: 0; +} + +// 1. Correct the text wrapping in Edge and IE. +// 2. Correct the color inheritance from `fieldset` elements in IE. +legend { + display: block; + width: 100%; + max-width: 100%; // 1 + padding: 0; + margin-bottom: .5rem; + font-size: 1.5rem; + line-height: inherit; + color: inherit; // 2 + white-space: normal; // 1 +} + +progress { + vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera. +} + +// Correct the cursor style of increment and decrement buttons in Chrome. +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +[type="search"] { + // This overrides the extra rounded corners on search inputs in iOS so that our + // `.form-control` class can properly style them. Note that this cannot simply + // be added to `.form-control` as it's not specific enough. For details, see + // https://github.com/twbs/bootstrap/issues/11586. + outline-offset: -2px; // 2. Correct the outline style in Safari. + -webkit-appearance: none; +} + +// +// Remove the inner padding and cancel buttons in Chrome and Safari on macOS. +// + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +// +// 1. Correct the inability to style clickable types in iOS and Safari. +// 2. Change font properties to `inherit` in Safari. +// + +::-webkit-file-upload-button { + font: inherit; // 2 + -webkit-appearance: button; // 1 +} + +// +// Correct element displays +// + +output { + display: inline-block; +} + +summary { + display: list-item; // Add the correct display in all browsers +} + +template { + display: none; // Add the correct display in IE +} + +// Always hide an element with the `hidden` HTML attribute (from PureCSS). +// Needed for proper display in IE 10-. +[hidden] { + display: none !important; +} diff --git a/templates/assets/bootstrap/scss/_responsive-embed.scss b/templates/assets/bootstrap/scss/_responsive-embed.scss new file mode 100644 index 0000000..d3362b6 --- /dev/null +++ b/templates/assets/bootstrap/scss/_responsive-embed.scss @@ -0,0 +1,52 @@ +// Credit: Nicolas Gallagher and SUIT CSS. + +.embed-responsive { + position: relative; + display: block; + width: 100%; + padding: 0; + overflow: hidden; + + &::before { + display: block; + content: ""; + } + + .embed-responsive-item, + iframe, + embed, + object, + video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; + } +} + +.embed-responsive-21by9 { + &::before { + padding-top: percentage(9 / 21); + } +} + +.embed-responsive-16by9 { + &::before { + padding-top: percentage(9 / 16); + } +} + +.embed-responsive-4by3 { + &::before { + padding-top: percentage(3 / 4); + } +} + +.embed-responsive-1by1 { + &::before { + padding-top: percentage(1 / 1); + } +} diff --git a/templates/assets/bootstrap/scss/_tables.scss b/templates/assets/bootstrap/scss/_tables.scss new file mode 100644 index 0000000..f041f60 --- /dev/null +++ b/templates/assets/bootstrap/scss/_tables.scss @@ -0,0 +1,169 @@ +// +// Basic Bootstrap table +// + +.table { + width: 100%; + max-width: 100%; + margin-bottom: $spacer; + background-color: $table-bg; // Reset for nesting within parents with `background-color`. + + th, + td { + padding: $table-cell-padding; + vertical-align: top; + border-top: $table-border-width solid $table-border-color; + } + + thead th { + vertical-align: bottom; + border-bottom: (2 * $table-border-width) solid $table-border-color; + } + + tbody + tbody { + border-top: (2 * $table-border-width) solid $table-border-color; + } + + .table { + background-color: $body-bg; + } +} + + +// +// Condensed table w/ half padding +// + +.table-sm { + th, + td { + padding: $table-sm-cell-padding; + } +} + + +// Bordered version +// +// Add borders all around the table and between all the columns. + +.table-bordered { + border: $table-border-width solid $table-border-color; + + th, + td { + border: $table-border-width solid $table-border-color; + } + + thead { + th, + td { + border-bottom-width: (2 * $table-border-width); + } + } +} + + +// Zebra-striping +// +// Default zebra-stripe styles (alternating gray and transparent backgrounds) + +.table-striped { + tbody tr:nth-of-type(odd) { + background-color: $table-bg-accent; + } +} + + +// Hover effect +// +// Placed here since it has to come after the potential zebra striping + +.table-hover { + tbody tr { + @include hover { + background-color: $table-bg-hover; + } + } +} + + +// Table backgrounds +// +// Exact selectors below required to override `.table-striped` and prevent +// inheritance to nested tables. + +// Generate the contextual variants +@include table-row-variant(active, $table-bg-active); +@include table-row-variant(success, $state-success-bg); +@include table-row-variant(info, $state-info-bg); +@include table-row-variant(warning, $state-warning-bg); +@include table-row-variant(danger, $state-danger-bg); + + +// Inverse styles +// +// Same table markup, but inverted color scheme: dark background and light text. + +.thead-inverse { + th { + color: $table-inverse-color; + background-color: $table-inverse-bg; + } +} + +.thead-default { + th { + color: $table-head-color; + background-color: $table-head-bg; + } +} + +.table-inverse { + color: $table-inverse-color; + background-color: $table-inverse-bg; + + th, + td, + thead th { + border-color: $table-inverse-border; + } + + &.table-bordered { + border: 0; + } + + &.table-striped { + tbody tr:nth-of-type(odd) { + background-color: $table-inverse-bg-accent; + } + } + + &.table-hover { + tbody tr { + @include hover { + background-color: $table-inverse-bg-hover; + } + } + } +} + + +// Responsive tables +// +// Add `.table-responsive` to `.table`s and we'll make them mobile friendly by +// enabling horizontal scrolling. Only applies <768px. Everything above that +// will display normally. + +.table-responsive { + @include media-breakpoint-down(md) { + display: block; + width: 100%; + overflow-x: auto; + -ms-overflow-style: -ms-autohiding-scrollbar; // See https://github.com/twbs/bootstrap/pull/10057 + + // Prevent double border on horizontal scroll due to use of `display: block;` + &.table-bordered { + border: 0; + } + } +} diff --git a/templates/assets/bootstrap/scss/_tooltip.scss b/templates/assets/bootstrap/scss/_tooltip.scss new file mode 100644 index 0000000..24e198d --- /dev/null +++ b/templates/assets/bootstrap/scss/_tooltip.scss @@ -0,0 +1,90 @@ +// Base class +.tooltip { + position: absolute; + z-index: $zindex-tooltip; + display: block; + // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element. + // So reset our font and text properties to avoid inheriting weird values. + @include reset-text(); + font-size: $font-size-sm; + // Allow breaking very long words so they don't overflow the tooltip's bounds + word-wrap: break-word; + opacity: 0; + + &.show { opacity: $tooltip-opacity; } + + &.tooltip-top, + &.bs-tether-element-attached-bottom { + padding: $tooltip-arrow-width 0; + margin-top: -$tooltip-margin; + + .tooltip-inner::before { + bottom: 0; + left: 50%; + margin-left: -$tooltip-arrow-width; + content: ""; + border-width: $tooltip-arrow-width $tooltip-arrow-width 0; + border-top-color: $tooltip-arrow-color; + } + } + &.tooltip-right, + &.bs-tether-element-attached-left { + padding: 0 $tooltip-arrow-width; + margin-left: $tooltip-margin; + + .tooltip-inner::before { + top: 50%; + left: 0; + margin-top: -$tooltip-arrow-width; + content: ""; + border-width: $tooltip-arrow-width $tooltip-arrow-width $tooltip-arrow-width 0; + border-right-color: $tooltip-arrow-color; + } + } + &.tooltip-bottom, + &.bs-tether-element-attached-top { + padding: $tooltip-arrow-width 0; + margin-top: $tooltip-margin; + + .tooltip-inner::before { + top: 0; + left: 50%; + margin-left: -$tooltip-arrow-width; + content: ""; + border-width: 0 $tooltip-arrow-width $tooltip-arrow-width; + border-bottom-color: $tooltip-arrow-color; + } + } + &.tooltip-left, + &.bs-tether-element-attached-right { + padding: 0 $tooltip-arrow-width; + margin-left: -$tooltip-margin; + + .tooltip-inner::before { + top: 50%; + right: 0; + margin-top: -$tooltip-arrow-width; + content: ""; + border-width: $tooltip-arrow-width 0 $tooltip-arrow-width $tooltip-arrow-width; + border-left-color: $tooltip-arrow-color; + } + } +} + +// Wrapper for the tooltip content +.tooltip-inner { + max-width: $tooltip-max-width; + padding: $tooltip-padding-y $tooltip-padding-x; + color: $tooltip-color; + text-align: center; + background-color: $tooltip-bg; + @include border-radius($border-radius); + + &::before { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + } +} diff --git a/templates/assets/bootstrap/scss/_transitions.scss b/templates/assets/bootstrap/scss/_transitions.scss new file mode 100644 index 0000000..86c04a5 --- /dev/null +++ b/templates/assets/bootstrap/scss/_transitions.scss @@ -0,0 +1,34 @@ +.fade { + opacity: 0; + @include transition($transition-fade); + + &.show { + opacity: 1; + } +} + +.collapse { + display: none; + &.show { + display: block; + } +} + +tr { + &.collapse.show { + display: table-row; + } +} + +tbody { + &.collapse.show { + display: table-row-group; + } +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + @include transition($transition-collapse); +} diff --git a/templates/assets/bootstrap/scss/_type.scss b/templates/assets/bootstrap/scss/_type.scss new file mode 100644 index 0000000..fc9c791 --- /dev/null +++ b/templates/assets/bootstrap/scss/_type.scss @@ -0,0 +1,143 @@ +// +// Headings +// + +h1, h2, h3, h4, h5, h6, +.h1, .h2, .h3, .h4, .h5, .h6 { + margin-bottom: $headings-margin-bottom; + font-family: $headings-font-family; + font-weight: $headings-font-weight; + line-height: $headings-line-height; + color: $headings-color; +} + +h1, .h1 { font-size: $font-size-h1; } +h2, .h2 { font-size: $font-size-h2; } +h3, .h3 { font-size: $font-size-h3; } +h4, .h4 { font-size: $font-size-h4; } +h5, .h5 { font-size: $font-size-h5; } +h6, .h6 { font-size: $font-size-h6; } + +.lead { + font-size: $lead-font-size; + font-weight: $lead-font-weight; +} + +// Type display classes +.display-1 { + font-size: $display1-size; + font-weight: $display1-weight; + line-height: $display-line-height; +} +.display-2 { + font-size: $display2-size; + font-weight: $display2-weight; + line-height: $display-line-height; +} +.display-3 { + font-size: $display3-size; + font-weight: $display3-weight; + line-height: $display-line-height; +} +.display-4 { + font-size: $display4-size; + font-weight: $display4-weight; + line-height: $display-line-height; +} + + +// +// Horizontal rules +// + +hr { + margin-top: 1rem; + margin-bottom: 1rem; + border: 0; + border-top: $hr-border-width solid $hr-border-color; +} + + +// +// Emphasis +// + +small, +.small { + font-size: $small-font-size; + font-weight: $font-weight-normal; +} + +mark, +.mark { + padding: $mark-padding; + background-color: $mark-bg; +} + + +// +// Lists +// + +.list-unstyled { + @include list-unstyled; +} + +// Inline turns list items into inline-block +.list-inline { + @include list-unstyled; +} +.list-inline-item { + display: inline-block; + + &:not(:last-child) { + margin-right: $list-inline-padding; + } +} + + +// +// Misc +// + +// Builds on `abbr` +.initialism { + font-size: 90%; + text-transform: uppercase; +} + +// Blockquotes +.blockquote { + padding: ($spacer / 2) $spacer; + margin-bottom: $spacer; + font-size: $blockquote-font-size; + border-left: $blockquote-border-width solid $blockquote-border-color; +} + +.blockquote-footer { + display: block; + font-size: 80%; // back to default font-size + color: $blockquote-small-color; + + &::before { + content: "\2014 \00A0"; // em dash, nbsp + } +} + +// Opposite alignment of blockquote +.blockquote-reverse { + padding-right: $spacer; + padding-left: 0; + text-align: right; + border-right: $blockquote-border-width solid $blockquote-border-color; + border-left: 0; +} + +.blockquote-reverse .blockquote-footer { + &::before { + content: ""; + } + &::after { + content: "\00A0 \2014"; // nbsp, em dash + } +} diff --git a/templates/assets/bootstrap/scss/_utilities.scss b/templates/assets/bootstrap/scss/_utilities.scss new file mode 100644 index 0000000..7d08ff2 --- /dev/null +++ b/templates/assets/bootstrap/scss/_utilities.scss @@ -0,0 +1,13 @@ +@import "utilities/align"; +@import "utilities/background"; +@import "utilities/borders"; +@import "utilities/clearfix"; +@import "utilities/display"; +@import "utilities/flex"; +@import "utilities/float"; +@import "utilities/position"; +@import "utilities/screenreaders"; +@import "utilities/sizing"; +@import "utilities/spacing"; +@import "utilities/text"; +@import "utilities/visibility"; diff --git a/templates/assets/bootstrap/scss/_variables.scss b/templates/assets/bootstrap/scss/_variables.scss new file mode 100644 index 0000000..69eb401 --- /dev/null +++ b/templates/assets/bootstrap/scss/_variables.scss @@ -0,0 +1,921 @@ +// Variables +// +// Copy settings from this file into the provided `_custom.scss` to override +// the Bootstrap defaults without modifying key, versioned files. + + +// Table of Contents +// +// Colors +// Options +// Spacing +// Body +// Links +// Grid breakpoints +// Grid containers +// Grid columns +// Fonts +// Components +// Tables +// Buttons +// Forms +// Dropdowns +// Z-index master list +// Navbar +// Navs +// Pagination +// Jumbotron +// Form states and alerts +// Cards +// Tooltips +// Popovers +// Badges +// Modals +// Alerts +// Progress bars +// List group +// Image thumbnails +// Figures +// Breadcrumbs +// Carousel +// Close +// Code + +@mixin _assert-ascending($map, $map-name) { + $prev-key: null; + $prev-num: null; + @each $key, $num in $map { + @if $prev-num == null { + // Do nothing + } @else if not comparable($prev-num, $num) { + @warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !"; + } @else if $prev-num >= $num { + @warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !"; + } + $prev-key: $key; + $prev-num: $num; + } +} + +// Replace `$search` with `$replace` in `$string` +// @author Hugo Giraudel +// @param {String} $string - Initial string +// @param {String} $search - Substring to replace +// @param {String} $replace ('') - New value +// @return {String} - Updated string +@function str-replace($string, $search, $replace: "") { + $index: str-index($string, $search); + + @if $index { + @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); + } + + @return $string; +} + +@mixin _assert-starts-at-zero($map) { + $values: map-values($map); + $first-value: nth($values, 1); + @if $first-value != 0 { + @warn "First breakpoint in `$grid-breakpoints` must start at 0, but starts at #{$first-value}."; + } +} + + +// General variable structure +// +// Variable format should follow the `$component-modifier-state-property` order. + + +// Colors +// +// Grayscale and brand colors for use across Bootstrap. + +// Start with assigning color names to specific hex values. +$white: #fff !default; +$black: #000 !default; +$red: #d9534f !default; +$orange: #f0ad4e !default; +$yellow: #ffd500 !default; +$green: #5cb85c !default; +$blue: #0275d8 !default; +$teal: #5bc0de !default; +$pink: #ff5b77 !default; +$purple: #613d7c !default; + +// Create grayscale +$gray-dark: #292b2c !default; +$gray: #464a4c !default; +$gray-light: #636c72 !default; +$gray-lighter: #eceeef !default; +$gray-lightest: #f7f7f9 !default; + +// Reassign color vars to semantic color scheme +$brand-primary: $blue !default; +$brand-success: $green !default; +$brand-info: $teal !default; +$brand-warning: $orange !default; +$brand-danger: $red !default; +$brand-inverse: $gray-dark !default; + + +// Options +// +// Quickly modify global styling by enabling or disabling optional features. + +$enable-rounded: true !default; +$enable-shadows: false !default; +$enable-gradients: false !default; +$enable-transitions: true !default; +$enable-hover-media-query: false !default; +$enable-grid-classes: true !default; +$enable-print-styles: true !default; + + +// Spacing +// +// Control the default styling of most Bootstrap elements by modifying these +// variables. Mostly focused on spacing. +// You can add more entries to the $spacers map, should you need more variation. + +$spacer: 1rem !default; +$spacers: ( + 0: 0, + 1: ($spacer * .25), + 2: ($spacer * .5), + 3: $spacer, + 4: ($spacer * 1.5), + 5: ($spacer * 3) +) !default; + +// This variable affects the `.h-*` and `.w-*` classes. +$sizes: ( + 25: 25%, + 50: 50%, + 75: 75%, + 100: 100% +) !default; + +// Body +// +// Settings for the `<body>` element. + +$body-bg: $white !default; +$body-color: $gray-dark !default; + +// Links +// +// Style anchor elements. + +$link-color: $brand-primary !default; +$link-decoration: none !default; +$link-hover-color: darken($link-color, 15%) !default; +$link-hover-decoration: underline !default; + + +// Grid breakpoints +// +// Define the minimum dimensions at which your layout will change, +// adapting to different screen sizes, for use in media queries. + +$grid-breakpoints: ( + xs: 0, + sm: 576px, + md: 768px, + lg: 992px, + xl: 1200px +) !default; +@include _assert-ascending($grid-breakpoints, "$grid-breakpoints"); +@include _assert-starts-at-zero($grid-breakpoints); + + +// Grid containers +// +// Define the maximum width of `.container` for different screen sizes. + +$container-max-widths: ( + sm: 540px, + md: 720px, + lg: 960px, + xl: 1140px +) !default; +@include _assert-ascending($container-max-widths, "$container-max-widths"); + + +// Grid columns +// +// Set the number of columns and specify the width of the gutters. + +$grid-columns: 12 !default; +$grid-gutter-width-base: 30px !default; +$grid-gutter-widths: ( + xs: $grid-gutter-width-base, + sm: $grid-gutter-width-base, + md: $grid-gutter-width-base, + lg: $grid-gutter-width-base, + xl: $grid-gutter-width-base +) !default; + + +// Components +// +// Define common padding and border radius sizes and more. + +$line-height-lg: (4 / 3) !default; +$line-height-sm: 1.5 !default; + +$border-width: 1px !default; + +$border-radius: .25rem !default; +$border-radius-lg: .3rem !default; +$border-radius-sm: .2rem !default; + +$component-active-color: $white !default; +$component-active-bg: $brand-primary !default; + +$caret-width: .3em !default; + +$transition-base: all .2s ease-in-out !default; +$transition-fade: opacity .15s linear !default; +$transition-collapse: height .35s ease !default; + + +// Fonts +// +// Font, line-height, and color for body text, headings, and more. + +$font-family-sans-serif: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !default; +$font-family-monospace: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default; +$font-family-base: $font-family-sans-serif !default; + +$font-size-base: 1rem !default; // Assumes the browser default, typically `16px` +$font-size-lg: 1.25rem !default; +$font-size-sm: .875rem !default; +$font-size-xs: .75rem !default; + +$font-weight-normal: normal !default; +$font-weight-bold: bold !default; + +$font-weight-base: $font-weight-normal !default; +$line-height-base: 1.5 !default; + +$font-size-h1: 2.5rem !default; +$font-size-h2: 2rem !default; +$font-size-h3: 1.75rem !default; +$font-size-h4: 1.5rem !default; +$font-size-h5: 1.25rem !default; +$font-size-h6: 1rem !default; + +$headings-margin-bottom: ($spacer / 2) !default; +$headings-font-family: inherit !default; +$headings-font-weight: 500 !default; +$headings-line-height: 1.1 !default; +$headings-color: inherit !default; + +$display1-size: 6rem !default; +$display2-size: 5.5rem !default; +$display3-size: 4.5rem !default; +$display4-size: 3.5rem !default; + +$display1-weight: 300 !default; +$display2-weight: 300 !default; +$display3-weight: 300 !default; +$display4-weight: 300 !default; +$display-line-height: $headings-line-height !default; + +$lead-font-size: 1.25rem !default; +$lead-font-weight: 300 !default; + +$small-font-size: 80% !default; + +$text-muted: $gray-light !default; + +$blockquote-small-color: $gray-light !default; +$blockquote-font-size: ($font-size-base * 1.25) !default; +$blockquote-border-color: $gray-lighter !default; +$blockquote-border-width: .25rem !default; + +$hr-border-color: rgba($black,.1) !default; +$hr-border-width: $border-width !default; + +$mark-padding: .2em !default; + +$dt-font-weight: $font-weight-bold !default; + +$kbd-box-shadow: inset 0 -.1rem 0 rgba($black,.25) !default; +$nested-kbd-font-weight: $font-weight-bold !default; + +$list-inline-padding: 5px !default; + + +// Tables +// +// Customizes the `.table` component with basic values, each used across all table variations. + +$table-cell-padding: .75rem !default; +$table-sm-cell-padding: .3rem !default; + +$table-bg: transparent !default; +$table-bg-accent: rgba($black,.05) !default; +$table-bg-hover: rgba($black,.075) !default; +$table-bg-active: $table-bg-hover !default; + +$table-border-width: $border-width !default; +$table-border-color: $gray-lighter !default; + +$table-head-bg: $gray-lighter !default; +$table-head-color: $gray !default; + +$table-inverse-bg: $gray-dark !default; +$table-inverse-bg-accent: rgba($white, .05) !default; +$table-inverse-bg-hover: rgba($white, .075) !default; +$table-inverse-bg-active: $table-inverse-bg-hover !default; +$table-inverse-border: lighten($gray-dark, 7.5%) !default; +$table-inverse-color: $body-bg !default; + + +// Buttons +// +// For each of Bootstrap's buttons, define text, background and border color. + +$btn-padding-x: 1rem !default; +$btn-padding-y: .5rem !default; +$btn-line-height: 1.25 !default; +$btn-font-weight: $font-weight-normal !default; +$btn-box-shadow: inset 0 1px 0 rgba($white,.15), 0 1px 1px rgba($black,.075) !default; +$btn-focus-box-shadow: 0 0 0 2px rgba($brand-primary, .25) !default; +$btn-active-box-shadow: inset 0 3px 5px rgba($black,.125) !default; + +$btn-primary-color: $white !default; +$btn-primary-bg: $brand-primary !default; +$btn-primary-border: $btn-primary-bg !default; + +$btn-secondary-color: $gray-dark !default; +$btn-secondary-bg: $white !default; +$btn-secondary-border: #ccc !default; + +$btn-info-color: $white !default; +$btn-info-bg: $brand-info !default; +$btn-info-border: $btn-info-bg !default; + +$btn-success-color: $white !default; +$btn-success-bg: $brand-success !default; +$btn-success-border: $btn-success-bg !default; + +$btn-warning-color: $white !default; +$btn-warning-bg: $brand-warning !default; +$btn-warning-border: $btn-warning-bg !default; + +$btn-danger-color: $white !default; +$btn-danger-bg: $brand-danger !default; +$btn-danger-border: $btn-danger-bg !default; + +$btn-link-disabled-color: $gray-light !default; + +$btn-padding-x-sm: .5rem !default; +$btn-padding-y-sm: .25rem !default; + +$btn-padding-x-lg: 1.5rem !default; +$btn-padding-y-lg: .75rem !default; + +$btn-block-spacing-y: .5rem !default; + +// Allows for customizing button radius independently from global border radius +$btn-border-radius: $border-radius !default; +$btn-border-radius-lg: $border-radius-lg !default; +$btn-border-radius-sm: $border-radius-sm !default; + +$btn-transition: all .2s ease-in-out !default; + + +// Forms + +$input-padding-x: .75rem !default; +$input-padding-y: .5rem !default; +$input-line-height: 1.25 !default; + +$input-bg: $white !default; +$input-bg-disabled: $gray-lighter !default; + +$input-color: $gray !default; +$input-border-color: rgba($black,.15) !default; +$input-btn-border-width: $border-width !default; // For form controls and buttons +$input-box-shadow: inset 0 1px 1px rgba($black,.075) !default; + +$input-border-radius: $border-radius !default; +$input-border-radius-lg: $border-radius-lg !default; +$input-border-radius-sm: $border-radius-sm !default; + +$input-bg-focus: $input-bg !default; +$input-border-focus: lighten($brand-primary, 25%) !default; +$input-box-shadow-focus: $input-box-shadow, rgba($input-border-focus, .6) !default; +$input-color-focus: $input-color !default; + +$input-color-placeholder: $gray-light !default; + +$input-padding-x-sm: .5rem !default; +$input-padding-y-sm: .25rem !default; + +$input-padding-x-lg: 1.5rem !default; +$input-padding-y-lg: .75rem !default; + +$input-height: (($font-size-base * $input-line-height) + ($input-padding-y * 2)) !default; +$input-height-lg: (($font-size-lg * $line-height-lg) + ($input-padding-y-lg * 2)) !default; +$input-height-sm: (($font-size-sm * $line-height-sm) + ($input-padding-y-sm * 2)) !default; + +$input-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s !default; + +$form-text-margin-top: .25rem !default; +$form-feedback-margin-top: $form-text-margin-top !default; + +$form-check-margin-bottom: .5rem !default; +$form-check-input-gutter: 1.25rem !default; +$form-check-input-margin-y: .25rem !default; +$form-check-input-margin-x: .25rem !default; + +$form-check-inline-margin-x: .75rem !default; + +$form-group-margin-bottom: 1rem !default; + +$input-group-addon-bg: $gray-lighter !default; +$input-group-addon-border-color: $input-border-color !default; + +$cursor-disabled: not-allowed !default; + +$custom-control-gutter: 1.5rem !default; +$custom-control-spacer-x: 1rem !default; +$custom-control-spacer-y: .25rem !default; + +$custom-control-indicator-size: 1rem !default; +$custom-control-indicator-bg: #ddd !default; +$custom-control-indicator-bg-size: 50% 50% !default; +$custom-control-indicator-box-shadow: inset 0 .25rem .25rem rgba($black,.1) !default; + +$custom-control-disabled-cursor: $cursor-disabled !default; +$custom-control-disabled-indicator-bg: $gray-lighter !default; +$custom-control-disabled-description-color: $gray-light !default; + +$custom-control-checked-indicator-color: $white !default; +$custom-control-checked-indicator-bg: $brand-primary !default; +$custom-control-checked-indicator-box-shadow: none !default; + +$custom-control-focus-indicator-box-shadow: 0 0 0 1px $body-bg, 0 0 0 3px $brand-primary !default; + +$custom-control-active-indicator-color: $white !default; +$custom-control-active-indicator-bg: lighten($brand-primary, 35%) !default; +$custom-control-active-indicator-box-shadow: none !default; + +$custom-checkbox-radius: $border-radius !default; +$custom-checkbox-checked-icon: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#{$custom-control-checked-indicator-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"), "#", "%23") !default; + +$custom-checkbox-indeterminate-bg: $brand-primary !default; +$custom-checkbox-indeterminate-indicator-color: $custom-control-checked-indicator-color !default; +$custom-checkbox-indeterminate-icon: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='#{$custom-checkbox-indeterminate-indicator-color}' d='M0 2h4'/%3E%3C/svg%3E"), "#", "%23") !default; +$custom-checkbox-indeterminate-box-shadow: none !default; + +$custom-radio-radius: 50% !default; +$custom-radio-checked-icon: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='#{$custom-control-checked-indicator-color}'/%3E%3C/svg%3E"), "#", "%23") !default; + +$custom-select-padding-x: .75rem !default; +$custom-select-padding-y: .375rem !default; +$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator +$custom-select-line-height: $input-line-height !default; +$custom-select-color: $input-color !default; +$custom-select-disabled-color: $gray-light !default; +$custom-select-bg: $white !default; +$custom-select-disabled-bg: $gray-lighter !default; +$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions +$custom-select-indicator-color: #333 !default; +$custom-select-indicator: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E"), "#", "%23") !default; +$custom-select-border-width: $input-btn-border-width !default; +$custom-select-border-color: $input-border-color !default; +$custom-select-border-radius: $border-radius !default; + +$custom-select-focus-border-color: lighten($brand-primary, 25%) !default; +$custom-select-focus-box-shadow: inset 0 1px 2px rgba($black, .075), 0 0 5px rgba($custom-select-focus-border-color, .5) !default; + +$custom-select-sm-font-size: 75% !default; + +$custom-file-height: 2.5rem !default; +$custom-file-width: 14rem !default; +$custom-file-focus-box-shadow: 0 0 0 .075rem $white, 0 0 0 .2rem $brand-primary !default; + +$custom-file-padding-x: .5rem !default; +$custom-file-padding-y: 1rem !default; +$custom-file-line-height: 1.5 !default; +$custom-file-color: $gray !default; +$custom-file-bg: $white !default; +$custom-file-border-width: $border-width !default; +$custom-file-border-color: $input-border-color !default; +$custom-file-border-radius: $border-radius !default; +$custom-file-box-shadow: inset 0 .2rem .4rem rgba($black,.05) !default; +$custom-file-button-color: $custom-file-color !default; +$custom-file-button-bg: $gray-lighter !default; +$custom-file-text: ( + placeholder: ( + en: "Choose file..." + ), + button-label: ( + en: "Browse" + ) +) !default; + + +// Form validation icons +$form-icon-success-color: $brand-success !default; +$form-icon-success: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#{$form-icon-success-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E"), "#", "%23") !default; + +$form-icon-warning-color: $brand-warning !default; +$form-icon-warning: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#{$form-icon-warning-color}' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E"), "#", "%23") !default; + +$form-icon-danger-color: $brand-danger !default; +$form-icon-danger: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$form-icon-danger-color}' viewBox='-2 -2 7 7'%3E%3Cpath stroke='#{$form-icon-danger-color}' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E"), "#", "%23") !default; + + +// Dropdowns +// +// Dropdown menu container and contents. + +$dropdown-min-width: 10rem !default; +$dropdown-padding-y: .5rem !default; +$dropdown-margin-top: .125rem !default; +$dropdown-bg: $white !default; +$dropdown-border-color: rgba($black,.15) !default; +$dropdown-border-width: $border-width !default; +$dropdown-divider-bg: $gray-lighter !default; +$dropdown-box-shadow: 0 .5rem 1rem rgba($black,.175) !default; + +$dropdown-link-color: $gray-dark !default; +$dropdown-link-hover-color: darken($gray-dark, 5%) !default; +$dropdown-link-hover-bg: $gray-lightest !default; + +$dropdown-link-active-color: $component-active-color !default; +$dropdown-link-active-bg: $component-active-bg !default; + +$dropdown-link-disabled-color: $gray-light !default; + +$dropdown-item-padding-x: 1.5rem !default; + +$dropdown-header-color: $gray-light !default; + + +// Z-index master list +// +// Warning: Avoid customizing these values. They're used for a bird's eye view +// of components dependent on the z-axis and are designed to all work together. + +$zindex-dropdown-backdrop: 990 !default; +$zindex-dropdown: 1000 !default; +$zindex-sticky: 1020 !default; +$zindex-fixed: 1030 !default; +$zindex-modal-backdrop: 1040 !default; +$zindex-modal: 1050 !default; +$zindex-popover: 1060 !default; +$zindex-tooltip: 1070 !default; + +// Navbar + +$navbar-padding-x: $spacer !default; +$navbar-padding-y: ($spacer / 2) !default; + +$navbar-toggler-padding-x: .75rem !default; +$navbar-toggler-padding-y: .25rem !default; +$navbar-toggler-font-size: $font-size-lg !default; +$navbar-toggler-border-radius: $btn-border-radius !default; + +$navbar-inverse-color: rgba($white,.5) !default; +$navbar-inverse-hover-color: rgba($white,.75) !default; +$navbar-inverse-active-color: rgba($white,1) !default; +$navbar-inverse-disabled-color: rgba($white,.25) !default; +$navbar-inverse-toggler-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-inverse-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"), "#", "%23") !default; +$navbar-inverse-toggler-border: rgba($white,.1) !default; + +$navbar-light-color: rgba($black,.5) !default; +$navbar-light-hover-color: rgba($black,.7) !default; +$navbar-light-active-color: rgba($black,.9) !default; +$navbar-light-disabled-color: rgba($black,.3) !default; +$navbar-light-toggler-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-light-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"), "#", "%23") !default; +$navbar-light-toggler-border: rgba($black,.1) !default; + +// Navs + +$nav-link-padding: .5em 1em !default; +$nav-disabled-link-color: $gray-light !default; + +$nav-tabs-border-color: #ddd !default; +$nav-tabs-border-width: $border-width !default; +$nav-tabs-border-radius: $border-radius !default; +$nav-tabs-link-hover-border-color: $gray-lighter !default; +$nav-tabs-active-link-color: $gray !default; +$nav-tabs-active-link-bg: $body-bg !default; +$nav-tabs-active-link-border-color: #ddd !default; + +$nav-pills-border-radius: $border-radius !default; +$nav-pills-active-link-color: $component-active-color !default; +$nav-pills-active-link-bg: $component-active-bg !default; + + +// Pagination + +$pagination-padding-x: .75rem !default; +$pagination-padding-y: .5rem !default; +$pagination-padding-x-sm: .5rem !default; +$pagination-padding-y-sm: .25rem !default; +$pagination-padding-x-lg: 1.5rem !default; +$pagination-padding-y-lg: .75rem !default; +$pagination-line-height: 1.25 !default; + +$pagination-color: $link-color !default; +$pagination-bg: $white !default; +$pagination-border-width: $border-width !default; +$pagination-border-color: #ddd !default; + +$pagination-hover-color: $link-hover-color !default; +$pagination-hover-bg: $gray-lighter !default; +$pagination-hover-border: #ddd !default; + +$pagination-active-color: $white !default; +$pagination-active-bg: $brand-primary !default; +$pagination-active-border: $brand-primary !default; + +$pagination-disabled-color: $gray-light !default; +$pagination-disabled-bg: $white !default; +$pagination-disabled-border: #ddd !default; + + +// Jumbotron + +$jumbotron-padding: 2rem !default; +$jumbotron-bg: $gray-lighter !default; + + +// Form states and alerts +// +// Define colors for form feedback states and, by default, alerts. + +$state-success-text: #3c763d !default; +$state-success-bg: #dff0d8 !default; +$state-success-border: darken($state-success-bg, 5%) !default; + +$state-info-text: #31708f !default; +$state-info-bg: #d9edf7 !default; +$state-info-border: darken($state-info-bg, 7%) !default; + +$state-warning-text: #8a6d3b !default; +$state-warning-bg: #fcf8e3 !default; +$mark-bg: $state-warning-bg !default; +$state-warning-border: darken($state-warning-bg, 5%) !default; + +$state-danger-text: #a94442 !default; +$state-danger-bg: #f2dede !default; +$state-danger-border: darken($state-danger-bg, 5%) !default; + + +// Cards + +$card-spacer-x: 1.25rem !default; +$card-spacer-y: .75rem !default; +$card-border-width: 1px !default; +$card-border-radius: $border-radius !default; +$card-border-color: rgba($black,.125) !default; +$card-border-radius-inner: calc(#{$card-border-radius} - #{$card-border-width}) !default; +$card-cap-bg: $gray-lightest !default; +$card-bg: $white !default; + +$card-link-hover-color: $white !default; + +$card-img-overlay-padding: 1.25rem !default; + +$card-deck-margin: ($grid-gutter-width-base / 2) !default; + +$card-columns-count: 3 !default; +$card-columns-gap: 1.25rem !default; +$card-columns-margin: $card-spacer-y !default; + + +// Tooltips + +$tooltip-max-width: 200px !default; +$tooltip-color: $white !default; +$tooltip-bg: $black !default; +$tooltip-opacity: .9 !default; +$tooltip-padding-y: 3px !default; +$tooltip-padding-x: 8px !default; +$tooltip-margin: 3px !default; + +$tooltip-arrow-width: 5px !default; +$tooltip-arrow-color: $tooltip-bg !default; + + +// Popovers + +$popover-inner-padding: 1px !default; +$popover-bg: $white !default; +$popover-max-width: 276px !default; +$popover-border-width: $border-width !default; +$popover-border-color: rgba($black,.2) !default; +$popover-box-shadow: 0 5px 10px rgba($black,.2) !default; + +$popover-title-bg: darken($popover-bg, 3%) !default; +$popover-title-padding-x: 14px !default; +$popover-title-padding-y: 8px !default; + +$popover-content-padding-x: 14px !default; +$popover-content-padding-y: 9px !default; + +$popover-arrow-width: 10px !default; +$popover-arrow-color: $popover-bg !default; + +$popover-arrow-outer-width: ($popover-arrow-width + 1px) !default; +$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default; + + +// Badges + +$badge-default-bg: $gray-light !default; +$badge-primary-bg: $brand-primary !default; +$badge-success-bg: $brand-success !default; +$badge-info-bg: $brand-info !default; +$badge-warning-bg: $brand-warning !default; +$badge-danger-bg: $brand-danger !default; + +$badge-color: $white !default; +$badge-link-hover-color: $white !default; +$badge-font-size: 75% !default; +$badge-font-weight: $font-weight-bold !default; +$badge-padding-x: .4em !default; +$badge-padding-y: .25em !default; + +$badge-pill-padding-x: .6em !default; +// Use a higher than normal value to ensure completely rounded edges when +// customizing padding or font-size on labels. +$badge-pill-border-radius: 10rem !default; + + +// Modals + +// Padding applied to the modal body +$modal-inner-padding: 15px !default; + +$modal-dialog-margin: 10px !default; +$modal-dialog-sm-up-margin-y: 30px !default; + +$modal-title-line-height: $line-height-base !default; + +$modal-content-bg: $white !default; +$modal-content-border-color: rgba($black,.2) !default; +$modal-content-border-width: $border-width !default; +$modal-content-xs-box-shadow: 0 3px 9px rgba($black,.5) !default; +$modal-content-sm-up-box-shadow: 0 5px 15px rgba($black,.5) !default; + +$modal-backdrop-bg: $black !default; +$modal-backdrop-opacity: .5 !default; +$modal-header-border-color: $gray-lighter !default; +$modal-footer-border-color: $modal-header-border-color !default; +$modal-header-border-width: $modal-content-border-width !default; +$modal-footer-border-width: $modal-header-border-width !default; +$modal-header-padding: 15px !default; + +$modal-lg: 800px !default; +$modal-md: 500px !default; +$modal-sm: 300px !default; + +$modal-transition: transform .3s ease-out !default; + + +// Alerts +// +// Define alert colors, border radius, and padding. + +$alert-padding-x: 1.25rem !default; +$alert-padding-y: .75rem !default; +$alert-margin-bottom: 1rem !default; +$alert-border-radius: $border-radius !default; +$alert-link-font-weight: $font-weight-bold !default; +$alert-border-width: $border-width !default; + +$alert-success-bg: $state-success-bg !default; +$alert-success-text: $state-success-text !default; +$alert-success-border: $state-success-border !default; + +$alert-info-bg: $state-info-bg !default; +$alert-info-text: $state-info-text !default; +$alert-info-border: $state-info-border !default; + +$alert-warning-bg: $state-warning-bg !default; +$alert-warning-text: $state-warning-text !default; +$alert-warning-border: $state-warning-border !default; + +$alert-danger-bg: $state-danger-bg !default; +$alert-danger-text: $state-danger-text !default; +$alert-danger-border: $state-danger-border !default; + + +// Progress bars + +$progress-height: 1rem !default; +$progress-font-size: .75rem !default; +$progress-bg: $gray-lighter !default; +$progress-border-radius: $border-radius !default; +$progress-box-shadow: inset 0 .1rem .1rem rgba($black,.1) !default; +$progress-bar-color: $white !default; +$progress-bar-bg: $brand-primary !default; +$progress-bar-animation-timing: 1s linear infinite !default; + +// List group + +$list-group-color: $body-color !default; +$list-group-bg: $white !default; +$list-group-border-color: rgba($black,.125) !default; +$list-group-border-width: $border-width !default; +$list-group-border-radius: $border-radius !default; + +$list-group-item-padding-x: 1.25rem !default; +$list-group-item-padding-y: .75rem !default; + +$list-group-hover-bg: $gray-lightest !default; +$list-group-active-color: $component-active-color !default; +$list-group-active-bg: $component-active-bg !default; +$list-group-active-border: $list-group-active-bg !default; + +$list-group-disabled-color: $gray-light !default; +$list-group-disabled-bg: $list-group-bg !default; + +$list-group-link-color: $gray !default; +$list-group-link-hover-color: $list-group-link-color !default; + +$list-group-link-active-color: $list-group-color !default; +$list-group-link-active-bg: $gray-lighter !default; + + +// Image thumbnails + +$thumbnail-padding: .25rem !default; +$thumbnail-bg: $body-bg !default; +$thumbnail-border-width: $border-width !default; +$thumbnail-border-color: #ddd !default; +$thumbnail-border-radius: $border-radius !default; +$thumbnail-box-shadow: 0 1px 2px rgba($black,.075) !default; +$thumbnail-transition: all .2s ease-in-out !default; + + +// Figures + +$figure-caption-font-size: 90% !default; +$figure-caption-color: $gray-light !default; + + +// Breadcrumbs + +$breadcrumb-padding-y: .75rem !default; +$breadcrumb-padding-x: 1rem !default; +$breadcrumb-item-padding: .5rem !default; + +$breadcrumb-bg: $gray-lighter !default; +$breadcrumb-divider-color: $gray-light !default; +$breadcrumb-active-color: $gray-light !default; +$breadcrumb-divider: "/" !default; + + +// Carousel + +$carousel-control-color: $white !default; +$carousel-control-width: 15% !default; +$carousel-control-opacity: .5 !default; + +$carousel-indicator-width: 30px !default; +$carousel-indicator-height: 3px !default; +$carousel-indicator-spacer: 3px !default; +$carousel-indicator-active-bg: $white !default; + +$carousel-caption-width: 70% !default; +$carousel-caption-color: $white !default; + +$carousel-control-icon-width: 20px !default; + +$carousel-control-prev-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M4 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E"), "#", "%23") !default; +$carousel-control-next-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M1.5 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E"), "#", "%23") !default; + +$carousel-transition: transform .6s ease-in-out !default; + + +// Close + +$close-font-size: $font-size-base * 1.5 !default; +$close-font-weight: $font-weight-bold !default; +$close-color: $black !default; +$close-text-shadow: 0 1px 0 $white !default; + +// Code + +$code-font-size: 90% !default; +$code-padding-x: .4rem !default; +$code-padding-y: .2rem !default; +$code-color: #bd4147 !default; +$code-bg: $gray-lightest !default; + +$kbd-color: $white !default; +$kbd-bg: $gray-dark !default; + +$pre-color: $gray-dark !default; +$pre-scrollable-max-height: 340px !default; diff --git a/templates/assets/bootstrap/scss/bootstrap-grid.scss b/templates/assets/bootstrap/scss/bootstrap-grid.scss new file mode 100644 index 0000000..2ba6858 --- /dev/null +++ b/templates/assets/bootstrap/scss/bootstrap-grid.scss @@ -0,0 +1,37 @@ +// Bootstrap Grid only +// +// Includes relevant variables and mixins for the flexbox grid +// system, as well as the generated predefined classes (e.g., `.col-sm-4`). + +// +// Box sizing, responsive, and more +// + +@at-root { + @-ms-viewport { width: device-width; } +} + +html { + box-sizing: border-box; + -ms-overflow-style: scrollbar; +} + +*, +*::before, +*::after { + box-sizing: inherit; +} + +@import "custom"; +@import "variables"; + +// +// Grid mixins +// + +@import "mixins/breakpoints"; +@import "mixins/grid-framework"; +@import "mixins/grid"; + +@import "grid"; +@import "utilities/flex"; diff --git a/templates/assets/bootstrap/scss/bootstrap-reboot.scss b/templates/assets/bootstrap/scss/bootstrap-reboot.scss new file mode 100644 index 0000000..5867f08 --- /dev/null +++ b/templates/assets/bootstrap/scss/bootstrap-reboot.scss @@ -0,0 +1,9 @@ +// Bootstrap Reboot only +// +// Includes only Normalize and our custom Reboot reset. + +@import "custom"; +@import "variables"; +@import "mixins"; + +@import "reboot"; diff --git a/templates/assets/bootstrap/scss/bootstrap.scss b/templates/assets/bootstrap/scss/bootstrap.scss new file mode 100644 index 0000000..f7577f5 --- /dev/null +++ b/templates/assets/bootstrap/scss/bootstrap.scss @@ -0,0 +1,52 @@ +/*! + * Bootstrap v4.0.0-alpha.6 (https://getbootstrap.com) + * Copyright 2011-2017 The Bootstrap Authors + * Copyright 2011-2017 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +// Core variables and mixins +@import "custom"; +@import "variables"; +@import "mixins"; + +@import "print"; + +// Core CSS +@import "reboot"; +@import "type"; +@import "images"; +@import "code"; +@import "grid"; +@import "tables"; +@import "forms"; +@import "buttons"; + +// Components +@import "transitions"; +@import "dropdown"; +@import "button-group"; +@import "input-group"; +@import "custom-forms"; +@import "nav"; +@import "navbar"; +@import "card"; +@import "breadcrumb"; +@import "pagination"; +@import "badge"; +@import "jumbotron"; +@import "alert"; +@import "progress"; +@import "media"; +@import "list-group"; +@import "responsive-embed"; +@import "close"; + +// Components w/ JavaScript +@import "modal"; +@import "tooltip"; +@import "popover"; +@import "carousel"; + +// Utility classes +@import "utilities"; diff --git a/templates/assets/bootstrap/scss/mixins/_alert.scss b/templates/assets/bootstrap/scss/mixins/_alert.scss new file mode 100644 index 0000000..1e9307e --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_alert.scss @@ -0,0 +1,14 @@ +// Alerts + +@mixin alert-variant($background, $border, $body-color) { + color: $body-color; + background-color: $background; + border-color: $border; + + hr { + border-top-color: darken($border, 5%); + } + .alert-link { + color: darken($body-color, 10%); + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_background-variant.scss b/templates/assets/bootstrap/scss/mixins/_background-variant.scss new file mode 100644 index 0000000..54a734d --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_background-variant.scss @@ -0,0 +1,12 @@ +// Contextual backgrounds + +@mixin bg-variant($parent, $color) { + #{$parent} { + background-color: $color !important; + } + a#{$parent} { + @include hover-focus { + background-color: darken($color, 10%) !important; + } + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_badge.scss b/templates/assets/bootstrap/scss/mixins/_badge.scss new file mode 100644 index 0000000..9fa44b6 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_badge.scss @@ -0,0 +1,11 @@ +// Badges + +@mixin badge-variant($color) { + background-color: $color; + + &[href] { + @include hover-focus { + background-color: darken($color, 10%); + } + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_border-radius.scss b/templates/assets/bootstrap/scss/mixins/_border-radius.scss new file mode 100644 index 0000000..2024feb --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_border-radius.scss @@ -0,0 +1,35 @@ +// Single side border-radius + +@mixin border-radius($radius: $border-radius) { + @if $enable-rounded { + border-radius: $radius; + } +} + +@mixin border-top-radius($radius) { + @if $enable-rounded { + border-top-left-radius: $radius; + border-top-right-radius: $radius; + } +} + +@mixin border-right-radius($radius) { + @if $enable-rounded { + border-top-right-radius: $radius; + border-bottom-right-radius: $radius; + } +} + +@mixin border-bottom-radius($radius) { + @if $enable-rounded { + border-bottom-right-radius: $radius; + border-bottom-left-radius: $radius; + } +} + +@mixin border-left-radius($radius) { + @if $enable-rounded { + border-top-left-radius: $radius; + border-bottom-left-radius: $radius; + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_box-shadow.scss b/templates/assets/bootstrap/scss/mixins/_box-shadow.scss new file mode 100644 index 0000000..b2410e5 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_box-shadow.scss @@ -0,0 +1,5 @@ +@mixin box-shadow($shadow...) { + @if $enable-shadows { + box-shadow: $shadow; + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_breakpoints.scss b/templates/assets/bootstrap/scss/mixins/_breakpoints.scss new file mode 100644 index 0000000..904b60f --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_breakpoints.scss @@ -0,0 +1,95 @@ +// Breakpoint viewport sizes and media queries. +// +// Breakpoints are defined as a map of (name: minimum width), order from small to large: +// +// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px) +// +// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default. + +// Name of the next breakpoint, or null for the last breakpoint. +// +// >> breakpoint-next(sm) +// md +// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) +// md +// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl)) +// md +@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) { + $n: index($breakpoint-names, $name); + @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null); +} + +// Minimum breakpoint width. Null for the smallest (first) breakpoint. +// +// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) +// 576px +@function breakpoint-min($name, $breakpoints: $grid-breakpoints) { + $min: map-get($breakpoints, $name); + @return if($min != 0, $min, null); +} + +// Maximum breakpoint width. Null for the largest (last) breakpoint. +// The maximum value is calculated as the minimum of the next one less 0.1. +// +// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) +// 767px +@function breakpoint-max($name, $breakpoints: $grid-breakpoints) { + $next: breakpoint-next($name, $breakpoints); + @return if($next, breakpoint-min($next, $breakpoints) - 1px, null); +} + +// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront. +// Useful for making responsive utilities. +// +// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) +// "" (Returns a blank string) +// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) +// "-sm" +@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) { + @return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}"); +} + +// Media of at least the minimum breakpoint width. No query for the smallest breakpoint. +// Makes the @content apply to the given breakpoint and wider. +@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) { + $min: breakpoint-min($name, $breakpoints); + @if $min { + @media (min-width: $min) { + @content; + } + } @else { + @content; + } +} + +// Media of at most the maximum breakpoint width. No query for the largest breakpoint. +// Makes the @content apply to the given breakpoint and narrower. +@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) { + $max: breakpoint-max($name, $breakpoints); + @if $max { + @media (max-width: $max) { + @content; + } + } @else { + @content; + } +} + +// Media that spans multiple breakpoint widths. +// Makes the @content apply between the min and max breakpoints +@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) { + @include media-breakpoint-up($lower, $breakpoints) { + @include media-breakpoint-down($upper, $breakpoints) { + @content; + } + } +} + +// Media between the breakpoint's minimum and maximum widths. +// No minimum for the smallest breakpoint, and no maximum for the largest one. +// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower. +@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) { + @include media-breakpoint-between($name, $name, $breakpoints) { + @content; + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_buttons.scss b/templates/assets/bootstrap/scss/mixins/_buttons.scss new file mode 100644 index 0000000..91eb444 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_buttons.scss @@ -0,0 +1,86 @@ +// Button variants +// +// Easily pump out default styles, as well as :hover, :focus, :active, +// and disabled options for all buttons + +@mixin button-variant($color, $background, $border) { + $active-background: darken($background, 10%); + $active-border: darken($border, 12%); + + color: $color; + background-color: $background; + border-color: $border; + @include box-shadow($btn-box-shadow); + + // Hover and focus styles are shared + @include hover { + color: $color; + background-color: $active-background; + border-color: $active-border; + } + &:focus, + &.focus { + // Avoid using mixin so we can pass custom focus shadow properly + @if $enable-shadows { + box-shadow: $btn-box-shadow, 0 0 0 2px rgba($border, .5); + } @else { + box-shadow: 0 0 0 2px rgba($border, .5); + } + } + + // Disabled comes first so active can properly restyle + &.disabled, + &:disabled { + background-color: $background; + border-color: $border; + } + + &:active, + &.active, + .show > &.dropdown-toggle { + color: $color; + background-color: $active-background; + background-image: none; // Remove the gradient for the pressed/active state + border-color: $active-border; + @include box-shadow($btn-active-box-shadow); + } +} + +@mixin button-outline-variant($color, $color-hover: #fff) { + color: $color; + background-color: transparent; + background-image: none; + border-color: $color; + + @include hover { + color: $color-hover; + background-color: $color; + border-color: $color; + } + + &:focus, + &.focus { + box-shadow: 0 0 0 2px rgba($color, .5); + } + + &.disabled, + &:disabled { + color: $color; + background-color: transparent; + } + + &:active, + &.active, + .show > &.dropdown-toggle { + color: $color-hover; + background-color: $color; + border-color: $color; + } +} + +// Button sizes +@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) { + padding: $padding-y $padding-x; + font-size: $font-size; + @include border-radius($border-radius); +} diff --git a/templates/assets/bootstrap/scss/mixins/_cards.scss b/templates/assets/bootstrap/scss/mixins/_cards.scss new file mode 100644 index 0000000..4b1232d --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_cards.scss @@ -0,0 +1,47 @@ +// Card variants + +@mixin card-variant($background, $border) { + background-color: $background; + border-color: $border; + + .card-header, + .card-footer { + background-color: transparent; + } +} + +@mixin card-outline-variant($color) { + background-color: transparent; + border-color: $color; +} + +// +// Inverse text within a card for use with dark backgrounds +// + +@mixin card-inverse { + color: rgba(255,255,255,.65); + + .card-header, + .card-footer { + background-color: transparent; + border-color: rgba(255,255,255,.2); + } + .card-header, + .card-footer, + .card-title, + .card-blockquote { + color: #fff; + } + .card-link, + .card-text, + .card-subtitle, + .card-blockquote .blockquote-footer { + color: rgba(255,255,255,.65); + } + .card-link { + @include hover-focus { + color: $card-link-hover-color; + } + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_clearfix.scss b/templates/assets/bootstrap/scss/mixins/_clearfix.scss new file mode 100644 index 0000000..11a977b --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_clearfix.scss @@ -0,0 +1,7 @@ +@mixin clearfix() { + &::after { + display: block; + clear: both; + content: ""; + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_float.scss b/templates/assets/bootstrap/scss/mixins/_float.scss new file mode 100644 index 0000000..b43116f --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_float.scss @@ -0,0 +1,9 @@ +@mixin float-left { + float: left !important; +} +@mixin float-right { + float: right !important; +} +@mixin float-none { + float: none !important; +} diff --git a/templates/assets/bootstrap/scss/mixins/_forms.scss b/templates/assets/bootstrap/scss/mixins/_forms.scss new file mode 100644 index 0000000..33b186a --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_forms.scss @@ -0,0 +1,55 @@ +// Form validation states +// +// Used in _forms.scss to generate the form validation CSS for warnings, errors, +// and successes. + +@mixin form-control-validation($color) { + // Color the label and help text + .form-control-feedback, + .form-control-label, + .col-form-label, + .form-check-label, + .custom-control { + color: $color; + } + + // Set the border and box shadow on specific inputs to match + .form-control, + .custom-select, + .custom-file-control { + border-color: $color; + + &:focus { + @include box-shadow($input-box-shadow, 0 0 6px lighten($color, 20%)); + } + } + + // Set validation states also for addons + .input-group-addon { + color: $color; + background-color: lighten($color, 40%); + border-color: $color; + } +} + +// Form control focus state +// +// Generate a customized focus state and for any input with the specified color, +// which defaults to the `@input-border-focus` variable. +// +// We highly encourage you to not customize the default value, but instead use +// this to tweak colors on an as-needed basis. This aesthetic change is based on +// WebKit's default styles, but applicable to a wider range of browsers. Its +// usability and accessibility should be taken into account with any change. +// +// Example usage: change the default blue border and shadow to white for better +// contrast against a dark gray background. +@mixin form-control-focus() { + &:focus { + color: $input-color-focus; + background-color: $input-bg-focus; + border-color: $input-border-focus; + outline: none; + @include box-shadow($input-box-shadow-focus); + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_gradients.scss b/templates/assets/bootstrap/scss/mixins/_gradients.scss new file mode 100644 index 0000000..bad79f9 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_gradients.scss @@ -0,0 +1,37 @@ +// Gradients + +// Horizontal gradient, from left to right +// +// Creates two color stops, start and end, by specifying a color and position for each color stop. +@mixin gradient-x($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) { + background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); + background-repeat: repeat-x; +} + +// Vertical gradient, from top to bottom +// +// Creates two color stops, start and end, by specifying a color and position for each color stop. +@mixin gradient-y($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) { + background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); + background-repeat: repeat-x; +} + +@mixin gradient-directional($start-color: #555, $end-color: #333, $deg: 45deg) { + background-image: linear-gradient($deg, $start-color, $end-color); + background-repeat: repeat-x; +} +@mixin gradient-x-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) { + background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color); + background-repeat: no-repeat; +} +@mixin gradient-y-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) { + background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color); + background-repeat: no-repeat; +} +@mixin gradient-radial($inner-color: #555, $outer-color: #333) { + background-image: radial-gradient(circle, $inner-color, $outer-color); + background-repeat: no-repeat; +} +@mixin gradient-striped($color: rgba(255,255,255,.15), $angle: 45deg) { + background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent); +} diff --git a/templates/assets/bootstrap/scss/mixins/_grid-framework.scss b/templates/assets/bootstrap/scss/mixins/_grid-framework.scss new file mode 100644 index 0000000..0aa814a --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_grid-framework.scss @@ -0,0 +1,65 @@ +// Framework grid generation +// +// Used only by Bootstrap to generate the correct number of grid classes given +// any value of `$grid-columns`. + +@mixin make-grid-columns($columns: $grid-columns, $gutters: $grid-gutter-widths, $breakpoints: $grid-breakpoints) { + // Common properties for all breakpoints + %grid-column { + position: relative; + width: 100%; + min-height: 1px; // Prevent columns from collapsing when empty + + @include make-gutters($gutters); + } + + @each $breakpoint in map-keys($breakpoints) { + $infix: breakpoint-infix($breakpoint, $breakpoints); + + // Allow columns to stretch full width below their breakpoints + @for $i from 1 through $columns { + .col#{$infix}-#{$i} { + @extend %grid-column; + } + } + .col#{$infix} { + @extend %grid-column; + } + + @include media-breakpoint-up($breakpoint, $breakpoints) { + // Provide basic `.col-{bp}` classes for equal-width flexbox columns + .col#{$infix} { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; + } + .col#{$infix}-auto { + flex: 0 0 auto; + width: auto; + } + + @for $i from 1 through $columns { + .col#{$infix}-#{$i} { + @include make-col($i, $columns); + } + } + + @each $modifier in (pull, push) { + @for $i from 0 through $columns { + .#{$modifier}#{$infix}-#{$i} { + @include make-col-modifier($modifier, $i, $columns) + } + } + } + + // `$columns - 1` because offsetting by the width of an entire row isn't possible + @for $i from 0 through ($columns - 1) { + @if not ($infix == "" and $i == 0) { // Avoid emitting useless .offset-xs-0 + .offset#{$infix}-#{$i} { + @include make-col-modifier(offset, $i, $columns) + } + } + } + } + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_grid.scss b/templates/assets/bootstrap/scss/mixins/_grid.scss new file mode 100644 index 0000000..eb6c012 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_grid.scss @@ -0,0 +1,100 @@ +/// Grid system +// +// Generate semantic grid columns with these mixins. + +@mixin make-container($gutters: $grid-gutter-widths) { + position: relative; + margin-right: auto; + margin-left: auto; + + @each $breakpoint in map-keys($gutters) { + @include media-breakpoint-up($breakpoint) { + $gutter: map-get($gutters, $breakpoint); + padding-right: ($gutter / 2); + padding-left: ($gutter / 2); + } + } +} + + +// For each breakpoint, define the maximum width of the container in a media query +@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) { + @each $breakpoint, $container-max-width in $max-widths { + @include media-breakpoint-up($breakpoint, $breakpoints) { + width: $container-max-width; + max-width: 100%; + } + } +} + +@mixin make-gutters($gutters: $grid-gutter-widths) { + @each $breakpoint in map-keys($gutters) { + @include media-breakpoint-up($breakpoint) { + $gutter: map-get($gutters, $breakpoint); + padding-right: ($gutter / 2); + padding-left: ($gutter / 2); + } + } +} + +@mixin make-row($gutters: $grid-gutter-widths) { + display: flex; + flex-wrap: wrap; + + @each $breakpoint in map-keys($gutters) { + @include media-breakpoint-up($breakpoint) { + $gutter: map-get($gutters, $breakpoint); + margin-right: ($gutter / -2); + margin-left: ($gutter / -2); + } + } +} + +@mixin make-col-ready($gutters: $grid-gutter-widths) { + position: relative; + // Prevent columns from becoming too narrow when at smaller grid tiers by + // always setting `width: 100%;`. This works because we use `flex` values + // later on to override this initial width. + width: 100%; + min-height: 1px; // Prevent collapsing + + @each $breakpoint in map-keys($gutters) { + @include media-breakpoint-up($breakpoint) { + $gutter: map-get($gutters, $breakpoint); + padding-right: ($gutter / 2); + padding-left: ($gutter / 2); + } + } +} + +@mixin make-col($size, $columns: $grid-columns) { + flex: 0 0 percentage($size / $columns); + // width: percentage($size / $columns); + // Add a `max-width` to ensure content within each column does not blow out + // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari + // do not appear to require this. + max-width: percentage($size / $columns); +} + +@mixin make-col-offset($size, $columns: $grid-columns) { + margin-left: percentage($size / $columns); +} + +@mixin make-col-push($size, $columns: $grid-columns) { + left: if($size > 0, percentage($size / $columns), auto); +} + +@mixin make-col-pull($size, $columns: $grid-columns) { + right: if($size > 0, percentage($size / $columns), auto); +} + +@mixin make-col-modifier($type, $size, $columns) { + // Work around the lack of dynamic mixin @include support (https://github.com/sass/sass/issues/626) + @if $type == push { + @include make-col-push($size, $columns); + } @else if $type == pull { + @include make-col-pull($size, $columns); + } @else if $type == offset { + @include make-col-offset($size, $columns); + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_hover.scss b/templates/assets/bootstrap/scss/mixins/_hover.scss new file mode 100644 index 0000000..4aa4b1d --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_hover.scss @@ -0,0 +1,60 @@ +@mixin hover { + // TODO: re-enable along with mq4-hover-shim +// @if $enable-hover-media-query { +// // See Media Queries Level 4: https://drafts.csswg.org/mediaqueries/#hover +// // Currently shimmed by https://github.com/twbs/mq4-hover-shim +// @media (hover: hover) { +// &:hover { @content } +// } +// } +// @else { +// scss-lint:disable Indentation + &:hover { @content } +// scss-lint:enable Indentation +// } +} + + +@mixin hover-focus { + @if $enable-hover-media-query { + &:focus { @content } + @include hover { @content } + } @else { + &:focus, + &:hover { + @content + } + } +} + +@mixin plain-hover-focus { + @if $enable-hover-media-query { + &, + &:focus { + @content + } + @include hover { @content } + } @else { + &, + &:focus, + &:hover { + @content + } + } +} + +@mixin hover-focus-active { + @if $enable-hover-media-query { + &:focus, + &:active { + @content + } + @include hover { @content } + } @else { + &:focus, + &:active, + &:hover { + @content + } + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_image.scss b/templates/assets/bootstrap/scss/mixins/_image.scss new file mode 100644 index 0000000..c2b45f2 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_image.scss @@ -0,0 +1,36 @@ +// Image Mixins +// - Responsive image +// - Retina image + + +// Responsive image +// +// Keep images from scaling beyond the width of their parents. + +@mixin img-fluid { + // Part 1: Set a maximum relative to the parent + max-width: 100%; + // Part 2: Override the height to auto, otherwise images will be stretched + // when setting a width and height attribute on the img element. + height: auto; +} + + +// Retina image +// +// Short retina mixin for setting background-image and -size. + +@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) { + background-image: url($file-1x); + + // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio, + // but doesn't convert dppx=>dpi. + // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard. + // Compatibility info: http://caniuse.com/#feat=css-media-resolution + @media + only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx + only screen and (min-resolution: 2dppx) { // Standardized + background-image: url($file-2x); + background-size: $width-1x $height-1x; + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_list-group.scss b/templates/assets/bootstrap/scss/mixins/_list-group.scss new file mode 100644 index 0000000..ba27b50 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_list-group.scss @@ -0,0 +1,26 @@ +// List Groups + +@mixin list-group-item-variant($state, $background, $color) { + .list-group-item-#{$state} { + color: $color; + background-color: $background; + } + + //scss-lint:disable QualifyingElement + a.list-group-item-#{$state}, + button.list-group-item-#{$state} { + color: $color; + + @include hover-focus { + color: $color; + background-color: darken($background, 5%); + } + + &.active { + color: #fff; + background-color: $color; + border-color: $color; + } + } + // scss-lint:enable QualifyingElement +} diff --git a/templates/assets/bootstrap/scss/mixins/_lists.scss b/templates/assets/bootstrap/scss/mixins/_lists.scss new file mode 100644 index 0000000..2518562 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_lists.scss @@ -0,0 +1,7 @@ +// Lists + +// Unstyled keeps list items block level, just removes default browser padding and list-style +@mixin list-unstyled { + padding-left: 0; + list-style: none; +} diff --git a/templates/assets/bootstrap/scss/mixins/_nav-divider.scss b/templates/assets/bootstrap/scss/mixins/_nav-divider.scss new file mode 100644 index 0000000..557673c --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_nav-divider.scss @@ -0,0 +1,10 @@ +// Horizontal dividers +// +// Dividers (basically an hr) within dropdowns and nav lists + +@mixin nav-divider($color: #e5e5e5) { + height: 1px; + margin: ($spacer / 2) 0; + overflow: hidden; + background-color: $color; +} diff --git a/templates/assets/bootstrap/scss/mixins/_navbar-align.scss b/templates/assets/bootstrap/scss/mixins/_navbar-align.scss new file mode 100644 index 0000000..c454a4f --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_navbar-align.scss @@ -0,0 +1,9 @@ +// Navbar vertical align +// +// Vertically center elements in the navbar. +// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin. + +// @mixin navbar-vertical-align($element-height) { +// margin-top: (($navbar-height - $element-height) / 2); +// margin-bottom: (($navbar-height - $element-height) / 2); +// } diff --git a/templates/assets/bootstrap/scss/mixins/_pagination.scss b/templates/assets/bootstrap/scss/mixins/_pagination.scss new file mode 100644 index 0000000..8cd9317 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_pagination.scss @@ -0,0 +1,21 @@ +// Pagination + +@mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) { + .page-link { + padding: $padding-y $padding-x; + font-size: $font-size; + } + + .page-item { + &:first-child { + .page-link { + @include border-left-radius($border-radius); + } + } + &:last-child { + .page-link { + @include border-right-radius($border-radius); + } + } + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_reset-text.scss b/templates/assets/bootstrap/scss/mixins/_reset-text.scss new file mode 100644 index 0000000..4cf9e79 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_reset-text.scss @@ -0,0 +1,18 @@ +// scss-lint:disable DuplicateProperty +@mixin reset-text { + font-family: $font-family-base; + // We deliberately do NOT reset font-size or word-wrap. + font-style: normal; + font-weight: $font-weight-normal; + line-height: $line-height-base; + text-align: left; // Fallback for where `start` is not supported + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; +} diff --git a/templates/assets/bootstrap/scss/mixins/_resize.scss b/templates/assets/bootstrap/scss/mixins/_resize.scss new file mode 100644 index 0000000..66f233a --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_resize.scss @@ -0,0 +1,6 @@ +// Resize anything + +@mixin resizable($direction) { + overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible` + resize: $direction; // Options: horizontal, vertical, both +} diff --git a/templates/assets/bootstrap/scss/mixins/_screen-reader.scss b/templates/assets/bootstrap/scss/mixins/_screen-reader.scss new file mode 100644 index 0000000..a5fa51c --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_screen-reader.scss @@ -0,0 +1,35 @@ +// Only display content to screen readers +// +// See: http://a11yproject.com/posts/how-to-hide-content +// See: http://hugogiraudel.com/2016/10/13/css-hide-and-seek/ + +@mixin sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + overflow: hidden; + clip: rect(0,0,0,0); + white-space: nowrap; + clip-path: inset(50%); + border: 0; +} + +// Use in conjunction with .sr-only to only display content when it's focused. +// +// Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 +// +// Credit: HTML5 Boilerplate + +@mixin sr-only-focusable { + &:active, + &:focus { + position: static; + width: auto; + height: auto; + overflow: visible; + clip: auto; + white-space: normal; + clip-path: none; + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_size.scss b/templates/assets/bootstrap/scss/mixins/_size.scss new file mode 100644 index 0000000..b9dd48e --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_size.scss @@ -0,0 +1,6 @@ +// Sizing shortcuts + +@mixin size($width, $height: $width) { + width: $width; + height: $height; +} diff --git a/templates/assets/bootstrap/scss/mixins/_table-row.scss b/templates/assets/bootstrap/scss/mixins/_table-row.scss new file mode 100644 index 0000000..84f1d30 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_table-row.scss @@ -0,0 +1,30 @@ +// Tables + +@mixin table-row-variant($state, $background) { + // Exact selectors below required to override `.table-striped` and prevent + // inheritance to nested tables. + .table-#{$state} { + &, + > th, + > td { + background-color: $background; + } + } + + // Hover states for `.table-hover` + // Note: this is not available for cells or rows within `thead` or `tfoot`. + .table-hover { + $hover-background: darken($background, 5%); + + .table-#{$state} { + @include hover { + background-color: $hover-background; + + > td, + > th { + background-color: $hover-background; + } + } + } + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_text-emphasis.scss b/templates/assets/bootstrap/scss/mixins/_text-emphasis.scss new file mode 100644 index 0000000..9cd4b6a --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_text-emphasis.scss @@ -0,0 +1,12 @@ +// Typography + +@mixin text-emphasis-variant($parent, $color) { + #{$parent} { + color: $color !important; + } + a#{$parent} { + @include hover-focus { + color: darken($color, 10%) !important; + } + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_text-hide.scss b/templates/assets/bootstrap/scss/mixins/_text-hide.scss new file mode 100644 index 0000000..52a38a9 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_text-hide.scss @@ -0,0 +1,8 @@ +// CSS image replacement +@mixin text-hide() { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} diff --git a/templates/assets/bootstrap/scss/mixins/_text-truncate.scss b/templates/assets/bootstrap/scss/mixins/_text-truncate.scss new file mode 100644 index 0000000..3504bb1 --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_text-truncate.scss @@ -0,0 +1,8 @@ +// Text truncate +// Requires inline-block or block for proper styling + +@mixin text-truncate() { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} diff --git a/templates/assets/bootstrap/scss/mixins/_transforms.scss b/templates/assets/bootstrap/scss/mixins/_transforms.scss new file mode 100644 index 0000000..4005c9d --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_transforms.scss @@ -0,0 +1,14 @@ +// Applies the given styles only when the browser support CSS3 3D transforms. +@mixin if-supports-3d-transforms() { + @media (-webkit-transform-3d) { + // Old Safari, Old Android + // http://caniuse.com/#feat=css-featurequeries + // https://developer.mozilla.org/en-US/docs/Web/CSS/@media/-webkit-transform-3d + @content; + } + + @supports (transform: translate3d(0,0,0)) { + // The Proper Way: Using a CSS feature query + @content; + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_transition.scss b/templates/assets/bootstrap/scss/mixins/_transition.scss new file mode 100644 index 0000000..7e33dee --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_transition.scss @@ -0,0 +1,9 @@ +@mixin transition($transition...) { + @if $enable-transitions { + @if length($transition) == 0 { + transition: $transition-base; + } @else { + transition: $transition; + } + } +} diff --git a/templates/assets/bootstrap/scss/mixins/_visibility.scss b/templates/assets/bootstrap/scss/mixins/_visibility.scss new file mode 100644 index 0000000..f67fc1c --- /dev/null +++ b/templates/assets/bootstrap/scss/mixins/_visibility.scss @@ -0,0 +1,5 @@ +// Visibility + +@mixin invisible($visibility) { + visibility: $visibility !important; +} diff --git a/templates/assets/bootstrap/scss/utilities/_align.scss b/templates/assets/bootstrap/scss/utilities/_align.scss new file mode 100644 index 0000000..4dbbbc2 --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_align.scss @@ -0,0 +1,6 @@ +.align-baseline { vertical-align: baseline !important; } // Browser default +.align-top { vertical-align: top !important; } +.align-middle { vertical-align: middle !important; } +.align-bottom { vertical-align: bottom !important; } +.align-text-bottom { vertical-align: text-bottom !important; } +.align-text-top { vertical-align: text-top !important; } diff --git a/templates/assets/bootstrap/scss/utilities/_background.scss b/templates/assets/bootstrap/scss/utilities/_background.scss new file mode 100644 index 0000000..b9ac295 --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_background.scss @@ -0,0 +1,19 @@ +// +// Contextual backgrounds +// + +.bg-faded { + background-color: darken($body-bg, 3%); +} + +@include bg-variant('.bg-primary', $brand-primary); + +@include bg-variant('.bg-success', $brand-success); + +@include bg-variant('.bg-info', $brand-info); + +@include bg-variant('.bg-warning', $brand-warning); + +@include bg-variant('.bg-danger', $brand-danger); + +@include bg-variant('.bg-inverse', $brand-inverse); diff --git a/templates/assets/bootstrap/scss/utilities/_borders.scss b/templates/assets/bootstrap/scss/utilities/_borders.scss new file mode 100644 index 0000000..b256881 --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_borders.scss @@ -0,0 +1,37 @@ +// +// Border +// + +.border-0 { border: 0 !important; } +.border-top-0 { border-top: 0 !important; } +.border-right-0 { border-right: 0 !important; } +.border-bottom-0 { border-bottom: 0 !important; } +.border-left-0 { border-left: 0 !important; } + +// +// Border-radius +// + +.rounded { + @include border-radius($border-radius); +} +.rounded-top { + @include border-top-radius($border-radius); +} +.rounded-right { + @include border-right-radius($border-radius); +} +.rounded-bottom { + @include border-bottom-radius($border-radius); +} +.rounded-left { + @include border-left-radius($border-radius); +} + +.rounded-circle { + border-radius: 50%; +} + +.rounded-0 { + border-radius: 0; +} diff --git a/templates/assets/bootstrap/scss/utilities/_clearfix.scss b/templates/assets/bootstrap/scss/utilities/_clearfix.scss new file mode 100644 index 0000000..e92522a --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_clearfix.scss @@ -0,0 +1,3 @@ +.clearfix { + @include clearfix(); +} diff --git a/templates/assets/bootstrap/scss/utilities/_display.scss b/templates/assets/bootstrap/scss/utilities/_display.scss new file mode 100644 index 0000000..4535362 --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_display.scss @@ -0,0 +1,53 @@ +// +// Utilities for common `display` values +// + +@each $breakpoint in map-keys($grid-breakpoints) { + @include media-breakpoint-up($breakpoint) { + $infix: breakpoint-infix($breakpoint, $grid-breakpoints); + + .d#{$infix}-none { display: none !important; } + .d#{$infix}-inline { display: inline !important; } + .d#{$infix}-inline-block { display: inline-block !important; } + .d#{$infix}-block { display: block !important; } + .d#{$infix}-table { display: table !important; } + .d#{$infix}-table-cell { display: table-cell !important; } + .d#{$infix}-flex { display: flex !important; } + .d#{$infix}-inline-flex { display: inline-flex !important; } + } +} + + +// +// Utilities for toggling `display` in print +// + +.d-print-block { + display: none !important; + + @media print { + display: block !important; + } +} + +.d-print-inline { + display: none !important; + + @media print { + display: inline !important; + } +} + +.d-print-inline-block { + display: none !important; + + @media print { + display: inline-block !important; + } +} + +.d-print-none { + @media print { + display: none !important; + } +} diff --git a/templates/assets/bootstrap/scss/utilities/_flex.scss b/templates/assets/bootstrap/scss/utilities/_flex.scss new file mode 100644 index 0000000..cc69678 --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_flex.scss @@ -0,0 +1,48 @@ +// Flex variation +// +// Custom styles for additional flex alignment options. + +@each $breakpoint in map-keys($grid-breakpoints) { + @include media-breakpoint-up($breakpoint) { + $infix: breakpoint-infix($breakpoint, $grid-breakpoints); + + .order#{$infix}-first { order: -1; } + .order#{$infix}-last { order: 1; } + .order#{$infix}-0 { order: 0; } + + .flex#{$infix}-row { flex-direction: row !important; } + .flex#{$infix}-column { flex-direction: column !important; } + .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; } + .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; } + + .flex#{$infix}-wrap { flex-wrap: wrap !important; } + .flex#{$infix}-nowrap { flex-wrap: nowrap !important; } + .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; } + + .justify-content#{$infix}-start { justify-content: flex-start !important; } + .justify-content#{$infix}-end { justify-content: flex-end !important; } + .justify-content#{$infix}-center { justify-content: center !important; } + .justify-content#{$infix}-between { justify-content: space-between !important; } + .justify-content#{$infix}-around { justify-content: space-around !important; } + + .align-items#{$infix}-start { align-items: flex-start !important; } + .align-items#{$infix}-end { align-items: flex-end !important; } + .align-items#{$infix}-center { align-items: center !important; } + .align-items#{$infix}-baseline { align-items: baseline !important; } + .align-items#{$infix}-stretch { align-items: stretch !important; } + + .align-content#{$infix}-start { align-content: flex-start !important; } + .align-content#{$infix}-end { align-content: flex-end !important; } + .align-content#{$infix}-center { align-content: center !important; } + .align-content#{$infix}-between { align-content: space-between !important; } + .align-content#{$infix}-around { align-content: space-around !important; } + .align-content#{$infix}-stretch { align-content: stretch !important; } + + .align-self#{$infix}-auto { align-self: auto !important; } + .align-self#{$infix}-start { align-self: flex-start !important; } + .align-self#{$infix}-end { align-self: flex-end !important; } + .align-self#{$infix}-center { align-self: center !important; } + .align-self#{$infix}-baseline { align-self: baseline !important; } + .align-self#{$infix}-stretch { align-self: stretch !important; } + } +} diff --git a/templates/assets/bootstrap/scss/utilities/_float.scss b/templates/assets/bootstrap/scss/utilities/_float.scss new file mode 100644 index 0000000..01655e9 --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_float.scss @@ -0,0 +1,9 @@ +@each $breakpoint in map-keys($grid-breakpoints) { + @include media-breakpoint-up($breakpoint) { + $infix: breakpoint-infix($breakpoint, $grid-breakpoints); + + .float#{$infix}-left { @include float-left; } + .float#{$infix}-right { @include float-right; } + .float#{$infix}-none { @include float-none; } + } +} diff --git a/templates/assets/bootstrap/scss/utilities/_position.scss b/templates/assets/bootstrap/scss/utilities/_position.scss new file mode 100644 index 0000000..2cf08bf --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_position.scss @@ -0,0 +1,23 @@ +// Positioning + +.fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: $zindex-fixed; +} + +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: $zindex-fixed; +} + +.sticky-top { + position: sticky; + top: 0; + z-index: $zindex-sticky; +} diff --git a/templates/assets/bootstrap/scss/utilities/_screenreaders.scss b/templates/assets/bootstrap/scss/utilities/_screenreaders.scss new file mode 100644 index 0000000..9f26fde --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_screenreaders.scss @@ -0,0 +1,11 @@ +// +// Screenreaders +// + +.sr-only { + @include sr-only(); +} + +.sr-only-focusable { + @include sr-only-focusable(); +} diff --git a/templates/assets/bootstrap/scss/utilities/_sizing.scss b/templates/assets/bootstrap/scss/utilities/_sizing.scss new file mode 100644 index 0000000..a7dc3e4 --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_sizing.scss @@ -0,0 +1,10 @@ +// Width and height + +@each $prop, $abbrev in (width: w, height: h) { + @each $size, $length in $sizes { + .#{$abbrev}-#{$size} { #{$prop}: $length !important; } + } +} + +.mw-100 { max-width: 100% !important; } +.mh-100 { max-height: 100% !important; } diff --git a/templates/assets/bootstrap/scss/utilities/_spacing.scss b/templates/assets/bootstrap/scss/utilities/_spacing.scss new file mode 100644 index 0000000..c89816b --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_spacing.scss @@ -0,0 +1,41 @@ +// Margin and Padding + +@each $breakpoint in map-keys($grid-breakpoints) { + @include media-breakpoint-up($breakpoint) { + $infix: breakpoint-infix($breakpoint, $grid-breakpoints); + + @each $prop, $abbrev in (margin: m, padding: p) { + @each $size, $length in $spacers { + + .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; } + .#{$abbrev}t#{$infix}-#{$size} { #{$prop}-top: $length !important; } + .#{$abbrev}r#{$infix}-#{$size} { #{$prop}-right: $length !important; } + .#{$abbrev}b#{$infix}-#{$size} { #{$prop}-bottom: $length !important; } + .#{$abbrev}l#{$infix}-#{$size} { #{$prop}-left: $length !important; } + .#{$abbrev}x#{$infix}-#{$size} { + #{$prop}-right: $length !important; + #{$prop}-left: $length !important; + } + .#{$abbrev}y#{$infix}-#{$size} { + #{$prop}-top: $length !important; + #{$prop}-bottom: $length !important; + } + } + } + + // Some special margin utils + .m#{$infix}-auto { margin: auto !important; } + .mt#{$infix}-auto { margin-top: auto !important; } + .mr#{$infix}-auto { margin-right: auto !important; } + .mb#{$infix}-auto { margin-bottom: auto !important; } + .ml#{$infix}-auto { margin-left: auto !important; } + .mx#{$infix}-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my#{$infix}-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + } +} diff --git a/templates/assets/bootstrap/scss/utilities/_text.scss b/templates/assets/bootstrap/scss/utilities/_text.scss new file mode 100644 index 0000000..4ac9053 --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_text.scss @@ -0,0 +1,61 @@ +// +// Text +// + +// Alignment + +.text-justify { text-align: justify !important; } +.text-nowrap { white-space: nowrap !important; } +.text-truncate { @include text-truncate; } + +// Responsive alignment + +@each $breakpoint in map-keys($grid-breakpoints) { + @include media-breakpoint-up($breakpoint) { + $infix: breakpoint-infix($breakpoint, $grid-breakpoints); + + .text#{$infix}-left { text-align: left !important; } + .text#{$infix}-right { text-align: right !important; } + .text#{$infix}-center { text-align: center !important; } + } +} + +// Transformation + +.text-lowercase { text-transform: lowercase !important; } +.text-uppercase { text-transform: uppercase !important; } +.text-capitalize { text-transform: capitalize !important; } + +// Weight and italics + +.font-weight-normal { font-weight: $font-weight-normal; } +.font-weight-bold { font-weight: $font-weight-bold; } +.font-italic { font-style: italic; } + +// Contextual colors + +.text-white { + color: #fff !important; +} + +@include text-emphasis-variant('.text-muted', $text-muted); + +@include text-emphasis-variant('.text-primary', $brand-primary); + +@include text-emphasis-variant('.text-success', $brand-success); + +@include text-emphasis-variant('.text-info', $brand-info); + +@include text-emphasis-variant('.text-warning', $brand-warning); + +@include text-emphasis-variant('.text-danger', $brand-danger); + +// Font color + +@include text-emphasis-variant('.text-gray-dark', $gray-dark); + +// Misc + +.text-hide { + @include text-hide(); +} diff --git a/templates/assets/bootstrap/scss/utilities/_visibility.scss b/templates/assets/bootstrap/scss/utilities/_visibility.scss new file mode 100644 index 0000000..823406d --- /dev/null +++ b/templates/assets/bootstrap/scss/utilities/_visibility.scss @@ -0,0 +1,11 @@ +// +// Visibility utilities +// + +.visible { + @include invisible(visible); +} + +.invisible { + @include invisible(hidden); +} |
