├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── README.md
├── build
├── build.js
├── check-versions.js
├── dev-client.js
├── dev-server.js
├── utils.js
├── vue-loader.conf.js
├── webpack.base.conf.js
├── webpack.dev.conf.js
├── webpack.prod.conf.js
└── webpack.test.conf.js
├── config
├── dev.env.js
├── index.js
├── prod.env.js
└── test.env.js
├── docs
├── index.html
└── static
│ ├── css
│ ├── app.f58dc275de6169a21640cb42cefa9960.css
│ └── app.f58dc275de6169a21640cb42cefa9960.css.map
│ └── js
│ ├── app.3df72a099ccfbf681458.js
│ ├── manifest.cde70f755a80598d9f5e.js
│ └── vendor.ad497b4e9f9f6446cc71.js
├── index.html
├── index2.html
├── package.json
├── src
├── App.vue
├── assets
│ └── logo.png
├── blocks.js
├── components
│ ├── GameBoard.vue
│ ├── Hello.vue
│ └── Tile.vue
├── main.js
└── store
│ ├── store.js
│ └── storeHelpers.js
└── test
├── e2e
├── custom-assertions
│ └── elementCount.js
├── nightwatch.conf.js
├── runner.js
└── specs
│ └── test.js
└── unit
├── .eslintrc
├── index.js
├── karma.conf.js
└── specs
├── GameBoard.spec.js
├── Hello.spec.js
├── store.spec.js
├── store
├── DELETE_LINE.spec.js
├── LOWER_CURRENT_BLOCK.spec.js
├── MOVE_CURRENT_BLOCK.spec.js
├── RESTART_GAME.spec.js
└── ROTATE_CURRENT_BLOCK.spec.js
└── storeHelper.spec.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["es2015", { "modules": false }],
4 | "stage-2"
5 | ],
6 | "plugins": ["transform-runtime"],
7 | "comments": false,
8 | "env": {
9 | "test": {
10 | "plugins": [ "istanbul" ]
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | build/*.js
2 | config/*.js
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // http://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parser: 'babel-eslint',
6 | parserOptions: {
7 | sourceType: 'module'
8 | },
9 | env: {
10 | browser: true,
11 | },
12 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
13 | extends: 'standard',
14 | // required to lint *.vue files
15 | plugins: [
16 | 'html'
17 | ],
18 | // add your custom rules here
19 | 'rules': {
20 | // allow paren-less arrow functions
21 | 'arrow-parens': 0,
22 | // allow async-await
23 | 'generator-star-spacing': 0,
24 | // allow debugger during development
25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | npm-debug.log
4 | test/unit/coverage
5 | test/e2e/reports
6 | selenium-debug.log
7 | node_modules/
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Tetris build with Vue.js
2 |
3 | ## Build Setup
4 |
5 | ``` bash
6 | # install dependencies
7 | npm install
8 |
9 | # serve with hot reload at localhost:8080
10 | npm run dev
11 |
12 | # build for production with minification
13 | npm run build
14 |
15 | # build for production and view the bundle analyzer report
16 | npm run build --report
17 |
18 | # run unit tests
19 | npm run unit
20 |
21 | # run e2e tests
22 | npm run e2e
23 |
24 | # run all tests
25 | npm test
26 | ```
27 |
28 |
--------------------------------------------------------------------------------
/build/build.js:
--------------------------------------------------------------------------------
1 | // https://github.com/shelljs/shelljs
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | var ora = require('ora')
7 | var path = require('path')
8 | var chalk = require('chalk')
9 | var shell = require('shelljs')
10 | var webpack = require('webpack')
11 | var config = require('../config')
12 | var webpackConfig = require('./webpack.prod.conf')
13 |
14 | var spinner = ora('building for production...')
15 | spinner.start()
16 |
17 | var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory)
18 | shell.rm('-rf', assetsPath)
19 | shell.mkdir('-p', assetsPath)
20 | shell.config.silent = true
21 | shell.cp('-R', 'static/*', assetsPath)
22 | shell.config.silent = false
23 |
24 | webpack(webpackConfig, function (err, stats) {
25 | spinner.stop()
26 | if (err) throw err
27 | process.stdout.write(stats.toString({
28 | colors: true,
29 | modules: false,
30 | children: false,
31 | chunks: false,
32 | chunkModules: false
33 | }) + '\n\n')
34 |
35 | console.log(chalk.cyan(' Build complete.\n'))
36 | console.log(chalk.yellow(
37 | ' Tip: built files are meant to be served over an HTTP server.\n' +
38 | ' Opening index.html over file:// won\'t work.\n'
39 | ))
40 | })
41 |
--------------------------------------------------------------------------------
/build/check-versions.js:
--------------------------------------------------------------------------------
1 | var chalk = require('chalk')
2 | var semver = require('semver')
3 | var packageConfig = require('../package.json')
4 |
5 | function exec (cmd) {
6 | return require('child_process').execSync(cmd).toString().trim()
7 | }
8 |
9 | var versionRequirements = [
10 | {
11 | name: 'node',
12 | currentVersion: semver.clean(process.version),
13 | versionRequirement: packageConfig.engines.node
14 | },
15 | {
16 | name: 'npm',
17 | currentVersion: exec('npm --version'),
18 | versionRequirement: packageConfig.engines.npm
19 | }
20 | ]
21 |
22 | module.exports = function () {
23 | var warnings = []
24 | for (var i = 0; i < versionRequirements.length; i++) {
25 | var mod = versionRequirements[i]
26 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
27 | warnings.push(mod.name + ': ' +
28 | chalk.red(mod.currentVersion) + ' should be ' +
29 | chalk.green(mod.versionRequirement)
30 | )
31 | }
32 | }
33 |
34 | if (warnings.length) {
35 | console.log('')
36 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
37 | console.log()
38 | for (var i = 0; i < warnings.length; i++) {
39 | var warning = warnings[i]
40 | console.log(' ' + warning)
41 | }
42 | console.log()
43 | process.exit(1)
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/build/dev-client.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | require('eventsource-polyfill')
3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
4 |
5 | hotClient.subscribe(function (event) {
6 | if (event.action === 'reload') {
7 | window.location.reload()
8 | }
9 | })
10 |
--------------------------------------------------------------------------------
/build/dev-server.js:
--------------------------------------------------------------------------------
1 | require('./check-versions')()
2 |
3 | var config = require('../config')
4 | if (!process.env.NODE_ENV) {
5 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
6 | }
7 |
8 | var opn = require('opn')
9 | var path = require('path')
10 | var express = require('express')
11 | var webpack = require('webpack')
12 | var proxyMiddleware = require('http-proxy-middleware')
13 | var webpackConfig = process.env.NODE_ENV === 'testing'
14 | ? require('./webpack.prod.conf')
15 | : require('./webpack.dev.conf')
16 |
17 | // default port where dev server listens for incoming traffic
18 | var port = process.env.PORT || config.dev.port
19 | // automatically open browser, if not set will be false
20 | var autoOpenBrowser = !!config.dev.autoOpenBrowser
21 | // Define HTTP proxies to your custom API backend
22 | // https://github.com/chimurai/http-proxy-middleware
23 | var proxyTable = config.dev.proxyTable
24 |
25 | var app = express()
26 | var compiler = webpack(webpackConfig)
27 |
28 | var devMiddleware = require('webpack-dev-middleware')(compiler, {
29 | publicPath: webpackConfig.output.publicPath,
30 | quiet: true
31 | })
32 |
33 | var hotMiddleware = require('webpack-hot-middleware')(compiler, {
34 | log: () => {}
35 | })
36 | // force page reload when html-webpack-plugin template changes
37 | compiler.plugin('compilation', function (compilation) {
38 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
39 | hotMiddleware.publish({ action: 'reload' })
40 | cb()
41 | })
42 | })
43 |
44 | // proxy api requests
45 | Object.keys(proxyTable).forEach(function (context) {
46 | var options = proxyTable[context]
47 | if (typeof options === 'string') {
48 | options = { target: options }
49 | }
50 | app.use(proxyMiddleware(options.filter || context, options))
51 | })
52 |
53 | // handle fallback for HTML5 history API
54 | app.use(require('connect-history-api-fallback')())
55 |
56 | // serve webpack bundle output
57 | app.use(devMiddleware)
58 |
59 | // enable hot-reload and state-preserving
60 | // compilation error display
61 | app.use(hotMiddleware)
62 |
63 | // serve pure static assets
64 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
65 | app.use(staticPath, express.static('./static'))
66 |
67 | var uri = 'http://localhost:' + port
68 |
69 | devMiddleware.waitUntilValid(function () {
70 | console.log('> Listening at ' + uri + '\n')
71 | })
72 |
73 | module.exports = app.listen(port, function (err) {
74 | if (err) {
75 | console.log(err)
76 | return
77 | }
78 |
79 | // when env is testing, don't need open it
80 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
81 | opn(uri)
82 | }
83 | })
84 |
--------------------------------------------------------------------------------
/build/utils.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var config = require('../config')
3 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
4 |
5 | exports.assetsPath = function (_path) {
6 | var assetsSubDirectory = process.env.NODE_ENV === 'production'
7 | ? config.build.assetsSubDirectory
8 | : config.dev.assetsSubDirectory
9 | return path.posix.join(assetsSubDirectory, _path)
10 | }
11 |
12 | exports.cssLoaders = function (options) {
13 | options = options || {}
14 | // generate loader string to be used with extract text plugin
15 | function generateLoaders (loaders) {
16 | var sourceLoader = loaders.map(function (loader) {
17 | var extraParamChar
18 | if (/\?/.test(loader)) {
19 | loader = loader.replace(/\?/, '-loader?')
20 | extraParamChar = '&'
21 | } else {
22 | loader = loader + '-loader'
23 | extraParamChar = '?'
24 | }
25 | return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '')
26 | }).join('!')
27 |
28 | // Extract CSS when that option is specified
29 | // (which is the case during production build)
30 | if (options.extract) {
31 | return ExtractTextPlugin.extract({
32 | loader: sourceLoader,
33 | fallbackLoader: 'vue-style-loader'
34 | })
35 | } else {
36 | return ['vue-style-loader', sourceLoader].join('!')
37 | }
38 | }
39 |
40 | // http://vuejs.github.io/vue-loader/en/configurations/extract-css.html
41 | return {
42 | css: generateLoaders(['css']),
43 | postcss: generateLoaders(['css']),
44 | less: generateLoaders(['css', 'less']),
45 | sass: generateLoaders(['css', 'sass?indentedSyntax']),
46 | scss: generateLoaders(['css', 'sass']),
47 | stylus: generateLoaders(['css', 'stylus']),
48 | styl: generateLoaders(['css', 'stylus'])
49 | }
50 | }
51 |
52 | // Generate loaders for standalone style files (outside of .vue)
53 | exports.styleLoaders = function (options) {
54 | var output = []
55 | var loaders = exports.cssLoaders(options)
56 | for (var extension in loaders) {
57 | var loader = loaders[extension]
58 | output.push({
59 | test: new RegExp('\\.' + extension + '$'),
60 | loader: loader
61 | })
62 | }
63 | return output
64 | }
65 |
--------------------------------------------------------------------------------
/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | var utils = require('./utils')
2 | var config = require('../config')
3 | var isProduction = process.env.NODE_ENV === 'production'
4 |
5 | module.exports = {
6 | loaders: utils.cssLoaders({
7 | sourceMap: isProduction
8 | ? config.build.productionSourceMap
9 | : config.dev.cssSourceMap,
10 | extract: isProduction
11 | }),
12 | postcss: [
13 | require('autoprefixer')({
14 | browsers: ['last 2 versions']
15 | })
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var utils = require('./utils')
3 | var config = require('../config')
4 | var vueLoaderConfig = require('./vue-loader.conf')
5 | var eslintFriendlyFormatter = require('eslint-friendly-formatter')
6 |
7 | function resolve (dir) {
8 | return path.join(__dirname, '..', dir)
9 | }
10 |
11 | module.exports = {
12 | entry: {
13 | app: './src/main.js'
14 | },
15 | output: {
16 | path: config.build.assetsRoot,
17 | filename: '[name].js',
18 | publicPath: process.env.NODE_ENV === 'production'
19 | ? config.build.assetsPublicPath
20 | : config.dev.assetsPublicPath
21 | },
22 | resolve: {
23 | extensions: ['.js', '.vue', '.json'],
24 | modules: [
25 | resolve('src'),
26 | resolve('node_modules')
27 | ],
28 | alias: {
29 | 'vue$': 'vue/dist/vue.common.js',
30 | 'src': resolve('src'),
31 | 'assets': resolve('src/assets'),
32 | 'components': resolve('src/components')
33 | }
34 | },
35 | module: {
36 | rules: [
37 | {
38 | test: /\.(js|vue)$/,
39 | loader: 'eslint-loader',
40 | enforce: "pre",
41 | include: [resolve('src'), resolve('test')],
42 | options: {
43 | formatter: eslintFriendlyFormatter
44 | }
45 | },
46 | {
47 | test: /\.vue$/,
48 | loader: 'vue-loader',
49 | options: vueLoaderConfig
50 | },
51 | {
52 | test: /\.js$/,
53 | loader: 'babel-loader',
54 | include: [resolve('src'), resolve('test')]
55 | },
56 | {
57 | test: /\.json$/,
58 | loader: 'json-loader'
59 | },
60 | {
61 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
62 | loader: 'url-loader',
63 | query: {
64 | limit: 10000,
65 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
66 | }
67 | },
68 | {
69 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
70 | loader: 'url-loader',
71 | query: {
72 | limit: 10000,
73 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
74 | }
75 | }
76 | ]
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | var utils = require('./utils')
2 | var webpack = require('webpack')
3 | var config = require('../config')
4 | var merge = require('webpack-merge')
5 | var baseWebpackConfig = require('./webpack.base.conf')
6 | var HtmlWebpackPlugin = require('html-webpack-plugin')
7 | var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
8 |
9 | // add hot-reload related code to entry chunks
10 | Object.keys(baseWebpackConfig.entry).forEach(function (name) {
11 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
12 | })
13 |
14 | module.exports = merge(baseWebpackConfig, {
15 | module: {
16 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
17 | },
18 | // cheap-module-eval-source-map is faster for development
19 | devtool: '#cheap-module-eval-source-map',
20 | plugins: [
21 | new webpack.DefinePlugin({
22 | 'process.env': config.dev.env
23 | }),
24 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
25 | new webpack.HotModuleReplacementPlugin(),
26 | new webpack.NoEmitOnErrorsPlugin(),
27 | // https://github.com/ampedandwired/html-webpack-plugin
28 | new HtmlWebpackPlugin({
29 | filename: 'index.html',
30 | template: 'index.html',
31 | inject: true
32 | }),
33 | new FriendlyErrorsPlugin()
34 | ]
35 | })
36 |
--------------------------------------------------------------------------------
/build/webpack.prod.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var utils = require('./utils')
3 | var webpack = require('webpack')
4 | var config = require('../config')
5 | var merge = require('webpack-merge')
6 | var baseWebpackConfig = require('./webpack.base.conf')
7 | var HtmlWebpackPlugin = require('html-webpack-plugin')
8 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
9 | var env = process.env.NODE_ENV === 'testing'
10 | ? require('../config/test.env')
11 | : config.build.env
12 |
13 | var webpackConfig = merge(baseWebpackConfig, {
14 | module: {
15 | rules: utils.styleLoaders({
16 | sourceMap: config.build.productionSourceMap,
17 | extract: true
18 | })
19 | },
20 | devtool: config.build.productionSourceMap ? '#source-map' : false,
21 | output: {
22 | path: config.build.assetsRoot,
23 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
24 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
25 | },
26 | plugins: [
27 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
28 | new webpack.DefinePlugin({
29 | 'process.env': env
30 | }),
31 | new webpack.optimize.UglifyJsPlugin({
32 | compress: {
33 | warnings: false
34 | }
35 | }),
36 | // extract css into its own file
37 | new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),
38 | // generate dist index.html with correct asset hash for caching.
39 | // you can customize output by editing /index.html
40 | // see https://github.com/ampedandwired/html-webpack-plugin
41 | new HtmlWebpackPlugin({
42 | filename: process.env.NODE_ENV === 'testing'
43 | ? 'index.html'
44 | : config.build.index,
45 | template: 'index.html',
46 | inject: true,
47 | minify: {
48 | removeComments: true,
49 | collapseWhitespace: true,
50 | removeAttributeQuotes: true
51 | // more options:
52 | // https://github.com/kangax/html-minifier#options-quick-reference
53 | },
54 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
55 | chunksSortMode: 'dependency'
56 | }),
57 | // split vendor js into its own file
58 | new webpack.optimize.CommonsChunkPlugin({
59 | name: 'vendor',
60 | minChunks: function (module, count) {
61 | // any required modules inside node_modules are extracted to vendor
62 | return (
63 | module.resource &&
64 | /\.js$/.test(module.resource) &&
65 | module.resource.indexOf(
66 | path.join(__dirname, '../node_modules')
67 | ) === 0
68 | )
69 | }
70 | }),
71 | // extract webpack runtime and module manifest to its own file in order to
72 | // prevent vendor hash from being updated whenever app bundle is updated
73 | new webpack.optimize.CommonsChunkPlugin({
74 | name: 'manifest',
75 | chunks: ['vendor']
76 | })
77 | ]
78 | })
79 |
80 | if (config.build.productionGzip) {
81 | var CompressionWebpackPlugin = require('compression-webpack-plugin')
82 |
83 | webpackConfig.plugins.push(
84 | new CompressionWebpackPlugin({
85 | asset: '[path].gz[query]',
86 | algorithm: 'gzip',
87 | test: new RegExp(
88 | '\\.(' +
89 | config.build.productionGzipExtensions.join('|') +
90 | ')$'
91 | ),
92 | threshold: 10240,
93 | minRatio: 0.8
94 | })
95 | )
96 | }
97 |
98 | if (config.build.bundleAnalyzerReport) {
99 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
100 | webpackConfig.plugins.push(new BundleAnalyzerPlugin())
101 | }
102 |
103 | module.exports = webpackConfig
104 |
--------------------------------------------------------------------------------
/build/webpack.test.conf.js:
--------------------------------------------------------------------------------
1 | // This is the webpack config used for unit tests.
2 |
3 | var utils = require('./utils')
4 | var webpack = require('webpack')
5 | var merge = require('webpack-merge')
6 | var baseConfig = require('./webpack.base.conf')
7 |
8 | var webpackConfig = merge(baseConfig, {
9 | // use inline sourcemap for karma-sourcemap-loader
10 | module: {
11 | rules: utils.styleLoaders()
12 | },
13 | devtool: '#inline-source-map',
14 | plugins: [
15 | new webpack.DefinePlugin({
16 | 'process.env': require('../config/test.env')
17 | })
18 | ]
19 | })
20 |
21 | // no need for app entry during tests
22 | delete webpackConfig.entry
23 |
24 | module.exports = webpackConfig
25 |
--------------------------------------------------------------------------------
/config/dev.env.js:
--------------------------------------------------------------------------------
1 | var merge = require('webpack-merge')
2 | var prodEnv = require('./prod.env')
3 |
4 | module.exports = merge(prodEnv, {
5 | NODE_ENV: '"development"'
6 | })
7 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | // see http://vuejs-templates.github.io/webpack for documentation.
2 | var path = require('path')
3 |
4 | module.exports = {
5 | build: {
6 | env: require('./prod.env'),
7 | index: path.resolve(__dirname, '../dist/index.html'),
8 | assetsRoot: path.resolve(__dirname, '../dist'),
9 | assetsSubDirectory: 'static',
10 | assetsPublicPath: '/',
11 | productionSourceMap: true,
12 | // Gzip off by default as many popular static hosts such as
13 | // Surge or Netlify already gzip all static assets for you.
14 | // Before setting to `true`, make sure to:
15 | // npm install --save-dev compression-webpack-plugin
16 | productionGzip: false,
17 | productionGzipExtensions: ['js', 'css'],
18 | // Run the build command with an extra argument to
19 | // View the bundle analyzer report after build finishes:
20 | // `npm run build --report`
21 | // Set to `true` or `false` to always turn it on or off
22 | bundleAnalyzerReport: process.env.npm_config_report
23 | },
24 | dev: {
25 | env: require('./dev.env'),
26 | port: 8080,
27 | autoOpenBrowser: true,
28 | assetsSubDirectory: 'static',
29 | assetsPublicPath: '/',
30 | proxyTable: {},
31 | // CSS Sourcemaps off by default because relative paths are "buggy"
32 | // with this option, according to the CSS-Loader README
33 | // (https://github.com/webpack/css-loader#sourcemaps)
34 | // In our experience, they generally work as expected,
35 | // just be aware of this issue when enabling this option.
36 | cssSourceMap: false
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/config/prod.env.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | NODE_ENV: '"production"'
3 | }
4 |
--------------------------------------------------------------------------------
/config/test.env.js:
--------------------------------------------------------------------------------
1 | var merge = require('webpack-merge')
2 | var devEnv = require('./dev.env')
3 |
4 | module.exports = merge(devEnv, {
5 | NODE_ENV: '"testing"'
6 | })
7 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 | tetris
3 |
4 | GH Pages
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/docs/static/css/app.f58dc275de6169a21640cb42cefa9960.css:
--------------------------------------------------------------------------------
1 |
2 | .game.board[data-v-1c653e6e] {
3 | text-align: center;
4 | }
5 |
6 | .restart.button[data-v-250744c4] {
7 | border: 0.125em solid black;
8 | display: inline-block;
9 | width: 25.5em;
10 | height: 2.5em;
11 | margin-top: 0.5em;
12 | }
13 | .score[data-v-250744c4] {
14 | display: inline-block;
15 | font-size: 1.5em;
16 | }
17 | .tile[data-v-250744c4] {
18 | display: inline-block;
19 | width: 1.5em;
20 | height: 1.5em;
21 | border: 0.125em solid grey;
22 | margin-left: 0.125em;
23 | }
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | /*# sourceMappingURL=app.f58dc275de6169a21640cb42cefa9960.css.map*/
--------------------------------------------------------------------------------
/docs/static/css/app.f58dc275de6169a21640cb42cefa9960.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///webpack:///src/App.vue","webpack:///webpack:///src/components/GameBoard.vue"],"names":[],"mappings":";AACA;EACE,mBAAmB;CACpB;;ACFD;EACE,4BAA4B;EAC5B,sBAAsB;EACtB,cAAc;EACd,cAAc;EACd,kBAAkB;CACnB;AACD;EACE,sBAAsB;EACtB,iBAAiB;CAClB;AACD;EACE,sBAAsB;EACtB,aAAa;EACb,cAAc;EACd,2BAA2B;EAC3B,qBAAqB;CACtB","file":"static/css/app.f58dc275de6169a21640cb42cefa9960.css","sourcesContent":["\n.game.board[data-v-1c653e6e] {\n text-align: center;\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/App.vue","\n.restart.button[data-v-250744c4] {\n border: 0.125em solid black;\n display: inline-block;\n width: 25.5em;\n height: 2.5em;\n margin-top: 0.5em;\n}\n.score[data-v-250744c4] {\n display: inline-block;\n font-size: 1.5em;\n}\n.tile[data-v-250744c4] {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n border: 0.125em solid grey;\n margin-left: 0.125em;\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/GameBoard.vue"],"sourceRoot":""}
--------------------------------------------------------------------------------
/docs/static/js/app.3df72a099ccfbf681458.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([1,2],[,,,,,,,function(r,t,e){"use strict";t.a=[{id:0,name:"I",rotIndex:0,rotations:[[[1,4],[1,5],[1,6],[1,7]],[[0,4],[1,4],[2,4],[3,4]],[[1,4],[1,5],[1,6],[1,7]],[[0,5],[1,5],[2,5],[3,5]]]},{id:1,name:"L",rotIndex:0,rotations:[[[0,4],[1,4],[2,4],[2,5]],[[1,4],[1,5],[1,6],[2,4]],[[0,4],[0,5],[1,5],[2,5]],[[1,4],[1,5],[1,6],[0,6]]]},{id:2,name:"Z",rotIndex:0,rotations:[[[0,4],[1,4],[1,5],[2,5]],[[1,6],[2,4],[1,5],[2,5]],[[0,4],[1,4],[1,5],[2,5]],[[1,6],[2,4],[1,5],[2,5]]]},{id:3,name:"S",rotIndex:0,rotations:[[[0,5],[1,4],[1,5],[2,4]],[[2,5],[1,4],[1,5],[2,6]],[[0,5],[1,4],[1,5],[2,4]],[[2,5],[1,4],[1,5],[2,6]]]},{id:4,name:"J",rotIndex:0,rotations:[[[0,5],[1,5],[2,5],[2,4]],[[0,4],[1,4],[1,5],[1,6]],[[0,5],[1,5],[2,5],[0,6]],[[2,6],[1,4],[1,5],[1,6]]]},{id:5,name:"O",rotIndex:0,rotations:[[[0,4],[0,5],[1,4],[1,5]],[[0,4],[0,5],[1,4],[1,5]],[[0,4],[0,5],[1,4],[1,5]],[[0,4],[0,5],[1,4],[1,5]]]},{id:6,name:"T",rotIndex:0,rotations:[[[1,4],[1,5],[1,6],[0,5]],[[0,5],[1,5],[2,5],[1,6]],[[1,5],[1,6],[1,4],[2,5]],[[0,5],[1,5],[2,5],[1,4]]]}]},,,,,,,function(r,t,e){"use strict";var o=e(6),n=e.n(o),i=e(13),a=e.n(i),s=e(7),c=e(16);n.a.use(a.a);var u={board:[],currentBlock:{},shouldCreateNextBlock:!0,gameOver:!1,score:0,previousColorId:0,currentColorId:0,lowerSpeed:500},l={SETUP_BOARD:function(r,t){r.board=t},CREATE_BLOCK:function(r,t){var e=t.rotations[t.rotIndex];for(var o in e)r.board[e[o][0]][e[o][1]]=1,r.shouldCreateNextBlock=!1;r.currentColorId=t.id},SET_CURRENT_BLOCK:function(r,t){r.currentBlock=t},ROTATE_CURRENT_BLOCK:function(r){if(e.i(c.a)(r.currentBlock,r.board)){var t=r.currentBlock.rotations[r.currentBlock.rotIndex],o=e.i(c.b)(r.currentBlock);for(var n in t)r.board[t[n][0]].splice(t[n][1],1,0);for(var i in o)r.board[o[i][0]].splice(o[i][1],1,1);r.currentBlock.rotIndex<3?r.currentBlock.rotIndex+=1:r.currentBlock.rotIndex=0}},MOVE_CURRENT_BLOCK:function(r,t){var o=r.currentBlock.rotations[r.currentBlock.rotIndex];if(!e.i(c.c)(t,r.board[0].length,o)&&e.i(c.d)(t,r.board,o)){var n=[],i=[];for(var a in o){var s=o[a][0],u=o[a][1],l=0;l="right"===t?o[a][1]+1:o[a][1]-1,e.i(c.e)([s,u],i)===-1&&r.board[s].splice(u,1,0),r.board[s].splice(l,1,1),i.push([s,l]),n.push([s,l])}r.currentBlock.rotations[r.currentBlock.rotIndex]=n;var d=r.currentBlock.rotIndex;for(var f in r.currentBlock.rotations)if(parseInt(f)!==parseInt(d))for(var v in r.currentBlock.rotations[f])"right"===t?r.currentBlock.rotations[f][v][1]+=1:r.currentBlock.rotations[f][v][1]-=1}},LOWER_CURRENT_BLOCK:function(r){var t=[],o=[],n=r.currentBlock.rotations[r.currentBlock.rotIndex];if(e.i(c.f)(r.board,r.currentBlock)||e.i(c.g)(r.board,r.currentBlock)){var i=r.currentBlock,a=i.rotations[i.rotIndex],u=s.a[i.id].rotations[i.rotIndex],l=!1;for(var d in a)for(var f in a[d])a[d][f]!==u[d][f]&&(l=!0);l?(r.previousColorId=i.id,r.shouldCreateNextBlock=!0):r.gameOver=!0}else{for(var v in n){var h=n[v][0],p=n[v][0]+1,B=n[v][1];e.i(c.e)([h,B],t)===-1&&r.board[h].splice(B,1,0),r.board[p].splice(B,1,1),t.push([p,B]),o.push([p,B])}r.currentBlock.rotations[r.currentBlock.rotIndex]=o;var m=r.currentBlock.rotIndex;for(var C in r.currentBlock.rotations)if(parseInt(C)!==parseInt(m))for(var k in r.currentBlock.rotations[C])r.currentBlock.rotations[C][k][0]+=1}},DELETE_LINE_IF_COMPLETE:function(r,t){if(e.i(c.h)(r.board[t])){r.board.splice(t,1);var o=new Array(r.board[0].length).fill(0);r.board.unshift(o),r.score+=1}},RESTART_GAME:function(r){for(var t in r.board)r.board.splice(t,1,new Array(r.board[0].length).fill(0));r.gameOver=!1,r.shouldCreateNextBlock=!0,r.score=0,r.previousColorId=0,r.currentColorId=0}},d={},f={currentBlockTiles:function(r){},canBeLowered:function(r){return!e.i(c.f)(r.board,r.currentBlock)&&!e.i(c.g)(r.board,r.currentBlock)}};t.a=new a.a.Store({state:u,getters:f,actions:d,mutations:l})},function(r,t,e){e(50);var o=e(5)(e(17),e(55),"data-v-1c653e6e",null);r.exports=o.exports},function(r,t,e){"use strict";function o(r,t,e){if("right"===r){for(var o in e)if(e[o][1]+1===t)return!0}else for(var n in e)if(e[n][1]-1<0)return!0;return!1}function n(r){return!r.includes(0)}function i(r){var t=void 0;return t=r.rotIndex<3?r.rotations[r.rotIndex+1]:r.rotations[0]}function a(r,t){if(c(t,r)||u(t,r))return!1;var e=i(r),o=JSON.parse(p()(t)),n=r.rotations[r.rotIndex];for(var a in n)o[n[a][0]].splice(n[a][1],1,0);for(var s in e){if(!(e[s][0]=0))return!1;if(1===o[e[s][0]][e[s][1]])return!1}return!0}function s(r,t,e){if("right"===r){var o=f(e);for(var n in o)if(0!==t[o[n][0]][o[n][1]+1])return!1}else if("left"===r){var i=d(e);for(var a in i)if(0!==t[i[a][0]][i[a][1]-1])return!1}return!0}function c(r,t){var e=v(t.rotations[t.rotIndex]);for(var o in e)if(!(e[o][0]r[o][1]&&e.splice(n,1,r[o]);else t.push(r[o][0]),e.push(r[o]);return e}function f(r){var t=[],e=[];for(var o in r)if(t.includes(r[o][0]))for(var n in t)e[n][0]===r[o][0]&&e[n][1]1)for(var o=Array.prototype.slice.call(arguments,1);e--;)t[r-1-e]=this.createArray.apply(this,o);return t},randomBlockNumber:function(){return Math.floor(Math.random()*(c.a.length-0))},restart:function(){this.$store.commit("RESTART_GAME")}},computed:n()({},e.i(s.mapState)({board:function(r){return r.board}}))}},function(r,t,e){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={props:["tile","x","y"],data:function(){return{tileColorSet:!1,tileColorId:"",colors:["red","blue","green","orange","pink","purple","yellow"]}},methods:{isCurrentBlockTile:function(){var r=this.$store.state.currentBlock.rotations[this.$store.state.currentBlock.rotIndex];for(var t in r)if(r[t][0]===this.y&&r[t][1]===this.x)return!0;return!1}},computed:{tileStyle:function(){return 1===this.tile?this.isCurrentBlockTile()?{backgroundColor:this.colors[this.$store.state.currentColorId]}:(this.tileColorSet||(this.tileColorId=this.$store.state.previousColorId),this.tileColorSet=!0,{backgroundColor:this.colors[this.tileColorId]}):void(this.tileColorSet=!1)}}}},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,function(r,t){},function(r,t){},function(r,t){},function(r,t,e){e(51);var o=e(5)(e(18),e(56),"data-v-250744c4",null);r.exports=o.exports},function(r,t,e){e(52);var o=e(5)(e(19),e(57),"data-v-4627f414",null);r.exports=o.exports},function(r,t){r.exports={render:function(){var r=this,t=r.$createElement,e=r._self._c||t;return e("div",{attrs:{id:"app"},on:{keydown:r.moveBlock}},[e("div",{staticClass:"game board"},[e("GameBoard")],1)])},staticRenderFns:[]}},function(r,t){r.exports={render:function(){var r=this,t=r.$createElement,e=r._self._c||t;return e("div",[r._l(r.board,function(t,o){return e("div",{staticClass:"line"},r._l(t,function(r,t){return e("Tile",{attrs:{y:o,x:t,tile:r}})}))}),r._v(" "),e("div",{staticClass:"score"},[r._v("\n Score: "+r._s(r.$store.state.score)+"\n ")]),r._v(" "),r.$store.state.gameOver?e("div",[e("button",{staticClass:"restart button",on:{click:r.restart}},[r._v("\n Restart\n ")])]):r._e()],2)},staticRenderFns:[]}},function(r,t){r.exports={render:function(){var r=this,t=r.$createElement,e=r._self._c||t;return e("div",{staticClass:"tile",style:r.tileStyle},[e("div")])},staticRenderFns:[]}},,,function(r,t,e){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=e(6),n=e.n(o),i=e(15),a=e.n(i),s=e(14);new n.a({el:"#app",store:s.a,template:"",components:{App:a.a}})}],[60]);
--------------------------------------------------------------------------------
/docs/static/js/manifest.cde70f755a80598d9f5e.js:
--------------------------------------------------------------------------------
1 | !function(e){function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}var n=window.webpackJsonp;window.webpackJsonp=function(t,c,i){for(var u,a,f,s=0,l=[];s-1)return t.splice(n,1)}}function a(t,e){return ai.call(t,e)}function s(t){return"string"==typeof t||"number"==typeof t}function c(t){var e=Object.create(null);return function(n){var r=e[n];return r||(e[n]=t(n))}}function u(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n}function l(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function f(t,e){for(var n in e)t[n]=e[n];return t}function p(t){return null!==t&&"object"==typeof t}function d(t){return pi.call(t)===di}function v(t){for(var e={},n=0;n1?l(n):n;for(var r=l(arguments,1),i=0,o=n.length;i=0&&Qi[n].id>t.id;)n--;Qi.splice(Math.max(n,no)+1,0,t)}else Qi.push(t);to||(to=!0,Si(Ot))}}function St(t){oo.clear(),Et(t,oo)}function Et(t,e){var n,r,i=Array.isArray(t);if((i||p(t))&&Object.isExtensible(t)){if(t.__ob__){var o=t.__ob__.dep.id;if(e.has(o))return;e.add(o)}if(i)for(n=t.length;n--;)Et(t[n],e);else for(r=Object.keys(t),n=r.length;n--;)Et(t[r[n]],e)}}function jt(t){t._watchers=[];var e=t.$options;e.props&&Tt(t,e.props),e.methods&&Pt(t,e.methods),e.data?Mt(t):A(t._data={},!0),e.computed&&Nt(t,e.computed),e.watch&&Lt(t,e.watch)}function Tt(t,e){var n=t.$options.propsData||{},r=t.$options._propKeys=Object.keys(e),i=!t.$parent;Di.shouldConvert=i;for(var o=function(i){var o=r[i];S(t,o,U(o,e,n,t))},a=0;a-1:t.test(e)}function Zt(t,e){for(var n in t){var r=t[n];if(r){var i=Kt(r.componentOptions);i&&!e(i)&&(Yt(r),t[n]=null)}}}function Yt(t){t&&(t.componentInstance._inactive||Ct(t.componentInstance,"deactivated"),t.componentInstance.$destroy())}function Qt(t){var e={};e.get=function(){return mi},Object.defineProperty(t,"config",e),t.util=Hi,t.set=E,t.delete=j,t.nextTick=Si,t.options=Object.create(null),mi._assetTypes.forEach(function(e){t.options[e+"s"]=Object.create(null)}),t.options._base=t,f(t.options.components,lo),zt(t),Jt(t),qt(t),Gt(t)}function Xt(t){for(var e=t.data,n=t,r=t;r.componentInstance;)r=r.componentInstance._vnode,r.data&&(e=te(r.data,e));for(;n=n.parent;)n.data&&(e=te(e,n.data));return ee(e)}function te(t,e){return{staticClass:ne(t.staticClass,e.staticClass),class:t.class?[t.class,e.class]:e.class}}function ee(t){var e=t.class,n=t.staticClass;return n||e?ne(n,re(e)):""}function ne(t,e){return t?e?t+" "+e:t:e||""}function re(t){var e="";if(!t)return e;if("string"==typeof t)return t;if(Array.isArray(t)){for(var n,r=0,i=t.length;r-1?Ao[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:Ao[t]=/HTMLUnknownElement/.test(e.toString())}function ae(t){if("string"==typeof t){if(t=document.querySelector(t),!t)return document.createElement("div")}return t}function se(t,e){var n=document.createElement(t);return"select"!==t?n:(e.data&&e.data.attrs&&"multiple"in e.data.attrs&&n.setAttribute("multiple","multiple"),n)}function ce(t,e){return document.createElementNS(xo[t],e)}function ue(t){return document.createTextNode(t)}function le(t){return document.createComment(t)}function fe(t,e,n){t.insertBefore(e,n)}function pe(t,e){t.removeChild(e)}function de(t,e){t.appendChild(e)}function ve(t){return t.parentNode}function he(t){return t.nextSibling}function me(t){return t.tagName}function ge(t,e){t.textContent=e}function ye(t,e,n){t.setAttribute(e,n)}function _e(t,e){var n=t.data.ref;if(n){var r=t.context,i=t.componentInstance||t.elm,a=r.$refs;e?Array.isArray(a[n])?o(a[n],i):a[n]===i&&(a[n]=void 0):t.data.refInFor?Array.isArray(a[n])&&a[n].indexOf(i)<0?a[n].push(i):a[n]=[i]:a[n]=i}}function be(t){return null==t}function we(t){return null!=t}function xe(t,e){return t.key===e.key&&t.tag===e.tag&&t.isComment===e.isComment&&!t.data==!e.data}function $e(t,e,n){var r,i,o={};for(r=e;r<=n;++r)i=t[r].key,we(i)&&(o[i]=r);return o}function Ce(t){function e(t){return new Bi(A.tagName(t).toLowerCase(),{},[],void 0,t)}function n(t,e){function n(){0===--n.listeners&&r(t)}return n.listeners=e,n}function r(t){var e=A.parentNode(t);e&&A.removeChild(e,t)}function o(t,e,n,r,i){if(t.isRootInsert=!i,!a(t,e,n,r)){var o=t.data,s=t.children,c=t.tag;we(c)?(t.elm=t.ns?A.createElementNS(t.ns,c):A.createElement(c,t),v(t),f(t,s,e),we(o)&&d(t,e),l(n,t.elm,r)):t.isComment?(t.elm=A.createComment(t.text),l(n,t.elm,r)):(t.elm=A.createTextNode(t.text),l(n,t.elm,r))}}function a(t,e,n,r){var i=t.data;if(we(i)){var o=we(t.componentInstance)&&i.keepAlive;if(we(i=i.hook)&&we(i=i.init)&&i(t,!1,n,r),we(t.componentInstance))return c(t,e),o&&u(t,e,n,r),!0}}function c(t,e){t.data.pendingInsert&&e.push.apply(e,t.data.pendingInsert),t.elm=t.componentInstance.$el,p(t)?(d(t,e),v(t)):(_e(t),e.push(t))}function u(t,e,n,r){for(var i,o=t;o.componentInstance;)if(o=o.componentInstance._vnode,we(i=o.data)&&we(i=i.transition)){for(i=0;ip?(u=be(n[m+1])?null:n[m+1].elm,h(t,u,n,f,m,r)):f>m&&g(t,e,l,p)}function b(t,e,n,r){if(t!==e){if(e.isStatic&&t.isStatic&&e.key===t.key&&(e.isCloned||e.isOnce))return e.elm=t.elm,void(e.componentInstance=t.componentInstance);var i,o=e.data,a=we(o);a&&we(i=o.hook)&&we(i=i.prepatch)&&i(t,e);var s=e.elm=t.elm,c=t.children,u=e.children;if(a&&p(e)){for(i=0;i-1?e.split(/\s+/).forEach(function(e){return t.classList.add(e)}):t.classList.add(e);else{var n=" "+t.getAttribute("class")+" ";n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function Je(t,e){if(e&&e.trim())if(t.classList)e.indexOf(" ")>-1?e.split(/\s+/).forEach(function(e){return t.classList.remove(e)}):t.classList.remove(e);else{for(var n=" "+t.getAttribute("class")+" ",r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");t.setAttribute("class",n.trim())}}function qe(t){Xo(function(){Xo(t)})}function Ge(t,e){(t._transitionClasses||(t._transitionClasses=[])).push(e),ze(t,e)}function Ke(t,e){t._transitionClasses&&o(t._transitionClasses,e),Je(t,e)}function We(t,e,n){var r=Ze(t,e),i=r.type,o=r.timeout,a=r.propCount;if(!i)return n();var s=i===Go?Zo:Qo,c=0,u=function(){t.removeEventListener(s,l),n()},l=function(e){e.target===t&&++c>=a&&u()};setTimeout(function(){c0&&(n=Go,l=a,f=o.length):e===Ko?u>0&&(n=Ko,l=u,f=c.length):(l=Math.max(a,u),n=l>0?a>u?Go:Ko:null,f=n?n===Go?o.length:c.length:0);var p=n===Go&&ta.test(r[Wo+"Property"]);return{type:n,timeout:l,propCount:f,hasTransform:p}}function Ye(t,e){for(;t.length1,M=n._enterCb=nn(function(){j&&(Ke(n,k),Ke(n,C)),M.cancelled?(j&&Ke(n,$),E&&E(n)):S&&S(n),n._enterCb=null});t.data.show||it(t.data.hook||(t.data.hook={}),"insert",function(){var e=n.parentNode,r=e&&e._pending&&e._pending[t.key];r&&r.tag===t.tag&&r.elm._leaveCb&&r.elm._leaveCb(),A&&A(n,M)},"transition-insert"),O&&O(n),j&&(Ge(n,$),Ge(n,C),qe(function(){Ge(n,k),Ke(n,$),M.cancelled||T||We(n,o,M)})),t.data.show&&(e&&e(),A&&A(n,M)),j||T||M()}}}function tn(t,e){function n(){g.cancelled||(t.data.show||((r.parentNode._pending||(r.parentNode._pending={}))[t.key]=t),l&&l(r),h&&(Ge(r,s),Ge(r,u),qe(function(){Ge(r,c),Ke(r,s),g.cancelled||m||We(r,a,g)})),f&&f(r,g),h||m||g())}var r=t.elm;r._enterCb&&(r._enterCb.cancelled=!0,r._enterCb());var i=en(t.data.transition);if(!i)return e();if(!r._leaveCb&&1===r.nodeType){var o=i.css,a=i.type,s=i.leaveClass,c=i.leaveToClass,u=i.leaveActiveClass,l=i.beforeLeave,f=i.leave,p=i.afterLeave,d=i.leaveCancelled,v=i.delayLeave,h=o!==!1&&!xi,m=f&&(f._length||f.length)>1,g=r._leaveCb=nn(function(){r.parentNode&&r.parentNode._pending&&(r.parentNode._pending[t.key]=null),h&&(Ke(r,c),Ke(r,u)),g.cancelled?(h&&Ke(r,s),d&&d(r)):(e(),p&&p(r)),r._leaveCb=null});v?v(n):n()}}function en(t){if(t){if("object"==typeof t){var e={};return t.css!==!1&&f(e,ea(t.name||"v")),f(e,t),e}return"string"==typeof t?ea(t):void 0}}function nn(t){var e=!1;return function(){e||(e=!0,t())}}function rn(t,e){e.data.show||Xe(e)}function on(t,e,n){var r=e.value,i=t.multiple;if(!i||Array.isArray(r)){for(var o,a,s=0,c=t.options.length;s-1,a.selected!==o&&(a.selected=o);else if(g(sn(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));i||(t.selectedIndex=-1)}}function an(t,e){for(var n=0,r=e.length;n',n.innerHTML.indexOf(e)>0}function wn(t){return va=va||document.createElement("div"),va.innerHTML=t,va.textContent}function xn(t,e){return e&&(t=t.replace(ss,"\n")),t.replace(os,"<").replace(as,">").replace(cs,"&").replace(us,'"')}function $n(t,e){function n(e){f+=e,t=t.substring(e)}function r(){var e=t.match(ka);if(e){var r={tagName:e[1],attrs:[],start:f};n(e[0].length);for(var i,o;!(i=t.match(Oa))&&(o=t.match(xa));)n(o[0].length),r.attrs.push(o);if(i)return r.unarySlash=i[1],n(i[0].length),r.end=f,r}}function i(t){var n=t.tagName,r=t.unarySlash;u&&("p"===s&&ya(n)&&o(s),ga(n)&&s===n&&o(n));for(var i=l(n)||"html"===n&&"head"===s||!!r,a=t.attrs.length,f=new Array(a),p=0;p=0&&c[i].lowerCasedTag!==o;i--);else i=0;if(i>=0){for(var a=c.length-1;a>=i;a--)e.end&&e.end(c[a].tag,n,r);c.length=i,s=i&&c[i-1].tag}else"br"===o?e.start&&e.start(t,[],!0,n,r):"p"===o&&(e.start&&e.start(t,[],!1,n,r),e.end&&e.end(t,n,r))}for(var a,s,c=[],u=e.expectHTML,l=e.isUnaryTag||vi,f=0;t;){if(a=t,s&&rs(s)){var p=s.toLowerCase(),d=is[p]||(is[p]=new RegExp("([\\s\\S]*?)("+p+"[^>]*>)","i")),v=0,h=t.replace(d,function(t,n,r){return v=r.length,"script"!==p&&"style"!==p&&"noscript"!==p&&(n=n.replace(//g,"$1").replace(//g,"$1")),e.chars&&e.chars(n),""});f+=t.length-h.length,t=h,o(p,f-v,f)}else{var m=t.indexOf("<");if(0===m){if(Ea.test(t)){var g=t.indexOf("-->");if(g>=0){n(g+3);continue}}if(ja.test(t)){var y=t.indexOf("]>");if(y>=0){n(y+2);continue}}var _=t.match(Sa);if(_){n(_[0].length);continue}var b=t.match(Aa);if(b){var w=f;n(b[0].length),o(b[1],w,f);continue}var x=r();if(x){i(x);continue}}var $=void 0,C=void 0,k=void 0;if(m>0){for(C=t.slice(m);!(Aa.test(C)||ka.test(C)||Ea.test(C)||ja.test(C)||(k=C.indexOf("<",1),k<0));)m+=k,C=t.slice(m);$=t.substring(0,m),n(m)}m<0&&($=t,t=""),e.chars&&$&&e.chars($)}if(t===a&&e.chars){e.chars(t);break}}o()}function Cn(t){function e(){(a||(a=[])).push(t.slice(v,i).trim()),v=i+1}var n,r,i,o,a,s=!1,c=!1,u=!1,l=!1,f=0,p=0,d=0,v=0;for(i=0;i=0&&(m=t.charAt(h)," "===m);h--);m&&/[\w$]/.test(m)||(l=!0)}}else void 0===o?(v=i+1,o=t.slice(0,i).trim()):e();if(void 0===o?o=t.slice(0,i).trim():0!==v&&e(),a)for(i=0;ia&&o.push(JSON.stringify(t.slice(a,i)));var s=Cn(r[1].trim());o.push("_s("+s+")"),a=i+r[0].length}return a=Ma}function Rn(t){return 34===t||39===t}function Un(t){var e=1;for(La=Pa;!Dn();)if(t=Ln(),Rn(t))Fn(t);else if(91===t&&e++,93===t&&e--,0===e){Da=Pa;break}}function Fn(t){for(var e=t;!Dn()&&(t=Ln(),t!==e););}function Hn(t,e){Ra=e.warn||An,Ua=e.getTagNamespace||vi,Fa=e.mustUseProp||vi,Ha=e.isPreTag||vi,Ba=Sn(e.modules,"preTransformNode"),Va=Sn(e.modules,"transformNode"),za=Sn(e.modules,"postTransformNode"),Ja=e.delimiters;var n,r,i=[],o=e.preserveWhitespace!==!1,a=!1,s=!1;return $n(t,{expectHTML:e.expectHTML,isUnaryTag:e.isUnaryTag,shouldDecodeNewlines:e.shouldDecodeNewlines,start:function(t,o,c){function u(t){}var l=r&&r.ns||Ua(t);wi&&"svg"===l&&(o=or(o));var f={type:1,tag:t,attrsList:o,attrsMap:rr(o),parent:r,children:[]};l&&(f.ns=l),ir(f)&&!Oi()&&(f.forbidden=!0);for(var p=0;p-1"+("true"===o?":("+e+")":":_q("+e+","+o+")")),Mn(t,"click","var $$a="+e+",$$el=$event.target,$$c=$$el.checked?("+o+"):("+a+");if(Array.isArray($$a)){var $$v="+(r?"_n("+i+")":i)+",$$i=_i($$a,$$v);if($$c){$$i<0&&("+e+"=$$a.concat($$v))}else{$$i>-1&&("+e+"=$$a.slice(0,$$i).concat($$a.slice($$i+1)))}}else{"+e+"=$$c}",null,!0)}function Gr(t,e,n){var r=n&&n.number,i=Nn(t,"value")||"null";i=r?"_n("+i+")":i,En(t,"checked","_q("+e+","+i+")"),Mn(t,"click",Zr(e,i),null,!0)}function Kr(t,e,n){var r=t.attrsMap.type,i=n||{},o=i.lazy,a=i.number,s=i.trim,c=o||wi&&"range"===r?"change":"input",u=!o&&"range"!==r,l="input"===t.tag||"textarea"===t.tag,f=l?"$event.target.value"+(s?".trim()":""):s?"(typeof $event === 'string' ? $event.trim() : $event)":"$event";f=a||"number"===r?"_n("+f+")":f;var p=Zr(e,f);l&&u&&(p="if($event.target.composing)return;"+p),En(t,"value",l?"_s("+e+")":"("+e+")"),Mn(t,c,p,null,!0),(s||a||"number"===r)&&Mn(t,"blur","$forceUpdate()")}function Wr(t,e,n){var r=n&&n.number,i='Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = "_value" in o ? o._value : o.value;return '+(r?"_n(val)":"val")+"})"+(null==t.attrsMap.multiple?"[0]":""),o=Zr(e,i);Mn(t,"change",o,null,!0)}function Zr(t,e){var n=Pn(t);return null===n.idx?t+"="+e:"var $$exp = "+n.exp+", $$idx = "+n.idx+";if (!Array.isArray($$exp)){"+t+"="+e+"}else{$$exp.splice($$idx, 1, "+e+")}"}function Yr(t,e){e.value&&En(t,"textContent","_s("+e.value+")")}function Qr(t,e){e.value&&En(t,"innerHTML","_s("+e.value+")")}function Xr(t,e){return e=e?f(f({},Is),e):Is,Fr(t,e)}function ti(t,e,n){var r=(e&&e.warn||ji,e&&e.delimiters?String(e.delimiters)+t:t);if(Ns[r])return Ns[r];var i={},o=Xr(t,e);i.render=ei(o.render);var a=o.staticRenderFns.length;i.staticRenderFns=new Array(a);for(var s=0;s0,$i=bi&&bi.indexOf("edge/")>0,Ci=bi&&bi.indexOf("android")>0,ki=bi&&/iphone|ipad|ipod|ios/.test(bi),Oi=function(){return void 0===ri&&(ri=!_i&&"undefined"!=typeof e&&"server"===e.process.env.VUE_ENV),ri},Ai=_i&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__,Si=function(){function t(){r=!1;var t=n.slice(0);n.length=0;for(var e=0;e1&&(e[n[0].trim()]=n[1].trim())}}),e}),Fo=/^--/,Ho=/\s*!important$/,Bo=function(t,e,n){Fo.test(e)?t.style.setProperty(e,n):Ho.test(n)?t.style.setProperty(e,n.replace(Ho,""),"important"):t.style[zo(e)]=n},Vo=["Webkit","Moz","ms"],zo=c(function(t){if(po=po||document.createElement("div"),t=ci(t),"filter"!==t&&t in po.style)return t;for(var e=t.charAt(0).toUpperCase()+t.slice(1),n=0;n\/=]+)/,ba=/(?:=)/,wa=[/"([^"]*)"+/.source,/'([^']*)'+/.source,/([^\s"'=<>`]+)/.source],xa=new RegExp("^\\s*"+_a.source+"(?:\\s*("+ba.source+")\\s*(?:"+wa.join("|")+"))?"),$a="[a-zA-Z_][\\w\\-\\.]*",Ca="((?:"+$a+"\\:)?"+$a+")",ka=new RegExp("^<"+Ca),Oa=/^\s*(\/?)>/,Aa=new RegExp("^<\\/"+Ca+"[^>]*>"),Sa=/^]+>/i,Ea=/^
11 |