├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── LICENSE ├── 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 ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── docs ├── index.html └── static │ ├── css │ └── app.f39db2f68b1cdbf6515263acc3a4d9a3.css │ └── js │ ├── app.b517d149c346ba201c8a.js │ ├── app.b517d149c346ba201c8a.js.map │ ├── manifest.706b9ac0cc4cf54c13df.js │ ├── manifest.706b9ac0cc4cf54c13df.js.map │ ├── vendor.39791b770e61bba0f787.js │ └── vendor.39791b770e61bba0f787.js.map ├── index.html ├── package.json ├── src ├── App.vue ├── assets │ ├── example.png │ └── logo.png ├── components │ ├── Hello.vue │ └── HelloWorld.vue ├── heatmap.js └── main.js ├── static └── .gitkeep └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-runtime"], 12 | "env": { 13 | "test": { 14 | "presets": ["env", "stage-2"], 15 | "plugins": ["istanbul"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.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 | // https://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 | extends: 'airbnb-base', 13 | // required to lint *.vue files 14 | plugins: [ 15 | 'html' 16 | ], 17 | // check if imports actually resolve 18 | 'settings': { 19 | 'import/resolver': { 20 | 'webpack': { 21 | 'config': 'build/webpack.base.conf.js' 22 | } 23 | } 24 | }, 25 | // add your custom rules here 26 | 'rules': { 27 | // don't require .vue extension when importing 28 | 'import/extensions': ['error', 'always', { 29 | 'js': 'never', 30 | 'vue': 'never' 31 | }], 32 | // allow optionalDependencies 33 | 'import/no-extraneous-dependencies': ['error', { 34 | 'optionalDependencies': ['test/unit/index.js'] 35 | }], 36 | // allow debugger during development 37 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | *.suo 12 | *.ntvs* 13 | *.njsproj 14 | *.sln 15 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserslist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Brock Reece 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![example](src/assets/example.png) 2 | 3 | # vue-heatmapjs 4 | [![npm version](https://badge.fury.io/js/vue-heatmapjs.svg)](https://badge.fury.io/js/vue-heatmapjs) 5 | 6 | 7 | > A vue directive for collecting and displaying user activity on a component 8 | 9 | ## [Demo](https://vue-heatmapjs.netlify.com) 10 | ## Install 11 | You can use NPM or Yarn to add this plugin to your project 12 | ```bash 13 | npm install vue-heatmapjs 14 | # or 15 | yarn add vue-heatmapjs 16 | ``` 17 | 18 | ## Usage 19 | You need to install this plugin in you main.js 20 | 21 | ```js 22 | // main.js 23 | 24 | import Vue from 'vue' 25 | import heatmap from 'vue-heatmapjs' 26 | 27 | Vue.use(heatmap) 28 | 29 | ``` 30 | ### v-heatmap 31 | And then you can add the `v-heatmap` directive to the dom elements you want to track. 32 | 33 | ```html 34 | 35 |
36 | ... 37 |
38 | ``` 39 | 40 | ### v-scrollmap 41 | You can use the `v-scrollmap` directive to collect scroll position data from your application 42 | 43 | ```html 44 | 45 |
46 | ... 47 |
48 | ``` 49 | 50 | ### Toggle heatmap 51 | You can toggle the heatmaps on and off by passing an expression into the directive, the example below will produce something similar to the image at the top of these docs 52 | 53 | ```html 54 | 60 | 61 | 70 | ``` 71 | 72 | ### Listen for events 73 | **Streams** 74 | 75 | You can pass in an Observable into the plugin options and subscribe to events captured for the heatmaps. 76 | 77 | ```js 78 | // main.js 79 | import { Subject } from 'rxjs'; 80 | 81 | const stream = new Subject(); 82 | Vue.use(Vueheatmap, { 83 | stream, 84 | }); 85 | 86 | stream.subscribe(console.log); 87 | ``` 88 | 89 | 90 | **Callback** 91 | 92 | You can pass an afterAdd method through with the plugin options, this will allow you to access and process the events captured for the heatmap 93 | 94 | ```js 95 | // main.js 96 | 97 | Vue.use(heatmap, { 98 | afterAdd(data) { 99 | console.log(data) 100 | // you can fire this back to your analytics server 101 | }, 102 | }) 103 | ``` 104 | 105 | ### Pause collection 106 | You can pass an RXJS Subject through with the plugin options that will allow you to toggle whether your directives collect data or not 107 | 108 | ```js 109 | //main.js 110 | export const pauser = new Subject(); 111 | 112 | Vue.config.productionTip = false; 113 | Vue.use(Vueheatmap, { 114 | pauser, 115 | }); 116 | ``` 117 | 118 | ```js 119 | // Pause data collection 120 | pauser.next(true); 121 | // Resume data collection 122 | pauser.next(false); 123 | ``` 124 | 125 | ### Preload heatmap 126 | Once you have captured heatmap data and persisted the data somewhere you will probably need a way of loading this data back in to your heatmap. 127 | 128 | You can pass in an array of heatmap events using the heatmap preload plugin option 129 | 130 | ```js 131 | //main.js 132 | Vue.use(Vueheatmap, { 133 | heatmapPreload: [{ x: 10, y: 10, value: 100 }], 134 | }); 135 | ``` 136 | 137 | The plugin can also handle a Promise 138 | ```js 139 | //main.js 140 | Vue.use(Vueheatmap, { 141 | heatmapPreload: fetch('http://api.example.com').then(response => response.json()), 142 | }); 143 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | process.env.NODE_ENV = 'production' 5 | 6 | const ora = require('ora') 7 | const rm = require('rimraf') 8 | const path = require('path') 9 | const chalk = require('chalk') 10 | const webpack = require('webpack') 11 | const config = require('../config') 12 | const webpackConfig = require('./webpack.prod.conf') 13 | 14 | const spinner = ora('building for production...') 15 | spinner.start() 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err 19 | webpack(webpackConfig, function (err, stats) { 20 | spinner.stop() 21 | if (err) throw err 22 | process.stdout.write(stats.toString({ 23 | colors: true, 24 | modules: false, 25 | children: false, 26 | chunks: false, 27 | chunkModules: false 28 | }) + '\n\n') 29 | 30 | if (stats.hasErrors()) { 31 | console.log(chalk.red(' Build failed with errors.\n')) 32 | process.exit(1) 33 | } 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 | }) 42 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const chalk = require('chalk') 3 | const semver = require('semver') 4 | const packageConfig = require('../package.json') 5 | const shell = require('shelljs') 6 | function exec (cmd) { 7 | return require('child_process').execSync(cmd).toString().trim() 8 | } 9 | 10 | const versionRequirements = [ 11 | { 12 | name: 'node', 13 | currentVersion: semver.clean(process.version), 14 | versionRequirement: packageConfig.engines.node 15 | } 16 | ] 17 | 18 | if (shell.which('npm')) { 19 | versionRequirements.push({ 20 | name: 'npm', 21 | currentVersion: exec('npm --version'), 22 | versionRequirement: packageConfig.engines.npm 23 | }) 24 | } 25 | 26 | module.exports = function () { 27 | const warnings = [] 28 | for (let i = 0; i < versionRequirements.length; i++) { 29 | const mod = versionRequirements[i] 30 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 31 | warnings.push(mod.name + ': ' + 32 | chalk.red(mod.currentVersion) + ' should be ' + 33 | chalk.green(mod.versionRequirement) 34 | ) 35 | } 36 | } 37 | 38 | if (warnings.length) { 39 | console.log('') 40 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 41 | console.log() 42 | for (let i = 0; i < warnings.length; i++) { 43 | const warning = warnings[i] 44 | console.log(' ' + warning) 45 | } 46 | console.log() 47 | process.exit(1) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 'use strict' 3 | require('eventsource-polyfill') 4 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 5 | 6 | hotClient.subscribe(function (event) { 7 | if (event.action === 'reload') { 8 | window.location.reload() 9 | } 10 | }) 11 | -------------------------------------------------------------------------------- /build/dev-server.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | const config = require('../config') 5 | if (!process.env.NODE_ENV) { 6 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) 7 | } 8 | 9 | const opn = require('opn') 10 | const path = require('path') 11 | const express = require('express') 12 | const webpack = require('webpack') 13 | const proxyMiddleware = require('http-proxy-middleware') 14 | const webpackConfig = require('./webpack.dev.conf') 15 | 16 | // default port where dev server listens for incoming traffic 17 | const port = process.env.PORT || config.dev.port 18 | // automatically open browser, if not set will be false 19 | const autoOpenBrowser = !!config.dev.autoOpenBrowser 20 | // Define HTTP proxies to your custom API backend 21 | // https://github.com/chimurai/http-proxy-middleware 22 | const proxyTable = config.dev.proxyTable 23 | 24 | const app = express() 25 | const compiler = webpack(webpackConfig) 26 | 27 | const devMiddleware = require('webpack-dev-middleware')(compiler, { 28 | publicPath: webpackConfig.output.publicPath, 29 | quiet: true 30 | }) 31 | 32 | const hotMiddleware = require('webpack-hot-middleware')(compiler, { 33 | log: false, 34 | heartbeat: 2000 35 | }) 36 | // force page reload when html-webpack-plugin template changes 37 | // currently disabled until this is resolved: 38 | // https://github.com/jantimon/html-webpack-plugin/issues/680 39 | // compiler.plugin('compilation', function (compilation) { 40 | // compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 41 | // hotMiddleware.publish({ action: 'reload' }) 42 | // cb() 43 | // }) 44 | // }) 45 | 46 | // enable hot-reload and state-preserving 47 | // compilation error display 48 | app.use(hotMiddleware) 49 | 50 | // proxy api requests 51 | Object.keys(proxyTable).forEach(function (context) { 52 | let options = proxyTable[context] 53 | if (typeof options === 'string') { 54 | options = { target: options } 55 | } 56 | app.use(proxyMiddleware(options.filter || context, options)) 57 | }) 58 | 59 | // handle fallback for HTML5 history API 60 | app.use(require('connect-history-api-fallback')()) 61 | 62 | // serve webpack bundle output 63 | app.use(devMiddleware) 64 | 65 | // serve pure static assets 66 | const staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 67 | app.use(staticPath, express.static('./static')) 68 | 69 | const uri = 'http://localhost:' + port 70 | 71 | var _resolve 72 | var _reject 73 | var readyPromise = new Promise((resolve, reject) => { 74 | _resolve = resolve 75 | _reject = reject 76 | }) 77 | 78 | var server 79 | var portfinder = require('portfinder') 80 | portfinder.basePort = port 81 | 82 | console.log('> Starting dev server...') 83 | devMiddleware.waitUntilValid(() => { 84 | portfinder.getPort((err, port) => { 85 | if (err) { 86 | _reject(err) 87 | } 88 | process.env.PORT = port 89 | var uri = 'http://localhost:' + port 90 | console.log('> Listening at ' + uri + '\n') 91 | // when env is testing, don't need open it 92 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 93 | opn(uri) 94 | } 95 | server = app.listen(port) 96 | _resolve() 97 | }) 98 | }) 99 | 100 | module.exports = { 101 | ready: readyPromise, 102 | close: () => { 103 | server.close() 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const config = require('../config') 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | 6 | exports.assetsPath = function (_path) { 7 | const assetsSubDirectory = process.env.NODE_ENV === 'production' 8 | ? config.build.assetsSubDirectory 9 | : config.dev.assetsSubDirectory 10 | return path.posix.join(assetsSubDirectory, _path) 11 | } 12 | 13 | exports.cssLoaders = function (options) { 14 | options = options || {} 15 | 16 | const cssLoader = { 17 | loader: 'css-loader', 18 | options: { 19 | minimize: process.env.NODE_ENV === 'production', 20 | sourceMap: options.sourceMap 21 | } 22 | } 23 | 24 | // generate loader string to be used with extract text plugin 25 | function generateLoaders (loader, loaderOptions) { 26 | const loaders = [cssLoader] 27 | if (loader) { 28 | loaders.push({ 29 | loader: loader + '-loader', 30 | options: Object.assign({}, loaderOptions, { 31 | sourceMap: options.sourceMap 32 | }) 33 | }) 34 | } 35 | 36 | // Extract CSS when that option is specified 37 | // (which is the case during production build) 38 | if (options.extract) { 39 | return ExtractTextPlugin.extract({ 40 | use: loaders, 41 | fallback: 'vue-style-loader' 42 | }) 43 | } else { 44 | return ['vue-style-loader'].concat(loaders) 45 | } 46 | } 47 | 48 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 49 | return { 50 | css: generateLoaders(), 51 | postcss: generateLoaders(), 52 | less: generateLoaders('less'), 53 | sass: generateLoaders('sass', { indentedSyntax: true }), 54 | scss: generateLoaders('sass'), 55 | stylus: generateLoaders('stylus'), 56 | styl: generateLoaders('stylus') 57 | } 58 | } 59 | 60 | // Generate loaders for standalone style files (outside of .vue) 61 | exports.styleLoaders = function (options) { 62 | const output = [] 63 | const loaders = exports.cssLoaders(options) 64 | for (const extension in loaders) { 65 | const loader = loaders[extension] 66 | output.push({ 67 | test: new RegExp('\\.' + extension + '$'), 68 | use: loader 69 | }) 70 | } 71 | return output 72 | } 73 | -------------------------------------------------------------------------------- /build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('../config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | 6 | module.exports = { 7 | loaders: utils.cssLoaders({ 8 | sourceMap: isProduction 9 | ? config.build.productionSourceMap 10 | : config.dev.cssSourceMap, 11 | extract: isProduction 12 | }), 13 | transformToRequire: { 14 | video: 'src', 15 | source: 'src', 16 | img: 'src', 17 | image: 'xlink:href' 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const config = require('../config') 5 | const vueLoaderConfig = require('./vue-loader.conf') 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 | alias: { 25 | 'vue$': 'vue/dist/vue.esm.js', 26 | '@': resolve('src'), 27 | } 28 | }, 29 | module: { 30 | rules: [ 31 | { 32 | test: /\.(js|vue)$/, 33 | loader: 'eslint-loader', 34 | enforce: 'pre', 35 | include: [resolve('src'), resolve('test')], 36 | options: { 37 | formatter: require('eslint-friendly-formatter') 38 | } 39 | }, 40 | { 41 | test: /\.vue$/, 42 | loader: 'vue-loader', 43 | options: vueLoaderConfig 44 | }, 45 | { 46 | test: /\.js$/, 47 | loader: 'babel-loader', 48 | include: [resolve('src'), resolve('test')] 49 | }, 50 | { 51 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 52 | loader: 'url-loader', 53 | options: { 54 | limit: 10000, 55 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 56 | } 57 | }, 58 | { 59 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 60 | loader: 'url-loader', 61 | options: { 62 | limit: 10000, 63 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 64 | } 65 | }, 66 | { 67 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 68 | loader: 'url-loader', 69 | options: { 70 | limit: 10000, 71 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 72 | } 73 | } 74 | ] 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const webpack = require('webpack') 4 | const config = require('../config') 5 | const merge = require('webpack-merge') 6 | const baseWebpackConfig = require('./webpack.base.conf') 7 | const HtmlWebpackPlugin = require('html-webpack-plugin') 8 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 9 | 10 | // add hot-reload related code to entry chunks 11 | Object.keys(baseWebpackConfig.entry).forEach(function (name) { 12 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 13 | }) 14 | 15 | module.exports = merge(baseWebpackConfig, { 16 | module: { 17 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) 18 | }, 19 | // cheap-module-eval-source-map is faster for development 20 | devtool: '#cheap-module-eval-source-map', 21 | plugins: [ 22 | new webpack.DefinePlugin({ 23 | 'process.env': config.dev.env 24 | }), 25 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 26 | new webpack.HotModuleReplacementPlugin(), 27 | new webpack.NoEmitOnErrorsPlugin(), 28 | // https://github.com/ampedandwired/html-webpack-plugin 29 | new HtmlWebpackPlugin({ 30 | filename: 'index.html', 31 | template: 'index.html', 32 | inject: true 33 | }), 34 | new FriendlyErrorsPlugin() 35 | ] 36 | }) 37 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const webpack = require('webpack') 5 | const config = require('../config') 6 | const merge = require('webpack-merge') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 12 | 13 | const env = config.build.env 14 | 15 | const webpackConfig = merge(baseWebpackConfig, { 16 | module: { 17 | rules: utils.styleLoaders({ 18 | sourceMap: config.build.productionSourceMap, 19 | extract: true 20 | }) 21 | }, 22 | devtool: config.build.productionSourceMap ? '#source-map' : false, 23 | output: { 24 | path: config.build.assetsRoot, 25 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 26 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 27 | }, 28 | plugins: [ 29 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 30 | new webpack.DefinePlugin({ 31 | 'process.env': env 32 | }), 33 | // UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify 34 | new webpack.optimize.UglifyJsPlugin({ 35 | compress: { 36 | warnings: false 37 | }, 38 | sourceMap: true 39 | }), 40 | // extract css into its own file 41 | new ExtractTextPlugin({ 42 | filename: utils.assetsPath('css/[name].[contenthash].css') 43 | }), 44 | // Compress extracted CSS. We are using this plugin so that possible 45 | // duplicated CSS from different components can be deduped. 46 | new OptimizeCSSPlugin({ 47 | cssProcessorOptions: { 48 | safe: true 49 | } 50 | }), 51 | // generate dist index.html with correct asset hash for caching. 52 | // you can customize output by editing /index.html 53 | // see https://github.com/ampedandwired/html-webpack-plugin 54 | new HtmlWebpackPlugin({ 55 | filename: config.build.index, 56 | template: 'index.html', 57 | inject: true, 58 | minify: { 59 | removeComments: true, 60 | collapseWhitespace: true, 61 | removeAttributeQuotes: true 62 | // more options: 63 | // https://github.com/kangax/html-minifier#options-quick-reference 64 | }, 65 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 66 | chunksSortMode: 'dependency' 67 | }), 68 | // keep module.id stable when vender modules does not change 69 | new webpack.HashedModuleIdsPlugin(), 70 | // split vendor js into its own file 71 | new webpack.optimize.CommonsChunkPlugin({ 72 | name: 'vendor', 73 | minChunks: function (module) { 74 | // any required modules inside node_modules are extracted to vendor 75 | return ( 76 | module.resource && 77 | /\.js$/.test(module.resource) && 78 | module.resource.indexOf( 79 | path.join(__dirname, '../node_modules') 80 | ) === 0 81 | ) 82 | } 83 | }), 84 | // extract webpack runtime and module manifest to its own file in order to 85 | // prevent vendor hash from being updated whenever app bundle is updated 86 | new webpack.optimize.CommonsChunkPlugin({ 87 | name: 'manifest', 88 | chunks: ['vendor'] 89 | }), 90 | // copy custom static assets 91 | new CopyWebpackPlugin([ 92 | { 93 | from: path.resolve(__dirname, '../static'), 94 | to: config.build.assetsSubDirectory, 95 | ignore: ['.*'] 96 | } 97 | ]) 98 | ] 99 | }) 100 | 101 | if (config.build.productionGzip) { 102 | const CompressionWebpackPlugin = require('compression-webpack-plugin') 103 | 104 | webpackConfig.plugins.push( 105 | new CompressionWebpackPlugin({ 106 | asset: '[path].gz[query]', 107 | algorithm: 'gzip', 108 | test: new RegExp( 109 | '\\.(' + 110 | config.build.productionGzipExtensions.join('|') + 111 | ')$' 112 | ), 113 | threshold: 10240, 114 | minRatio: 0.8 115 | }) 116 | ) 117 | } 118 | 119 | if (config.build.bundleAnalyzerReport) { 120 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 121 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 122 | } 123 | 124 | module.exports = webpackConfig 125 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict' 3 | // Template version: 1.1.3 4 | // see http://vuejs-templates.github.io/webpack for documentation. 5 | 6 | const path = require('path') 7 | 8 | module.exports = { 9 | build: { 10 | env: require('./prod.env'), 11 | index: path.resolve(__dirname, '../docs/index.html'), 12 | assetsRoot: path.resolve(__dirname, '../docs'), 13 | assetsSubDirectory: 'static', 14 | assetsPublicPath: '', 15 | productionSourceMap: true, 16 | // Gzip off by default as many popular static hosts such as 17 | // Surge or Netlify already gzip all static assets for you. 18 | // Before setting to `true`, make sure to: 19 | // npm install --save-dev compression-webpack-plugin 20 | productionGzip: false, 21 | productionGzipExtensions: ['js', 'css'], 22 | // Run the build command with an extra argument to 23 | // View the bundle analyzer report after build finishes: 24 | // `npm run build --report` 25 | // Set to `true` or `false` to always turn it on or off 26 | bundleAnalyzerReport: process.env.npm_config_report 27 | }, 28 | dev: { 29 | env: require('./dev.env'), 30 | port: process.env.PORT || 8080, 31 | autoOpenBrowser: true, 32 | assetsSubDirectory: 'static', 33 | assetsPublicPath: '/', 34 | proxyTable: {}, 35 | // CSS Sourcemaps off by default because relative paths are "buggy" 36 | // with this option, according to the CSS-Loader README 37 | // (https://github.com/webpack/css-loader#sourcemaps) 38 | // In our experience, they generally work as expected, 39 | // just be aware of this issue when enabling this option. 40 | cssSourceMap: false 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | vue-heatmapjs
-------------------------------------------------------------------------------- /docs/static/css/app.f39db2f68b1cdbf6515263acc3a4d9a3.css: -------------------------------------------------------------------------------- 1 | #app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#2c3e50;margin-top:60px;min-height:900px}h1[data-v-73219722],h2[data-v-73219722]{font-weight:400}ul[data-v-73219722]{list-style-type:none;padding:0}li[data-v-73219722]{display:inline-block;margin:0 10px}a[data-v-73219722]{color:#42b983} -------------------------------------------------------------------------------- /docs/static/js/app.b517d149c346ba201c8a.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([1],{"07PK":function(t,e,a){"use strict";e.a={name:"HelloWorld",data:function(){return{msg:"Welcome to Your Vue.js App"}}}},"7Otq":function(t,e){t.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDE0IDc5LjE1Njc5NywgMjAxNC8wOC8yMC0wOTo1MzowMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTk2QkI4RkE3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTk2QkI4Rjk3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NjU2QTEyNzk3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NjU2QTEyN0E3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5WHowqAAAXNElEQVR42uxda4xd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"},"95Bb":function(t,e){},M93x:function(t,e,a){"use strict";function n(t){a("95Bb")}var r=a("xJD8"),s=a("pjLW"),i=a("VU/8"),c=n,o=i(r.a,s.a,!1,c,null,null);e.a=o.exports},NHnr:function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),a.d(e,"pauser",function(){return o});var n=a("7+uW"),r=a("Gvdl"),s=(a.n(r),a("U48F")),i=a("M93x"),c=new r.Subject,o=new r.Subject;n.a.config.productionTip=!1,n.a.use(s.a,{stream:c,pauser:o,heatmapPreload:[{x:10,y:10,value:100}]}),c.throttleTime(1e3).subscribe(console.log),e.default=new n.a({el:"#app",template:"",components:{App:i.a}})},"Qdj/":function(t,e){},U48F:function(t,e,a){"use strict";var n=a("Xxa5"),r=a.n(n),s=a("//Fk"),i=a.n(s),c=a("exGp"),o=a.n(c),l=a("fZjL"),u=a.n(l),h=a("JkCx"),v=a.n(h),d=a("Gvdl"),p=(a.n(d),!1);window.addEventListener("load",function(){p=!0}),e.a={install:function(t){var e=this,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=void 0,s=function(t,e){return t.value=e,t},c=function(){var t=document.body,e=document.documentElement;return Math.max(t.scrollHeight,t.offsetHeight,e.clientHeight,e.scrollHeight,e.offsetHeight)},l=a.pauser||new d.Subject;t.directive("scrollmap",{inserted:function(t,e){var a=c(),n=document.createElement("canvas"),r=e.arg||50,s=e.value||!0,i=d.Observable.interval(2e3),o=0;document.body.appendChild(n),n.height=a,n.style.height=a+"px",n.width=window.outerWidth,n.style.position="absolute",n.style.left=0,n.style.top=0,n.style.width="100%",n.style.opacity="0.8",n.style.display=s,n.id="scrollMapCanvas",n.style.pointerEvents="none",l.switchMap(function(t){return t?d.Observable.never:i}).map(function(){return window.scrollY}).scan(function(t,e){for(var a=Math.round(e/r)*r,n=Math.round((e+window.innerHeight)/r)*r;n>=a;)t[n]=t[n]||0,t[n]+=1,o=Math.max(t[n],o),n-=r;return t},{0:1}).subscribe(function(t){var e=document.getElementById("scrollMapCanvas");e.height=a;var n=e.getContext("2d"),r=n.createLinearGradient(0,0,0,e.height);r.addColorStop(0,"hsla(0,50%,50%, 1)"),r.addColorStop(1,"hsla(0,50%,50%, 0)"),u()(t).forEach(function(a){r.addColorStop(Math.min(1,a/e.height),"hsla(0,50%,50%, "+t[a]/o+")")}),n.fillStyle=r,n.fillRect(0,0,e.width,e.height)}),l.next(!1)},update:function(t,e){document.getElementById("scrollMapCanvas").style.display=e.value?"inherit":"none"}});var h=function(){var t=o()(r.a.mark(function t(c,o){var u,h,p,m,f;return r.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:if(n=v.a.create({maxOpacity:.6,radius:50,blur:.9,backgroundColor:"rgba(0, 0, 58, 0)",container:c}),!a.heatmapPreload){t.next=7;break}return t.t0=n,t.next=5,i.a.resolve(a.heatmapPreload);case 5:t.t1=t.sent,t.t0.addData.call(t.t0,t.t1);case 7:u=d.Observable.fromEvent(c,"mousemove"),h=d.Observable.fromEvent(c,"touchmove"),p=d.Observable.fromEvent(c,"click"),m=d.Observable.merge(u.map(function(t){return s(t,5)}),h.map(function(t){return s(t,5)}),p.map(function(t){return s(t,10)})),f=l.switchMap(function(t){return t?d.Observable.never:m}),f.debounceTime(10).map(function(t){return{x:t.layerX,y:t.layerY,value:t.value}}).subscribe(function(t){return n.addData(t)}),a.afterAdd&&f.subscribe(a.afterAdd),a.stream&&f.subscribe(function(t){return a.stream.next(t)}),c.querySelector("canvas.heatmap-canvas").style.display=o.value?"inherit":"none",c.querySelector("canvas.heatmap-canvas").style.pointerEvents="none";case 17:case"end":return t.stop()}},t,e)}));return function(e,a){return t.apply(this,arguments)}}();t.directive("heatmap",{inserted:function(){var t=o()(r.a.mark(function t(a,n){return r.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:window.addEventListener("load",function(){h(a,n)}),p&&h(a,n);case 2:case"end":return t.stop()}},t,e)}));return function(e,a){return t.apply(this,arguments)}}(),update:function(t,e){t.querySelector("canvas.heatmap-canvas").style.display=e.value?"inherit":"none"}})}}},f7Ie:function(t,e,a){"use strict";var n=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"hello"},[a("h1",[t._v(t._s(t.msg))]),t._v(" "),a("h2",[t._v("Essential Links")]),t._v(" "),t._m(0),t._v(" "),a("h2",[t._v("Ecosystem")]),t._v(" "),t._m(1)])},r=[function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("ul",[a("li",[a("a",{attrs:{href:"https://vuejs.org",target:"_blank"}},[t._v("Core Docs")])]),t._v(" "),a("li",[a("a",{attrs:{href:"https://forum.vuejs.org",target:"_blank"}},[t._v("Forum")])]),t._v(" "),a("li",[a("a",{attrs:{href:"https://chat.vuejs.org",target:"_blank"}},[t._v("Community Chat")])]),t._v(" "),a("li",[a("a",{attrs:{href:"https://twitter.com/vuejs",target:"_blank"}},[t._v("Twitter")])]),t._v(" "),a("br"),t._v(" "),a("li",[a("a",{attrs:{href:"http://vuejs-templates.github.io/webpack/",target:"_blank"}},[t._v("Docs for This Template")])])])},function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("ul",[a("li",[a("a",{attrs:{href:"http://router.vuejs.org/",target:"_blank"}},[t._v("vue-router")])]),t._v(" "),a("li",[a("a",{attrs:{href:"http://vuex.vuejs.org/",target:"_blank"}},[t._v("vuex")])]),t._v(" "),a("li",[a("a",{attrs:{href:"http://vue-loader.vuejs.org/",target:"_blank"}},[t._v("vue-loader")])]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/vuejs/awesome-vue",target:"_blank"}},[t._v("awesome-vue")])])])}],s={render:n,staticRenderFns:r};e.a=s},gORT:function(t,e,a){"use strict";function n(t){a("Qdj/")}var r=a("07PK"),s=a("f7Ie"),i=a("VU/8"),c=n,o=i(r.a,s.a,!1,c,"data-v-73219722",null);e.a=o.exports},pjLW:function(t,e,a){"use strict";var n=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{directives:[{name:"scrollmap",rawName:"v-scrollmap:100",value:t.showScrollmap,expression:"showScrollmap",arg:"100"}],attrs:{id:"app"}},[n("div",{directives:[{name:"heatmap",rawName:"v-heatmap",value:t.showHeatmap,expression:"showHeatmap"}]},[n("img",{attrs:{src:a("7Otq")}})]),t._v(" "),n("button",{on:{click:function(e){t.showHeatmap=!t.showHeatmap}}},[t._v("Toggle Heatmap")]),t._v(" "),n("button",{on:{click:function(e){t.showScrollmap=!t.showScrollmap}}},[t._v("Toggle Scrollmap")]),t._v(" "),n("button",{on:{click:t.pauseCollection}},[t.paused?n("span",[t._v("Resume Collection")]):n("span",[t._v("Pause Collection")])])])},r=[],s={render:n,staticRenderFns:r};e.a=s},xJD8:function(t,e,a){"use strict";var n=a("Xxa5"),r=a.n(n),s=a("exGp"),i=a.n(s),c=a("gORT"),o=a("NHnr");e.a={name:"app",components:{HelloWorld:c.a},data:function(){return{paused:!1,showScrollmap:!0,showHeatmap:!0}},methods:{pauseCollection:function(){this.paused=!this.paused,o.pauser.next(this.paused)}},mounted:function(){var t=this;return i()(r.a.mark(function e(){return r.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:window.addEventListener("load",function(){o.pauser.next(!1)});case 1:case"end":return t.stop()}},e,t)}))()}}}},["NHnr"]); 2 | //# sourceMappingURL=app.b517d149c346ba201c8a.js.map -------------------------------------------------------------------------------- /docs/static/js/app.b517d149c346ba201c8a.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///static/js/app.b517d149c346ba201c8a.js","webpack:///src/components/HelloWorld.vue","webpack:///./src/assets/logo.png","webpack:///./src/App.vue","webpack:///./src/main.js","webpack:///./src/heatmap.js","webpack:///./src/components/HelloWorld.vue?96f7","webpack:///./src/components/HelloWorld.vue","webpack:///./src/App.vue?d71d","webpack:///src/App.vue"],"names":["webpackJsonp","07PK","module","__webpack_exports__","__webpack_require__","name","data","msg","7Otq","exports","95Bb","M93x","injectStyle","ssrContext","__WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_App_vue__","__WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_55bf0f57_hasScoped_false_transformToRequire_video_src_source_src_img_src_image_xlink_href_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_App_vue__","normalizeComponent","__vue_styles__","Component","NHnr","Object","defineProperty","value","d","pauser","__WEBPACK_IMPORTED_MODULE_0_vue__","__WEBPACK_IMPORTED_MODULE_1_rxjs__","__WEBPACK_IMPORTED_MODULE_2__heatmap__","n","__WEBPACK_IMPORTED_MODULE_3__App__","stream","config","productionTip","use","heatmapPreload","x","y","throttleTime","subscribe","console","log","el","template","components","App","Qdj/","U48F","__WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator__","__WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator___default","__WEBPACK_IMPORTED_MODULE_1_babel_runtime_core_js_promise__","__WEBPACK_IMPORTED_MODULE_1_babel_runtime_core_js_promise___default","__WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_asyncToGenerator__","__WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_asyncToGenerator___default","__WEBPACK_IMPORTED_MODULE_3_babel_runtime_core_js_object_keys__","__WEBPACK_IMPORTED_MODULE_3_babel_runtime_core_js_object_keys___default","__WEBPACK_IMPORTED_MODULE_4_heatmap_js__","__WEBPACK_IMPORTED_MODULE_4_heatmap_js___default","__WEBPACK_IMPORTED_MODULE_5_rxjs__","loaded","window","addEventListener","install","Vue","_this","this","options","arguments","length","undefined","heatmap","addValue","e","getHeight","body","document","html","documentElement","Math","max","scrollHeight","offsetHeight","clientHeight","directive","inserted","binding","height","canvas","createElement","rounding","arg","show","scroll","interval","appendChild","style","width","outerWidth","position","left","top","opacity","display","id","pointerEvents","switchMap","paused","never","map","scrollY","scan","acc","pos","rounded","round","roundedWithHeight","innerHeight","0","positions","c","getElementById","ctx","getContext","myGradient","createLinearGradient","addColorStop","forEach","key","min","fillStyle","fillRect","next","update","loadHeatmap","_ref","a","mark","_callee","move","touch","click","streams","pausable","wrap","_context","prev","create","maxOpacity","radius","blur","backgroundColor","container","t0","resolve","t1","sent","addData","call","fromEvent","merge","debounceTime","layerX","layerY","afterAdd","querySelector","stop","_x2","_x3","apply","_ref2","_callee2","_context2","_x4","_x5","f7Ie","render","_vm","_h","$createElement","_c","_self","staticClass","_v","_s","_m","staticRenderFns","attrs","href","target","esExports","gORT","__WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_HelloWorld_vue__","__WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_73219722_hasScoped_true_transformToRequire_video_src_source_src_img_src_image_xlink_href_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_HelloWorld_vue__","pjLW","directives","rawName","expression","src","on","$event","showHeatmap","showScrollmap","pauseCollection","xJD8","__WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_asyncToGenerator__","__WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_asyncToGenerator___default","__WEBPACK_IMPORTED_MODULE_2__components_HelloWorld__","__WEBPACK_IMPORTED_MODULE_3__main__","HelloWorld","methods","mounted"],"mappings":"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","file":"static/js/app.b517d149c346ba201c8a.js","sourcesContent":["webpackJsonp([1],{\n\n/***/ \"07PK\":\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n/* harmony default export */ __webpack_exports__[\"a\"] = ({\n name: 'HelloWorld',\n data: function data() {\n return {\n msg: 'Welcome to Your Vue.js App'\n };\n }\n});\n\n/***/ }),\n\n/***/ \"7Otq\":\n/***/ (function(module, exports) {\n\nmodule.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDE0IDc5LjE1Njc5NywgMjAxNC8wOC8yMC0wOTo1MzowMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTk2QkI4RkE3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTk2QkI4Rjk3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NjU2QTEyNzk3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NjU2QTEyN0E3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5WHowqAAAXNElEQVR42uxda4xd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\"\n\n/***/ }),\n\n/***/ \"95Bb\":\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n\n/***/ \"M93x\":\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_App_vue__ = __webpack_require__(\"xJD8\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_55bf0f57_hasScoped_false_transformToRequire_video_src_source_src_img_src_image_xlink_href_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_App_vue__ = __webpack_require__(\"pjLW\");\nfunction injectStyle (ssrContext) {\n __webpack_require__(\"95Bb\")\n}\nvar normalizeComponent = __webpack_require__(\"VU/8\")\n/* script */\n\n/* template */\n\n/* template functional */\n var __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_App_vue__[\"a\" /* default */],\n __WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_55bf0f57_hasScoped_false_transformToRequire_video_src_source_src_img_src_image_xlink_href_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_App_vue__[\"a\" /* default */],\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\n/* harmony default export */ __webpack_exports__[\"a\"] = (Component.exports);\n\n\n/***/ }),\n\n/***/ \"NHnr\":\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"pauser\", function() { return pauser; });\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_vue__ = __webpack_require__(\"7+uW\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_rxjs__ = __webpack_require__(\"Gvdl\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_rxjs___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_rxjs__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__heatmap__ = __webpack_require__(\"U48F\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__App__ = __webpack_require__(\"M93x\");\n// The Vue build version to load with the `import` command\n// (runtime-only or standalone) has been set in webpack.base.conf with an alias.\n\n\n\n// import { debounce } from 'lodash';\n\n\nvar stream = new __WEBPACK_IMPORTED_MODULE_1_rxjs__[\"Subject\"]();\nvar pauser = new __WEBPACK_IMPORTED_MODULE_1_rxjs__[\"Subject\"]();\n\n__WEBPACK_IMPORTED_MODULE_0_vue__[\"a\" /* default */].config.productionTip = false;\n__WEBPACK_IMPORTED_MODULE_0_vue__[\"a\" /* default */].use(__WEBPACK_IMPORTED_MODULE_2__heatmap__[\"a\" /* default */], {\n stream: stream,\n pauser: pauser,\n heatmapPreload: [{ x: 10, y: 10, value: 100 }]\n});\n\nstream.throttleTime(1000).subscribe(console.log);\n\n/* eslint-disable no-new */\n/* harmony default export */ __webpack_exports__[\"default\"] = (new __WEBPACK_IMPORTED_MODULE_0_vue__[\"a\" /* default */]({\n el: '#app',\n template: '',\n components: { App: __WEBPACK_IMPORTED_MODULE_3__App__[\"a\" /* default */] }\n}));\n\n/***/ }),\n\n/***/ \"Qdj/\":\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n\n/***/ \"U48F\":\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator__ = __webpack_require__(\"Xxa5\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_core_js_promise__ = __webpack_require__(\"//Fk\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_core_js_promise___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_babel_runtime_core_js_promise__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_asyncToGenerator__ = __webpack_require__(\"exGp\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_asyncToGenerator___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_asyncToGenerator__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_babel_runtime_core_js_object_keys__ = __webpack_require__(\"fZjL\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_babel_runtime_core_js_object_keys___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_babel_runtime_core_js_object_keys__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_heatmap_js__ = __webpack_require__(\"JkCx\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_heatmap_js___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_heatmap_js__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_rxjs__ = __webpack_require__(\"Gvdl\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_rxjs___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_rxjs__);\n\n\n\n\n\n\n\nvar loaded = false;\nwindow.addEventListener('load', function () {\n loaded = true;\n});\n\n/* harmony default export */ __webpack_exports__[\"a\"] = ({\n install: function install(Vue) {\n var _this = this;\n\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n var heatmap = void 0;\n\n var addValue = function addValue(e, value) {\n e.value = value;\n return e;\n };\n\n var getHeight = function getHeight() {\n var body = document.body;\n var html = document.documentElement;\n\n return Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);\n };\n\n var pauser = options.pauser || new __WEBPACK_IMPORTED_MODULE_5_rxjs__[\"Subject\"]();\n\n Vue.directive('scrollmap', {\n inserted: function inserted(el, binding) {\n var height = getHeight();\n var canvas = document.createElement('canvas');\n var rounding = binding.arg || 50;\n var show = binding.value || true;\n var scroll = __WEBPACK_IMPORTED_MODULE_5_rxjs__[\"Observable\"].interval(2000);\n\n var max = 0;\n\n document.body.appendChild(canvas);\n canvas.height = height;\n canvas.style.height = height + 'px';\n canvas.width = window.outerWidth;\n canvas.style.position = 'absolute';\n canvas.style.left = 0;\n canvas.style.top = 0;\n canvas.style.width = '100%';\n canvas.style.opacity = '0.8';\n canvas.style.display = show;\n canvas.id = 'scrollMapCanvas';\n canvas.style.pointerEvents = 'none';\n\n pauser.switchMap(function (paused) {\n return paused ? __WEBPACK_IMPORTED_MODULE_5_rxjs__[\"Observable\"].never : scroll;\n }).map(function () {\n return window.scrollY;\n }).scan(function (acc, pos) {\n var rounded = Math.round(pos / rounding) * rounding;\n var roundedWithHeight = Math.round((pos + window.innerHeight) / rounding) * rounding;\n\n while (roundedWithHeight >= rounded) {\n acc[roundedWithHeight] = acc[roundedWithHeight] || 0;\n acc[roundedWithHeight] += 1;\n max = Math.max(acc[roundedWithHeight], max);\n roundedWithHeight -= rounding;\n }\n\n return acc;\n }, { 0: 1 }).subscribe(function (positions) {\n var c = document.getElementById('scrollMapCanvas');\n c.height = height;\n var ctx = c.getContext('2d');\n var myGradient = ctx.createLinearGradient(0, 0, 0, c.height);\n\n myGradient.addColorStop(0, 'hsla(0,50%,50%, 1)');\n myGradient.addColorStop(1, 'hsla(0,50%,50%, 0)');\n\n __WEBPACK_IMPORTED_MODULE_3_babel_runtime_core_js_object_keys___default()(positions).forEach(function (key) {\n myGradient.addColorStop(Math.min(1, key / c.height), 'hsla(0,50%,50%, ' + positions[key] / max + ')');\n });\n\n ctx.fillStyle = myGradient;\n ctx.fillRect(0, 0, c.width, c.height);\n });\n\n pauser.next(false);\n },\n update: function update(el, binding) {\n document.getElementById('scrollMapCanvas').style.display = binding.value ? 'inherit' : 'none';\n }\n });\n\n var loadHeatmap = function () {\n var _ref = __WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_asyncToGenerator___default()( /*#__PURE__*/__WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator___default.a.mark(function _callee(el, binding) {\n var move, touch, click, streams, pausable;\n return __WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator___default.a.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n heatmap = __WEBPACK_IMPORTED_MODULE_4_heatmap_js___default.a.create({\n maxOpacity: 0.6,\n radius: 50,\n blur: 0.90,\n backgroundColor: 'rgba(0, 0, 58, 0)',\n container: el\n });\n\n if (!options.heatmapPreload) {\n _context.next = 7;\n break;\n }\n\n _context.t0 = heatmap;\n _context.next = 5;\n return __WEBPACK_IMPORTED_MODULE_1_babel_runtime_core_js_promise___default.a.resolve(options.heatmapPreload);\n\n case 5:\n _context.t1 = _context.sent;\n\n _context.t0.addData.call(_context.t0, _context.t1);\n\n case 7:\n move = __WEBPACK_IMPORTED_MODULE_5_rxjs__[\"Observable\"].fromEvent(el, 'mousemove');\n touch = __WEBPACK_IMPORTED_MODULE_5_rxjs__[\"Observable\"].fromEvent(el, 'touchmove');\n click = __WEBPACK_IMPORTED_MODULE_5_rxjs__[\"Observable\"].fromEvent(el, 'click');\n streams = __WEBPACK_IMPORTED_MODULE_5_rxjs__[\"Observable\"].merge(move.map(function (e) {\n return addValue(e, 5);\n }), touch.map(function (e) {\n return addValue(e, 5);\n }), click.map(function (e) {\n return addValue(e, 10);\n }));\n pausable = pauser.switchMap(function (paused) {\n return paused ? __WEBPACK_IMPORTED_MODULE_5_rxjs__[\"Observable\"].never : streams;\n });\n\n\n pausable.debounceTime(10).map(function (e) {\n return {\n x: e.layerX,\n y: e.layerY,\n value: e.value\n };\n }).subscribe(function (e) {\n return heatmap.addData(e);\n });\n\n if (options.afterAdd) {\n pausable.subscribe(options.afterAdd);\n }\n\n if (options.stream) {\n pausable.subscribe(function (e) {\n return options.stream.next(e);\n });\n }\n\n /* eslint-disable no-param-reassign */\n el.querySelector('canvas.heatmap-canvas').style.display = binding.value ? 'inherit' : 'none';\n el.querySelector('canvas.heatmap-canvas').style.pointerEvents = 'none';\n\n case 17:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, _this);\n }));\n\n return function loadHeatmap(_x2, _x3) {\n return _ref.apply(this, arguments);\n };\n }();\n\n Vue.directive('heatmap', {\n inserted: function () {\n var _ref2 = __WEBPACK_IMPORTED_MODULE_2_babel_runtime_helpers_asyncToGenerator___default()( /*#__PURE__*/__WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator___default.a.mark(function _callee2(el, binding) {\n return __WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator___default.a.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n window.addEventListener('load', function () {\n loadHeatmap(el, binding);\n });\n\n if (loaded) {\n loadHeatmap(el, binding);\n }\n\n case 2:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, _this);\n }));\n\n return function inserted(_x4, _x5) {\n return _ref2.apply(this, arguments);\n };\n }(),\n\n update: function update(el, binding) {\n /* eslint-disable no-param-reassign */\n el.querySelector('canvas.heatmap-canvas').style.display = binding.value ? 'inherit' : 'none';\n }\n });\n }\n});\n\n/***/ }),\n\n/***/ \"f7Ie\":\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nvar render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"hello\"},[_c('h1',[_vm._v(_vm._s(_vm.msg))]),_vm._v(\" \"),_c('h2',[_vm._v(\"Essential Links\")]),_vm._v(\" \"),_vm._m(0),_vm._v(\" \"),_c('h2',[_vm._v(\"Ecosystem\")]),_vm._v(\" \"),_vm._m(1)])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('ul',[_c('li',[_c('a',{attrs:{\"href\":\"https://vuejs.org\",\"target\":\"_blank\"}},[_vm._v(\"Core Docs\")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"https://forum.vuejs.org\",\"target\":\"_blank\"}},[_vm._v(\"Forum\")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"https://chat.vuejs.org\",\"target\":\"_blank\"}},[_vm._v(\"Community Chat\")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"https://twitter.com/vuejs\",\"target\":\"_blank\"}},[_vm._v(\"Twitter\")])]),_vm._v(\" \"),_c('br'),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"http://vuejs-templates.github.io/webpack/\",\"target\":\"_blank\"}},[_vm._v(\"Docs for This Template\")])])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('ul',[_c('li',[_c('a',{attrs:{\"href\":\"http://router.vuejs.org/\",\"target\":\"_blank\"}},[_vm._v(\"vue-router\")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"http://vuex.vuejs.org/\",\"target\":\"_blank\"}},[_vm._v(\"vuex\")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"http://vue-loader.vuejs.org/\",\"target\":\"_blank\"}},[_vm._v(\"vue-loader\")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"https://github.com/vuejs/awesome-vue\",\"target\":\"_blank\"}},[_vm._v(\"awesome-vue\")])])])}]\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\n/* harmony default export */ __webpack_exports__[\"a\"] = (esExports);\n\n/***/ }),\n\n/***/ \"gORT\":\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_HelloWorld_vue__ = __webpack_require__(\"07PK\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_73219722_hasScoped_true_transformToRequire_video_src_source_src_img_src_image_xlink_href_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_HelloWorld_vue__ = __webpack_require__(\"f7Ie\");\nfunction injectStyle (ssrContext) {\n __webpack_require__(\"Qdj/\")\n}\nvar normalizeComponent = __webpack_require__(\"VU/8\")\n/* script */\n\n/* template */\n\n/* template functional */\n var __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = \"data-v-73219722\"\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_HelloWorld_vue__[\"a\" /* default */],\n __WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_73219722_hasScoped_true_transformToRequire_video_src_source_src_img_src_image_xlink_href_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_HelloWorld_vue__[\"a\" /* default */],\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\n/* harmony default export */ __webpack_exports__[\"a\"] = (Component.exports);\n\n\n/***/ }),\n\n/***/ \"pjLW\":\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nvar render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{directives:[{name:\"scrollmap\",rawName:\"v-scrollmap:100\",value:(_vm.showScrollmap),expression:\"showScrollmap\",arg:\"100\"}],attrs:{\"id\":\"app\"}},[_c('div',{directives:[{name:\"heatmap\",rawName:\"v-heatmap\",value:(_vm.showHeatmap),expression:\"showHeatmap\"}]},[_c('img',{attrs:{\"src\":__webpack_require__(\"7Otq\")}})]),_vm._v(\" \"),_c('button',{on:{\"click\":function($event){_vm.showHeatmap = !_vm.showHeatmap}}},[_vm._v(\"Toggle Heatmap\")]),_vm._v(\" \"),_c('button',{on:{\"click\":function($event){_vm.showScrollmap = !_vm.showScrollmap}}},[_vm._v(\"Toggle Scrollmap\")]),_vm._v(\" \"),_c('button',{on:{\"click\":_vm.pauseCollection}},[(_vm.paused)?_c('span',[_vm._v(\"Resume Collection\")]):_c('span',[_vm._v(\"Pause Collection\")])])])}\nvar staticRenderFns = []\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\n/* harmony default export */ __webpack_exports__[\"a\"] = (esExports);\n\n/***/ }),\n\n/***/ \"xJD8\":\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator__ = __webpack_require__(\"Xxa5\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_asyncToGenerator__ = __webpack_require__(\"exGp\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_asyncToGenerator___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_asyncToGenerator__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__components_HelloWorld__ = __webpack_require__(\"gORT\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__main__ = __webpack_require__(\"NHnr\");\n\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"a\"] = ({\n name: 'app',\n components: {\n HelloWorld: __WEBPACK_IMPORTED_MODULE_2__components_HelloWorld__[\"a\" /* default */]\n },\n data: function data() {\n return {\n paused: false,\n showScrollmap: true,\n showHeatmap: true\n };\n },\n\n\n methods: {\n pauseCollection: function pauseCollection() {\n this.paused = !this.paused;\n __WEBPACK_IMPORTED_MODULE_3__main__[\"pauser\"].next(this.paused);\n }\n },\n\n mounted: function mounted() {\n var _this = this;\n\n return __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_asyncToGenerator___default()( /*#__PURE__*/__WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator___default.a.mark(function _callee() {\n return __WEBPACK_IMPORTED_MODULE_0_babel_runtime_regenerator___default.a.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n window.addEventListener('load', function () {\n __WEBPACK_IMPORTED_MODULE_3__main__[\"pauser\"].next(false);\n });\n\n case 1:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, _this);\n }))();\n }\n});\n\n/***/ })\n\n},[\"NHnr\"]);\n\n\n// WEBPACK FOOTER //\n// static/js/app.b517d149c346ba201c8a.js","\n\n\n\n\n\n\n\n\n// WEBPACK FOOTER //\n// src/components/HelloWorld.vue","module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDE0IDc5LjE1Njc5NywgMjAxNC8wOC8yMC0wOTo1MzowMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTk2QkI4RkE3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTk2QkI4Rjk3NjE2MTFFNUE4NEU4RkIxNjQ5MTYyRDgiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NjU2QTEyNzk3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NjU2QTEyN0E3NjkyMTFFMzkxODk4RDkwQkY4Q0U0NzYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5WHowqAAAXNElEQVR42uxda4xd1XVe53XvvD2eGQ/lXQcKuDwc2eFlCAGnUn7kT6T86J/+aNTgsWPchJJYciEOCQ8hF+G0hFCIHRSEqAuJBCqRaUEIEbmBppAIBGnESwZje8COZ+y587j3PLq+ffadGJix53HvPevcuz60xPjec89ZZ+39nf04+9vLSZKEFArFzHA1BAqFEkShUIIoFEoQhUIJolAoQRQKJYhCoQRRKJQgCoUSRKFQKEEUCiWIQrFo+Gv/8/YH+f/nsMWSHHMChyhxqPTTdyncWyJ3ScD/ztipiB3wXSqu6P17avN+TyFC5ggv4tRnmoxWTP1+5F+Mz17GPvPl49EKBWd3UsfXllPiso8VcYtmPba3fNuKrBVXrGFCbrdPwXndFL49ltI367roOpSUI4pGypv9s7q+ltj6JxqOQ07Bo/DgxGb2/a8cX0CnAWXJ5etz2TqdHiXHKlKj9w6i9XX8Ic41DmI8FVHhmmXk85MmRhCzJoiTWnig9LfJRHihgydxzAxJhBr7Bh/hK3yu+p9568FliTJF2aKMZfVd/kQOcKP6OBmS9+Rjm4zJ6faoeN0gOUn61MncLX4CJ+MRhe+P/dRxhfew2Df4CF/hs4jWg8vQYUKYMuWyRRkLjeHQ8YP0Z9mekVjA8Qj3VVcuoeDiXu63lkUE0ym6FA5PXBaNVr7qtPumGyPR4Bt8hK/wWUR5chn6XJYoU5StUHL8l+XEx2axhkS6yk+chJuP4rXLyOkIKJkS0B67adcqfL/0Y4pixxSysK6V8Yl9Mz7i3272NRFlhzJsu24Z5l9E9Ahmwfrpoj7uw3fZtktsRZKjIXnndlLxin7+W8ZTBwPf6I+Tg9HwxK2Ob8citbCoBoaxBxMCvsFH+CqjHCtUvLzflKWUcpwB91gupG5f9/Rtx39ZZBtmWyJtphKzHTQW0diP36b4aJmcLj/zGaSkHJPb4SWFi/tOJd8bTqd9s48VBRh4RKeUX/vjgXg8cpyCmz05xkJylxSoa8M5RF0eJaVIIkGOsg2yTc3UgpD94psiWxEOqDNYoOIXuHnGwE5AXUTFi46FTnRw4l/dwEm7/pSxcYnCF/gE3zInh52RRJkVP7/MlKFQcgCbjifHTAQBfsb2qsgBO3e1Cpf3UXBej3nRJKKrxU/rcH/pKzz4vNIQuRJTEmZklbg6EL4SPsE3GQPzinmfhbJDGQolB+r8w58abs5y8DqRt4ABeptLRR7koY9NleybEYw/MPisvF/ayT1/SvDewcnIcG32wfiCAbEvoCZyGaGsitdyz6XdTctQJq6fcT5mloNfYvu5yFZkpEz+RT0UrFoqpxVBV+vQxIrkaPnrbqdvXs6hcjbU+Jq4Nvvwd/BFRNeq2npwWfkX95iyE9p6PM72P/MhCPANTBSKu5WITHcC074Y9CUTkYglKBgcV/aVtlM5Kpp/RHFjDdfka7MP/2wG6m72661QNigjlBXKTGBtsjWKNs5atCf44Uds3xc5YD8Wknd2BxWuGjCzIxLWQzlFj+IjU108OL7bafM5sm5DDdfka/8T+9AJXyTMpqFsUEYoK5SZ0NbjVlvX500Q4Ha2A+JuCcEvhVS8qp/8MzspHhMSfO7mVPaP35BMRp9JsCQldbX+hmvxNfnamzJfqVvtWnGZoGxQRigroYs6UbfvOGHn4ORVkTaIbEWwtqg3MNO+Zql0JGCdVuCayhDuG9uJB7vp+oR17FbZc+NauCauLWLmKkqXr6NsUEYoK6GtxwY6CXXnEs0n2faIHLCPhhR8bikFKwRN+xZddHWu5a7Ol9yCZ2ZwHKdOxufGNeKRqS/hmnLWW1VMmQSrl5oyEkqOPbZu02IJAsic9sU7B+5uF9cOmqUfeLOdOaAZYb/CA+M/Ic9NxUoYMNfD/PT84f7xB807EAnrrbgMUBZt1w1SEpCIqfjF1Om5EuQNth0iu1r8tPLP76LCpX2yWpHDk2dGH018p6brtD5hOHf04cR3okOTZ0lqPVAW3gVdlMhdrfsTW6drRhDgRrYJcbeKZQxTkenvegNt6YBQwrQvOxG+P3ZHEia9TuClS9Br1XKge8XnxLlxjelzZ/2w4tijDMxyoHIsVQg1zvYPcy7KeZx4jG2zyFakFJF7Whu1XT2QvhfJeryeVNdplYPo4Pi9hKd7VVxVC8O5cH4+N65hXgoKuGfEHmWAskjGxI49Ntu6XHOCAD9ie1PcLSepjDNY00fB8m6KpSyJx/jgg9LfJEfLK40818w+LXY5e5zKaMfKl+DcIlSCZp0cd3U59igDI4+WOa2LunvfvDoD9RrcNLqAjDy3yzfrtKqbAkggSDIZmSlYxzz9a8BaJ101zF2rh3BuSTJaCKGMDEGujHbedXch0X2ebbdEkkDC6a9cQoWVguS53P0JP5xcHY1W/tppD9KxgrdAw5QxnwPn4nOukrPeqkzBJb0m9oJltLtt3a07QYD1IkMAeS7/hw0BXMhzJwXJc/eV7kuiyIN8OOGuUhLP06JUeoxz4FxiZLRouTsDM9WO2OdBRtsIgrzHtk3kgH00JO+cTipc2S9jqyCaluf2xwcnfuB6LndHuEsSzdP4N/gtzoFzSZHRIsaQQiPmidyXgttsnW0YQYDvsh2ROGBPxkMqXjNA/qlCFsnZ8UdlX+kfk0pymlnMWH2JOBfz0sWI+C3OMS1dzPphhPVWHOPC5wdMzIUOzFFHb1lwB2ARF+ZOPt0gshWBPLe/wCRZlu6CIkSei/cE0fD4g2ZbVWceyxH5WPwGvzXrrSTJaDnG7oBoGS3qaCULggCPsv1W5IAd8tzLllJwvpx1WthMIfyg9OVotHy1WVQ4V37wsfgNfkuSZLQcW8Q4lruU/RVbRykrggDXiwwN3uQWnXTa1xMkz2W/on2lndNajpNtAGePw2/MOicBMlqs+8K7GBNbjrFgGe2iX0nUgiAvs+0S2YpgndaFPVRc3SdmVanZlfGjifOiw5PrT/oGvPpG/vDkEH4jZ70Vt86rl5rYimmdP41/s3Uzc4Isup9XNxwvz+0tyNAlONPrtO6hctR+QnluKqNt52O3pxvtClhvxTH0egtmEwbBMlrUxU21OFGtCHKYbavIATv3j90z26kIea4QZRtahfhIuT0anrjH7O3rpjNVHzPIaLG3Lh8Tj5TbRQihjlNyehxTwTLarbZOiiEIcBfbPnGhMtroChXW9JN/VqeYdyPEY4nwwPj6ZCL8C1T+T61JhDqRv8MxZgwlJG2BxzEsrBmgeEzseqt9ti6SNIIA8t6wm901eFDZ66d7M4UkQ56LVgTTvvtKaRqFqoTWymjxGb6LpUzrImYcuzaOIWKJmAptPWpaB2sd+V+yvSB1wB6s7qXgwiUyBpbJdBqFq6MjU18mKCKhRsTyEbx558/wnRmYJzLiV+DYBat6JQ/MX7B1UCxBAKHy3IQrH6W7MhY9MWkUMNAN948/8Mm35/jMDIKlpC3gmBWQtsAjifkE61b36kGQP7DdL7KrVZXnXiYpjYKZxj09Gh7f4kB4yIa/8ZmU1brIIYiYIXaJ3Nbjflv3xBME+DZbSVwIzfIIK89dJkSea18Ihu+XflD9yPztCJnW5Ri5VRntpNh8giVb5ygvBIHu9yaRrchYRO6fFU0CSTPQlDLte6zshx9O3g3D3yJajySd4EDaAsQMsRPaetxk61zty+YTCXRqjf9jO19cOLnyYV+p8QffpcreMXJ7BeRgh77Ds6SIYhGbMBgB2tld1DW0nGL4VxbZfKBbdUHdhol1dl7mOi0MOjttGgWT11lAwU9r1mMSsX0oxwSxgYyWOvKXtiAvBPkV239I7GqZdVqX9FDw2V5+UoYipn2nt/WRMK3LMQlW9poYCZ7WfcrWsdwSBNggMrRYdcLdhjas0+q28lzJOc8bOU7jWLh2AwzEyLxclYm6Z2ZuBEE+YLtTZEVA9tzPdBh5biJ3q5rGD8yRjXbNAPkcm0RuyjTUqf3NQBDge2yHJFaGeDyi4tUD5J3WIXmzs8Y9NDgG3un80OCYIDZCHxqHbJ2iZiEIGmnB8twgzYIkd7vMxiBON59GLJyBQLKMdiM1qOPXyMn2f2f7X5EDdshzkUbhAtED0oZMXCAGiIXgtAW/YXusURdr9NsoufLcgmP20zKy2ErrNSNGRuunMUAshL7zABq61q/RBPkd2yNSn57+X3ZTQZA8t7H3H5p7RwwEt6KP2DrUtAQBIIUsiwt99Kf+tydFntuocVhVRltNWyBTRlumGslopRNkhO1mkRVlLCT3jHYzqyU48WSN+1ZWRou0BZDRyp3Ju9nWnaYnCHA3216JlQWy0gKy557dJSaNQn0nKNL1VrhnwTLavbbOUKsQBBApzzVpFHqsPFdIGoW6AfeG7cMwrcv3TC0io80LQZ5me07kU3WkYqSlhYvkpFGoz8C8bO7RyGjlpi14ztaVliMIIFOeizQKbpI+WdsDGfLcWvcmsaK53b4gdUW3lENZXjxrgrzNdq/IAftohbzzOql4eV/zjUUcu96K7w33KFhGi7rxVisTBEBSxWPiiqYqz71mGfmDQuS5tSIHstHyPZnd7+XKaI+RgKSxEggySWmKaXkVaSwi5xSbRmGiSdZpxVZGy/eEexMso73R1o2WJwiwk+11kQNZrNO6oo+Cc7vz39Wy07q4l+CKfnNvQu/ndVsnSAkifcCOAXq7R8W1y9JdRvI87QvfnTRtgdPeujLavBLkv9meEPnUHS2Tf1EPFT67lOKRnE77munrsrkH/+IeydPXqAO/VoLMDMhz5T2irTzXpFHoKeRPnluV0XYX0mlduTLamIRJtKUR5CDbbSIrGPfX/eUdVFyTQ3luku6OaNIW/HmH5LQFt9k6oAQ5Ab7PNiyxkmGndUhRvTNyJM9F1wrZaM9IZbQmG63MocewxIejRIKg+DaKbEXGI3KWBtT2hUFKyonUZeEfB3xkX4vsM3wXvIx/IwmMqCu0WH/B9qLIpzG6Wp/rpWBFj/x1WnaCAb4G7LPgad0XbZmTEmTukDnti0yzgZvKcwNPtDzXyGjZR5ONFincVEbbVAR5je0hkU/lkTL5F3TZzQ2EvjysJr1hH/0LuiVPTz9ky1oJsgB8iwQsN5hplISns5Hn9hXl9eurMlr2zUzrVsQuk5m0ZUxKkIXhKNsWkQN2yHNPhzx3WbqQMRZGYCOjXWZ8FDzjtsWWsRJkEfgh2zvyOvhWnovsucu75GTPtdlo4RN8i+W+s3nHli0pQRaPIXEeVeW53V46YJciz2Uf4IvxiX0juW/9h/JQ8fJCkGfZnpE5YK9QsHIJBZcIkOdW141d3Gt8EiyjfcaWqRKk6Z84kOc6duODjmzluUZGyz4g6Q18UhltaxHkXbbtIgfsRyvknQt5bobZc6dltP3Gl0SudmW7LUslSJ1mPUbFeWVUepDnDpB3SgazRtW0BXxt+ABfhE7rypyVbCKCTLF9U2QrgjQKg3b7zskGv3eI0+XsuDZ8EJy2YJMtQyVIHfEztldFDtghz728j4LzGphGoZq2gK9ZMDuwiH3ngTJ7OG+VLY8EAeTKc9ts9lwk42zEOi2st+JrYZIA1xYso12Xx4qWV4K8xPZzka3ISCrPDVY1YJ1WtfVYZWW0ctdbPW7LTAnSQHyDJCoykEYhTNdpuUsK6YDZqQ85cG5cw6y3CsWmLYBXG/NayfJMkI8oVR/KG7AfC8k7u4MKVw2kM1r1eB2RpDNXuAauJVhGe6stKyVIBrid7YA4r6o5N5BG4cxOI3mtaeWtymj53LiG4FwmKJs78lzB8k4QVIsN4ryqynN7AzP1ShXIc2tYg3GuSpJO6/aKltHK3KWmhQgCPMm2R+SAfTSkANlzV9Rw2rc6MDcyWtHZaPfYsiElSPaQOYVYiSnxiIprB8kpeGn+v8U2mZD8FjxzTpybKjqtqwQ5Od5g2yGyq4Xsued3UeHSvsW3IlUZLZ8L5xSctmCHLRMliCBgN/AJcV7F6SpbjBe8gUWkUaimLeBzmOUsU2JltOMkcbd+JQiNkYB8ErNVbPe0Nmq72i4kXMiwNUnfe+AcOJfgfCWbbVkoQQTiR2xvivPKynODNX0ULF9AGoVq2gL+Lc4hWEaL2N/XTBWq2Qgic3BYled2+ekeVfOV51az0WKNF59DsIx2XbNVpmYkyPNsuyWSBBJYf+USKsxHnlvNRsu/8WXLaHfb2CtBcoD1Ir2CPJf/wxSt2xmkupGT9c6QtoCPNdO66FfJldGub8aK1KwEeY9tm8gB+2hI3jmdVLii/+RbBdktfHAsfpPIfSm4zcZcCZIjfJftiMQBO1IQQBrrn3qCRYZ20SOOMTLacbHrrRDjW5q1EjUzQbiTTzeIbEUgz+232XNne59RfX+CbLT9omW0iHFFCZJPPMr2W5EDdshzL1tKwfkzrNOqrrfi73CMYBntKzbGpATJL64X6RXWZRVtxlnP+VgaBZO2wEu/wzGatkAJUk+8zLZLZCuCdVoXciux+rhVuXYVMD7Dd7Hc9Va7bGyVIE0Amf3kaXnuIHm9qTwXhr/xmWAZbUXk+E4JsmAcZtsqcsAOee6Z7VS08lwY/sZngmW0W21MlSBNhLvY9onzCqtIxipUuKqf3L6iMfyNz4RO6+6zsWwJ+NRawNvep8S1IhMxucie+8VT0o+6PIqPiB17rG+lCtNqBPkl2wts14gbsCONwqVLzT8Fr7d6wcawZeBS60Hm1GSSTu+a6d5EY6cEyQ5/YLtf4oCd4iQ1ma3H/TZ2SpAWwLfZSqSYK0o2ZqQEaQ1AN32T1vs54yYbMyVIC+GBVuwyLLBL+kCr3rzb4oV/vdZ/jZESZHb8iqS9F5GFp2yMlCAtjCENgcZGCTI79rPdqWH4FO60sVGCKOh7bIc0DNM4ZGNCShAFEFKOsyDVARttTJQgGoJpPMb2Gw2DicFjGgYlyExYpyHQGChBZsfv2B5p4ft/xMZAoQSZFZso3TKo1VC2965QgpwQI2w3t+B932zvXaEEOSnuZtvbQve7196zQgkyZ6zXe1UoQWbH02zPtcB9PmfvVaEEmTeG9B6VIIrZ8RbbvU18f/fae1QoQRYMJKU81oT3dYwkJj1VguQOk9REaY2Pw4323hRKkEVjJ9vrTXQ/r9t7UihBaobr9V6UIIrZ8Wu2J5rgPp6w96JQgtQcG2jmhGl5QWzvQaEEqQsOst2WY/9vs/egUILUtZIN59Dv4ZyTWwmSEyDnUx7luRtJar4qJUjT4RdsL+bI3xetzwolSMOwTn1Vgihmx2tsD+XAz4esrwolSMPxLZK9XGPS+qhQgmSCo2xbBPu3xfqoUIJkhh+yvSPQr3esbwolSOYYUp+UIIrZ8SzbM4L8ecb6pFCC6BNbWw8lSB7wLtt2AX5st74olCDikPWskfRZNSVIi2OKst2+c5P1QaEEEYuH2V7N4Lqv2msrlCDisa5FrqkEUSwIL7E93sDrPW6vqVCC5AaN0l/kVZ+iBGlxfMR2awOuc6u9lkIJkjvcwXagjuc/YK+hUILkEgnVdxeRDfYaCiVIbvEk2546nHePPbdCCZJ7rMvJORVKkEzwBtuOGp5vhz2nQgnSNMBu6uM1OM84Nedu80qQFscY1SYfx2Z7LoUSpOlwH9ubi/j9m/YcCiWIDth1YK4EaUU8z7Z7Ab/bbX+rUII0PdY36DcKJUgu8R7btnkcv83+RqEEaRncwnZkDscdsccqlCAthQrbDXM47gZ7rEIJ0nJ4lO2VE3z/ij1GoQRpWaxb4HcKJUhL4GW2XTN8vst+p1CCtDw+Oc6Y6/hEoQRpCRxm23rcv7fazxRKEIXFXZRuwBDZvxUC4GsIREHflguDkyQqaVYotIulUChBFAoliEKhBFEolCAKhRJEoVCCKBRKEIVCCaJQKJQgCoUSRKFQgigUShCFIhP8vwADACog5YM65zugAAAAAElFTkSuQmCC\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/assets/logo.png\n// module id = 7Otq\n// module chunks = 1","function injectStyle (ssrContext) {\n require(\"!!../node_modules/extract-text-webpack-plugin/dist/loader.js?{\\\"omit\\\":1,\\\"remove\\\":true}!vue-style-loader!css-loader?{\\\"minimize\\\":true,\\\"sourceMap\\\":true}!../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-55bf0f57\\\",\\\"scoped\\\":false,\\\"hasInlineConfig\\\":false}!../node_modules/vue-loader/lib/selector?type=styles&index=0!./App.vue\")\n}\nvar normalizeComponent = require(\"!../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nimport __vue_script__ from \"!!babel-loader!../node_modules/vue-loader/lib/selector?type=script&index=0!./App.vue\"\n/* template */\nimport __vue_template__ from \"!!../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-55bf0f57\\\",\\\"hasScoped\\\":false,\\\"transformToRequire\\\":{\\\"video\\\":\\\"src\\\",\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../node_modules/vue-loader/lib/selector?type=template&index=0!./App.vue\"\n/* template functional */\n var __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_template__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/App.vue\n// module id = M93x\n// module chunks = 1","// The Vue build version to load with the `import` command\n// (runtime-only or standalone) has been set in webpack.base.conf with an alias.\nimport Vue from 'vue';\nimport { Subject } from 'rxjs';\nimport Vueheatmap from './heatmap';\n// import { debounce } from 'lodash';\nimport App from './App';\n\nconst stream = new Subject();\nexport const pauser = new Subject();\n\nVue.config.productionTip = false;\nVue.use(Vueheatmap, {\n stream,\n pauser,\n heatmapPreload: [{ x: 10, y: 10, value: 100 }],\n});\n\nstream\n .throttleTime(1000)\n .subscribe(console.log);\n\n/* eslint-disable no-new */\nexport default new Vue({\n el: '#app',\n template: '',\n components: { App },\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.js","import h337 from 'heatmap.js';\nimport { Observable, Subject } from 'rxjs';\n\nlet loaded = false;\nwindow.addEventListener('load', () => { loaded = true; });\n\nexport default {\n install(Vue, options = {}) {\n let heatmap;\n\n const addValue = (e, value) => {\n e.value = value;\n return e;\n };\n\n const getHeight = () => {\n const body = document.body;\n const html = document.documentElement;\n\n return Math.max(body.scrollHeight, body.offsetHeight,\n html.clientHeight, html.scrollHeight, html.offsetHeight);\n };\n\n const pauser = options.pauser || new Subject();\n\n Vue.directive('scrollmap', {\n inserted(el, binding) {\n const height = getHeight();\n const canvas = document.createElement('canvas');\n const rounding = binding.arg || 50;\n const show = binding.value || true;\n const scroll = Observable.interval(2000);\n\n let max = 0;\n\n document.body.appendChild(canvas);\n canvas.height = height;\n canvas.style.height = `${height}px`;\n canvas.width = window.outerWidth;\n canvas.style.position = 'absolute';\n canvas.style.left = 0;\n canvas.style.top = 0;\n canvas.style.width = '100%';\n canvas.style.opacity = '0.8';\n canvas.style.display = show;\n canvas.id = 'scrollMapCanvas';\n canvas.style.pointerEvents = 'none';\n\n pauser.switchMap(paused => (paused ? Observable.never : scroll))\n .map(() => window.scrollY)\n .scan((acc, pos) => {\n const rounded = Math.round(pos / rounding) * rounding;\n let roundedWithHeight = Math.round((pos + window.innerHeight) / rounding) * rounding;\n\n while (roundedWithHeight >= rounded) {\n acc[roundedWithHeight] = acc[roundedWithHeight] || 0;\n acc[roundedWithHeight] += 1;\n max = Math.max(acc[roundedWithHeight], max);\n roundedWithHeight -= rounding;\n }\n\n return acc;\n }, { 0: 1 })\n .subscribe((positions) => {\n const c = document.getElementById('scrollMapCanvas');\n c.height = height;\n const ctx = c.getContext('2d');\n const myGradient = ctx.createLinearGradient(0, 0, 0, c.height);\n\n myGradient.addColorStop(0, 'hsla(0,50%,50%, 1)');\n myGradient.addColorStop(1, 'hsla(0,50%,50%, 0)');\n\n Object.keys(positions).forEach((key) => {\n myGradient.addColorStop(Math.min(1, key / c.height), `hsla(0,50%,50%, ${positions[key] / max})`);\n });\n\n ctx.fillStyle = myGradient;\n ctx.fillRect(0, 0, c.width, c.height);\n });\n\n pauser.next(false);\n },\n\n update(el, binding) {\n document.getElementById('scrollMapCanvas').style.display = binding.value ? 'inherit' : 'none';\n },\n });\n\n const loadHeatmap = async (el, binding) => {\n heatmap = h337.create({\n maxOpacity: 0.6,\n radius: 50,\n blur: 0.90,\n backgroundColor: 'rgba(0, 0, 58, 0)',\n container: el,\n });\n\n if (options.heatmapPreload) {\n heatmap.addData(await Promise.resolve(options.heatmapPreload));\n }\n\n const move = Observable.fromEvent(el, 'mousemove');\n const touch = Observable.fromEvent(el, 'touchmove');\n const click = Observable.fromEvent(el, 'click');\n\n const streams = Observable.merge(\n move.map(e => addValue(e, 5)),\n touch.map(e => addValue(e, 5)),\n click.map(e => addValue(e, 10)),\n );\n\n const pausable = pauser.switchMap(paused => (paused ? Observable.never : streams));\n\n pausable.debounceTime(10)\n .map(e => ({\n x: e.layerX,\n y: e.layerY,\n value: e.value,\n }))\n .subscribe(e => heatmap.addData(e));\n\n if (options.afterAdd) {\n pausable.subscribe(options.afterAdd);\n }\n\n if (options.stream) {\n pausable.subscribe(e => options.stream.next(e));\n }\n\n /* eslint-disable no-param-reassign */\n el.querySelector('canvas.heatmap-canvas').style.display = binding.value ? 'inherit' : 'none';\n el.querySelector('canvas.heatmap-canvas').style.pointerEvents = 'none';\n };\n\n Vue.directive('heatmap', {\n inserted: async (el, binding) => {\n window.addEventListener('load', () => {\n loadHeatmap(el, binding);\n });\n\n if (loaded) {\n loadHeatmap(el, binding);\n }\n },\n\n update(el, binding) {\n /* eslint-disable no-param-reassign */\n el.querySelector('canvas.heatmap-canvas').style.display = binding.value ? 'inherit' : 'none';\n },\n });\n },\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/heatmap.js","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"hello\"},[_c('h1',[_vm._v(_vm._s(_vm.msg))]),_vm._v(\" \"),_c('h2',[_vm._v(\"Essential Links\")]),_vm._v(\" \"),_vm._m(0),_vm._v(\" \"),_c('h2',[_vm._v(\"Ecosystem\")]),_vm._v(\" \"),_vm._m(1)])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('ul',[_c('li',[_c('a',{attrs:{\"href\":\"https://vuejs.org\",\"target\":\"_blank\"}},[_vm._v(\"Core Docs\")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"https://forum.vuejs.org\",\"target\":\"_blank\"}},[_vm._v(\"Forum\")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"https://chat.vuejs.org\",\"target\":\"_blank\"}},[_vm._v(\"Community Chat\")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"https://twitter.com/vuejs\",\"target\":\"_blank\"}},[_vm._v(\"Twitter\")])]),_vm._v(\" \"),_c('br'),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"http://vuejs-templates.github.io/webpack/\",\"target\":\"_blank\"}},[_vm._v(\"Docs for This Template\")])])])},function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('ul',[_c('li',[_c('a',{attrs:{\"href\":\"http://router.vuejs.org/\",\"target\":\"_blank\"}},[_vm._v(\"vue-router\")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"http://vuex.vuejs.org/\",\"target\":\"_blank\"}},[_vm._v(\"vuex\")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"http://vue-loader.vuejs.org/\",\"target\":\"_blank\"}},[_vm._v(\"vue-loader\")])]),_vm._v(\" \"),_c('li',[_c('a',{attrs:{\"href\":\"https://github.com/vuejs/awesome-vue\",\"target\":\"_blank\"}},[_vm._v(\"awesome-vue\")])])])}]\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-73219722\",\"hasScoped\":true,\"transformToRequire\":{\"video\":\"src\",\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/components/HelloWorld.vue\n// module id = f7Ie\n// module chunks = 1","function injectStyle (ssrContext) {\n require(\"!!../../node_modules/extract-text-webpack-plugin/dist/loader.js?{\\\"omit\\\":1,\\\"remove\\\":true}!vue-style-loader!css-loader?{\\\"minimize\\\":true,\\\"sourceMap\\\":true}!../../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-73219722\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../node_modules/vue-loader/lib/selector?type=styles&index=0!./HelloWorld.vue\")\n}\nvar normalizeComponent = require(\"!../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nimport __vue_script__ from \"!!babel-loader!../../node_modules/vue-loader/lib/selector?type=script&index=0!./HelloWorld.vue\"\n/* template */\nimport __vue_template__ from \"!!../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-73219722\\\",\\\"hasScoped\\\":true,\\\"transformToRequire\\\":{\\\"video\\\":\\\"src\\\",\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../../node_modules/vue-loader/lib/selector?type=template&index=0!./HelloWorld.vue\"\n/* template functional */\n var __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = \"data-v-73219722\"\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_template__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/components/HelloWorld.vue\n// module id = gORT\n// module chunks = 1","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{directives:[{name:\"scrollmap\",rawName:\"v-scrollmap:100\",value:(_vm.showScrollmap),expression:\"showScrollmap\",arg:\"100\"}],attrs:{\"id\":\"app\"}},[_c('div',{directives:[{name:\"heatmap\",rawName:\"v-heatmap\",value:(_vm.showHeatmap),expression:\"showHeatmap\"}]},[_c('img',{attrs:{\"src\":require(\"./assets/logo.png\")}})]),_vm._v(\" \"),_c('button',{on:{\"click\":function($event){_vm.showHeatmap = !_vm.showHeatmap}}},[_vm._v(\"Toggle Heatmap\")]),_vm._v(\" \"),_c('button',{on:{\"click\":function($event){_vm.showScrollmap = !_vm.showScrollmap}}},[_vm._v(\"Toggle Scrollmap\")]),_vm._v(\" \"),_c('button',{on:{\"click\":_vm.pauseCollection}},[(_vm.paused)?_c('span',[_vm._v(\"Resume Collection\")]):_c('span',[_vm._v(\"Pause Collection\")])])])}\nvar staticRenderFns = []\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-55bf0f57\",\"hasScoped\":false,\"transformToRequire\":{\"video\":\"src\",\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/App.vue\n// module id = pjLW\n// module chunks = 1","\n\n\n\n\n\n\n\n// WEBPACK FOOTER //\n// src/App.vue"],"sourceRoot":""} -------------------------------------------------------------------------------- /docs/static/js/manifest.706b9ac0cc4cf54c13df.js: -------------------------------------------------------------------------------- 1 | !function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,a){for(var i,u,f,s=0,l=[];s 2 | 3 | 4 | 5 | vue-heatmapjs 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-heatmapjs", 3 | "main": "src/heatmap.js", 4 | "version": "1.6.0-0", 5 | "description": "A vue directive for collecting and displaying user activity on a component", 6 | "author": "Brock ", 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "start": "npm run dev", 10 | "build": "node build/build.js", 11 | "lint": "eslint --ext .js,.vue src" 12 | }, 13 | "dependencies": { 14 | "heatmap.js": "^2.0.5", 15 | "rxjs": "^5.5.5" 16 | }, 17 | "devDependencies": { 18 | "autoprefixer": "^7.1.2", 19 | "babel-core": "^6.22.1", 20 | "babel-eslint": "^7.1.1", 21 | "babel-loader": "^7.1.1", 22 | "babel-plugin-transform-runtime": "^6.22.0", 23 | "babel-preset-env": "^1.3.2", 24 | "babel-preset-stage-2": "^6.22.0", 25 | "babel-register": "^6.22.0", 26 | "chalk": "^2.0.1", 27 | "connect-history-api-fallback": "^1.3.0", 28 | "copy-webpack-plugin": "^4.0.1", 29 | "css-loader": "^0.28.0", 30 | "eslint": "^4.18.2", 31 | "eslint-config-airbnb-base": "^11.3.0", 32 | "eslint-friendly-formatter": "^3.0.0", 33 | "eslint-import-resolver-webpack": "^0.8.3", 34 | "eslint-loader": "^1.7.1", 35 | "eslint-plugin-html": "^3.0.0", 36 | "eslint-plugin-import": "^2.7.0", 37 | "eventsource-polyfill": "^0.9.6", 38 | "express": "^4.14.1", 39 | "extract-text-webpack-plugin": "^3.0.0", 40 | "file-loader": "^1.1.4", 41 | "friendly-errors-webpack-plugin": "^1.6.1", 42 | "html-webpack-plugin": "^2.30.1", 43 | "http-proxy-middleware": "^0.17.3", 44 | "opn": "^5.1.0", 45 | "optimize-css-assets-webpack-plugin": "^3.2.0", 46 | "ora": "^1.2.0", 47 | "portfinder": "^1.0.13", 48 | "rimraf": "^2.6.0", 49 | "semver": "^7.5.2", 50 | "shelljs": "^0.8.5", 51 | "url-loader": "^0.5.8", 52 | "vue": "^2.5.2", 53 | "vue-loader": "^13.3.0", 54 | "vue-style-loader": "^3.0.1", 55 | "vue-template-compiler": "^2.5.2", 56 | "webpack": "^3.6.0", 57 | "webpack-bundle-analyzer": "^3.3.2", 58 | "webpack-dev-middleware": "^5.3.4", 59 | "webpack-hot-middleware": "^2.18.2", 60 | "webpack-merge": "^4.1.0" 61 | }, 62 | "engines": { 63 | "node": ">= 4.0.0", 64 | "npm": ">= 3.0.0" 65 | }, 66 | "browserslist": [ 67 | "> 1%", 68 | "last 2 versions", 69 | "not ie <= 8" 70 | ], 71 | "files": [ 72 | "src/heatmap.js" 73 | ] 74 | } 75 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 47 | 48 | 59 | -------------------------------------------------------------------------------- /src/assets/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrockReece/vue-heatmapjs/aad967c7cb9d4c115d37bdfd40766dce8ea55b0f/src/assets/example.png -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrockReece/vue-heatmapjs/aad967c7cb9d4c115d37bdfd40766dce8ea55b0f/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/Hello.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 54 | -------------------------------------------------------------------------------- /src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 54 | -------------------------------------------------------------------------------- /src/heatmap.js: -------------------------------------------------------------------------------- 1 | import h337 from 'heatmap.js'; 2 | import { Observable, Subject } from 'rxjs'; 3 | 4 | let loaded = false; 5 | window.addEventListener('load', () => { loaded = true; }); 6 | 7 | export default { 8 | install(Vue, options = {}) { 9 | const addValue = (e, value) => { 10 | e.value = value; 11 | return e; 12 | }; 13 | 14 | const getHeight = () => { 15 | const body = document.body; 16 | const html = document.documentElement; 17 | 18 | return Math.max(body.scrollHeight, body.offsetHeight, 19 | html.clientHeight, html.scrollHeight, html.offsetHeight); 20 | }; 21 | 22 | const pauser = options.pauser || new Subject(); 23 | 24 | Vue.directive('scrollmap', { 25 | inserted(el, binding) { 26 | const height = getHeight(); 27 | const canvas = document.createElement('canvas'); 28 | const rounding = binding.arg || 50; 29 | const show = binding.value || true; 30 | const scroll = Observable.interval(2000); 31 | 32 | let max = 0; 33 | 34 | document.body.appendChild(canvas); 35 | canvas.height = height; 36 | canvas.style.height = `${height}px`; 37 | canvas.width = window.outerWidth; 38 | canvas.style.position = 'absolute'; 39 | canvas.style.left = 0; 40 | canvas.style.top = 0; 41 | canvas.style.width = '100%'; 42 | canvas.style.opacity = '0.8'; 43 | canvas.style.display = show; 44 | canvas.id = 'scrollMapCanvas'; 45 | canvas.style.pointerEvents = 'none'; 46 | 47 | pauser.switchMap(paused => (paused ? Observable.never : scroll)) 48 | .map(() => window.scrollY) 49 | .scan((acc, pos) => { 50 | const rounded = Math.round(pos / rounding) * rounding; 51 | let roundedWithHeight = Math.round((pos + window.innerHeight) / rounding) * rounding; 52 | 53 | while (roundedWithHeight >= rounded) { 54 | acc[roundedWithHeight] = acc[roundedWithHeight] || 0; 55 | acc[roundedWithHeight] += 1; 56 | max = Math.max(acc[roundedWithHeight], max); 57 | roundedWithHeight -= rounding; 58 | } 59 | 60 | return acc; 61 | }, { 0: 1 }) 62 | .subscribe((positions) => { 63 | const c = document.getElementById('scrollMapCanvas'); 64 | c.height = height; 65 | const ctx = c.getContext('2d'); 66 | const myGradient = ctx.createLinearGradient(0, 0, 0, c.height); 67 | 68 | myGradient.addColorStop(0, 'hsla(0,50%,50%, 1)'); 69 | myGradient.addColorStop(1, 'hsla(0,50%,50%, 0)'); 70 | 71 | Object.keys(positions).forEach((key) => { 72 | myGradient.addColorStop(Math.min(1, key / c.height), `hsla(0,50%,50%, ${positions[key] / max})`); 73 | }); 74 | 75 | ctx.fillStyle = myGradient; 76 | ctx.fillRect(0, 0, c.width, c.height); 77 | }); 78 | 79 | pauser.next(false); 80 | }, 81 | 82 | update(el, binding) { 83 | document.getElementById('scrollMapCanvas').style.display = binding.value ? 'inherit' : 'none'; 84 | }, 85 | }); 86 | 87 | const loadHeatmap = async (el, binding) => { 88 | const heatmap = h337.create({ 89 | maxOpacity: 0.6, 90 | radius: 50, 91 | blur: 0.90, 92 | backgroundColor: 'rgba(0, 0, 58, 0)', 93 | container: el, 94 | }); 95 | 96 | if (options.heatmapPreload) { 97 | heatmap.addData(await Promise.resolve(options.heatmapPreload)); 98 | } 99 | 100 | const move = Observable.fromEvent(el, 'mousemove'); 101 | const touch = Observable.fromEvent(el, 'touchmove'); 102 | const click = Observable.fromEvent(el, 'click'); 103 | 104 | const streams = Observable.merge( 105 | move.map(e => addValue(e, 5)), 106 | touch.map(e => addValue(e, 5)), 107 | click.map(e => addValue(e, 10)), 108 | ); 109 | 110 | const pausable = pauser.switchMap(paused => (paused ? Observable.never : streams)); 111 | 112 | pausable.debounceTime(10) 113 | .map(e => ({ 114 | x: e.layerX, 115 | y: e.layerY, 116 | value: e.value, 117 | })) 118 | .subscribe(e => heatmap.addData(e)); 119 | 120 | if (options.afterAdd) { 121 | pausable.subscribe(options.afterAdd); 122 | } 123 | 124 | if (options.stream) { 125 | pausable.subscribe(e => options.stream.next(e)); 126 | } 127 | 128 | /* eslint-disable no-param-reassign */ 129 | el.querySelector('canvas.heatmap-canvas').style.display = binding.value ? 'inherit' : 'none'; 130 | el.querySelector('canvas.heatmap-canvas').style.pointerEvents = 'none'; 131 | }; 132 | 133 | Vue.directive('heatmap', { 134 | inserted: async (el, binding) => { 135 | window.addEventListener('load', () => { 136 | loadHeatmap(el, binding); 137 | }); 138 | 139 | if (loaded) { 140 | loadHeatmap(el, binding); 141 | } 142 | }, 143 | 144 | update(el, binding) { 145 | /* eslint-disable no-param-reassign */ 146 | el.querySelector('canvas.heatmap-canvas').style.display = binding.value ? 'inherit' : 'none'; 147 | }, 148 | }); 149 | }, 150 | }; 151 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue'; 4 | import { Subject } from 'rxjs'; 5 | import Vueheatmap from './heatmap'; 6 | // import { debounce } from 'lodash'; 7 | import App from './App'; 8 | 9 | const stream = new Subject(); 10 | export const pauser = new Subject(); 11 | 12 | Vue.config.productionTip = false; 13 | Vue.use(Vueheatmap, { 14 | stream, 15 | pauser, 16 | heatmapPreload: [{ x: 10, y: 10, value: 100 }], 17 | }); 18 | 19 | stream 20 | .throttleTime(1000) 21 | .subscribe(console.log); 22 | 23 | /* eslint-disable no-new */ 24 | export default new Vue({ 25 | el: '#app', 26 | template: '', 27 | components: { App }, 28 | }); 29 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrockReece/vue-heatmapjs/aad967c7cb9d4c115d37bdfd40766dce8ea55b0f/static/.gitkeep --------------------------------------------------------------------------------