CodeSandbox

tdf2017-interactive-infographic

Create Tour De France - Interactive Infographic using Vue.js, SVG and GreenSock animation Library.

Krutie
13.1k
21
38
Edit Sandbox
Files
build
config
src
assets
components
App.vue
main.js
mixin.js
store.js
static
.babelrc
.editorconfig
.eslintignore
.eslintrc.js
.gitignore
.postcssrc.js
README.md
index.html
package.json
Dependencies
gsap2.0.2
jquery3.3.1
vue^2.5.2
vuex3.0.1
main.js
Console
0
Problems
0
\n ),\n threshold: 10240,\n minRatio: 0.8\n })\n )\n}\n\nif (config.build.bundleAnalyzerReport) {\n const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin\n webpackConfig.plugins.push(new BundleAnalyzerPlugin())\n}\n\nmodule.exports = webpackConfig\n","id":"mod_4gA63kB2oonGfkwtGP4WVR","is_binary":false,"title":"webpack.prod.conf.js","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"rJ4lO26Smh7","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":"Skgd3aSm3m"},{"code":"'use strict'\nconst utils = require('.\u002Futils')\nconst webpack = require('webpack')\nconst config = require('..\u002Fconfig')\nconst merge = require('webpack-merge')\nconst path = require('path')\nconst baseWebpackConfig = require('.\u002Fwebpack.base.conf')\nconst CopyWebpackPlugin = require('copy-webpack-plugin')\nconst HtmlWebpackPlugin = require('html-webpack-plugin')\nconst FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')\nconst portfinder = require('portfinder')\n\nconst HOST = process.env.HOST\nconst PORT = process.env.PORT && Number(process.env.PORT)\n\nconst devWebpackConfig = merge(baseWebpackConfig, {\n module: {\n rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })\n },\n \u002F\u002F cheap-module-eval-source-map is faster for development\n devtool: config.dev.devtool,\n\n \u002F\u002F these devServer options should be customized in \u002Fconfig\u002Findex.js\n devServer: {\n clientLogLevel: 'warning',\n historyApiFallback: {\n rewrites: [\n { from: \u002F.*\u002F, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },\n ],\n },\n hot: true,\n contentBase: false, \u002F\u002F since we use CopyWebpackPlugin.\n compress: true,\n host: HOST || config.dev.host,\n port: PORT || config.dev.port,\n open: config.dev.autoOpenBrowser,\n overlay: config.dev.errorOverlay\n ? { warnings: false, errors: true }\n : false,\n publicPath: config.dev.assetsPublicPath,\n proxy: config.dev.proxyTable,\n quiet: true, \u002F\u002F necessary for FriendlyErrorsPlugin\n watchOptions: {\n poll: config.dev.poll,\n }\n },\n plugins: [\n new webpack.DefinePlugin({\n 'process.env': require('..\u002Fconfig\u002Fdev.env')\n }),\n new webpack.HotModuleReplacementPlugin(),\n new webpack.NamedModulesPlugin(), \u002F\u002F HMR shows correct file names in console on update.\n new webpack.NoEmitOnErrorsPlugin(),\n \u002F\u002F https:\u002F\u002Fgithub.com\u002Fampedandwired\u002Fhtml-webpack-plugin\n new HtmlWebpackPlugin({\n filename: 'index.html',\n template: 'index.html',\n inject: true\n }),\n \u002F\u002F copy custom static assets\n new CopyWebpackPlugin([\n {\n from: path.resolve(__dirname, '..\u002Fstatic'),\n to: config.dev.assetsSubDirectory,\n ignore: ['.*']\n }\n ])\n ]\n})\n\nmodule.exports = new Promise((resolve, reject) =\u003E {\n portfinder.basePort = process.env.PORT || config.dev.port\n portfinder.getPort((err, port) =\u003E {\n if (err) {\n reject(err)\n } else {\n \u002F\u002F publish the new Port, necessary for e2e tests\n process.env.PORT = port\n \u002F\u002F add port to devServer config\n devWebpackConfig.devServer.port = port\n\n \u002F\u002F Add FriendlyErrorsPlugin\n devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({\n compilationSuccessInfo: {\n messages: [`Your application is running here: http:\u002F\u002F${devWebpackConfig.devServer.host}:${port}`],\n },\n onErrors: config.dev.notifyOnErrors\n ? utils.createNotifierCallback()\n : undefined\n }))\n\n resolve(devWebpackConfig)\n }\n })\n})\n","id":"mod_YRvFFbp6WpvjKZEB9y9Uwb","is_binary":false,"title":"webpack.dev.conf.js","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"B1ml_2TBX2X","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":"Skgd3aSm3m"},{"code":"'use strict'\nconst path = require('path')\nconst utils = require('.\u002Futils')\nconst config = require('..\u002Fconfig')\nconst vueLoaderConfig = require('.\u002Fvue-loader.conf')\n\nfunction resolve (dir) {\n return path.join(__dirname, '..', dir)\n}\n\nconst createLintingRule = () =\u003E ({\n test: \u002F\\.(js|vue)$\u002F,\n loader: 'eslint-loader',\n enforce: 'pre',\n include: [resolve('src'), resolve('test')],\n options: {\n formatter: require('eslint-friendly-formatter'),\n emitWarning: !config.dev.showEslintErrorsInOverlay\n }\n})\n\nmodule.exports = {\n context: path.resolve(__dirname, '..\u002F'),\n entry: {\n app: '.\u002Fsrc\u002Fmain.js'\n },\n output: {\n path: config.build.assetsRoot,\n filename: '[name].js',\n publicPath: process.env.NODE_ENV === 'production'\n ? config.build.assetsPublicPath\n : config.dev.assetsPublicPath\n },\n resolve: {\n extensions: ['.js', '.vue', '.json'],\n alias: {\n 'vue
: 'vue\u002Fdist\u002Fvue.esm.js',\n '@': resolve('src'),\n }\n },\n module: {\n rules: [\n ...(config.dev.useEslint ? [createLintingRule()] : []),\n {\n test: \u002F\\.vue$\u002F,\n loader: 'vue-loader',\n options: vueLoaderConfig\n },\n {\n test: \u002F\\.js$\u002F,\n loader: 'babel-loader',\n include: [resolve('src'), resolve('test'), resolve('node_modules\u002Fwebpack-dev-server\u002Fclient')]\n },\n {\n test: \u002F\\.(png|jpe?g|gif|svg)(\\?.*)?$\u002F,\n loader: 'url-loader',\n options: {\n limit: 10000,\n name: utils.assetsPath('img\u002F[name].[hash:7].[ext]')\n }\n },\n {\n test: \u002F\\.(mp4|webm|ogg|mp3|wav|flac|aac)(\\?.*)?$\u002F,\n loader: 'url-loader',\n options: {\n limit: 10000,\n name: utils.assetsPath('media\u002F[name].[hash:7].[ext]')\n }\n },\n {\n test: \u002F\\.(woff2?|eot|ttf|otf)(\\?.*)?$\u002F,\n loader: 'url-loader',\n options: {\n limit: 10000,\n name: utils.assetsPath('fonts\u002F[name].[hash:7].[ext]')\n }\n }\n ]\n },\n node: {\n \u002F\u002F prevent webpack from injecting useless setImmediate polyfill because Vue\n \u002F\u002F source contains it (although only uses it if it's native).\n setImmediate: false,\n \u002F\u002F prevent webpack from injecting mocks to Node native modules\n \u002F\u002F that does not make sense for the client\n dgram: 'empty',\n fs: 'empty',\n net: 'empty',\n tls: 'empty',\n child_process: 'empty'\n }\n}\n","id":"mod_HFYkbBw2LyXxbGaZRN3WFx","is_binary":false,"title":"webpack.base.conf.js","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"Skfgd36BQ2Q","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":"Skgd3aSm3m"},{"code":"'use strict'\nconst utils = require('.\u002Futils')\nconst config = require('..\u002Fconfig')\nconst isProduction = process.env.NODE_ENV === 'production'\nconst sourceMapEnabled = isProduction\n ? config.build.productionSourceMap\n : config.dev.cssSourceMap\n\nmodule.exports = {\n loaders: utils.cssLoaders({\n sourceMap: sourceMapEnabled,\n extract: isProduction\n }),\n cssSourceMap: sourceMapEnabled,\n cacheBusting: config.dev.cacheBusting,\n transformToRequire: {\n video: ['src', 'poster'],\n source: 'src',\n img: 'src',\n image: 'xlink:href'\n }\n}\n","id":"mod_HqrrBpd4XFzLxfEcsLc5Wd","is_binary":false,"title":"vue-loader.conf.js","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"S1-luhTBX27","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":"Skgd3aSm3m"},{"code":"'use strict'\nconst path = require('path')\nconst config = require('..\u002Fconfig')\nconst ExtractTextPlugin = require('extract-text-webpack-plugin')\nconst packageConfig = require('..\u002Fpackage.json')\n\nexports.assetsPath = function (_path) {\n const assetsSubDirectory = process.env.NODE_ENV === 'production'\n ? config.build.assetsSubDirectory\n : config.dev.assetsSubDirectory\n\n return path.posix.join(assetsSubDirectory, _path)\n}\n\nexports.cssLoaders = function (options) {\n options = options || {}\n\n const cssLoader = {\n loader: 'css-loader',\n options: {\n sourceMap: options.sourceMap\n }\n }\n\n const postcssLoader = {\n loader: 'postcss-loader',\n options: {\n sourceMap: options.sourceMap\n }\n }\n\n \u002F\u002F generate loader string to be used with extract text plugin\n function generateLoaders (loader, loaderOptions) {\n const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]\n\n if (loader) {\n loaders.push({\n loader: loader + '-loader',\n options: Object.assign({}, loaderOptions, {\n sourceMap: options.sourceMap\n })\n })\n }\n\n \u002F\u002F Extract CSS when that option is specified\n \u002F\u002F (which is the case during production build)\n if (options.extract) {\n return ExtractTextPlugin.extract({\n use: loaders,\n fallback: 'vue-style-loader'\n })\n } else {\n return ['vue-style-loader'].concat(loaders)\n }\n }\n\n \u002F\u002F https:\u002F\u002Fvue-loader.vuejs.org\u002Fen\u002Fconfigurations\u002Fextract-css.html\n return {\n css: generateLoaders(),\n postcss: generateLoaders(),\n less: generateLoaders('less'),\n sass: generateLoaders('sass', { indentedSyntax: true }),\n scss: generateLoaders('sass'),\n stylus: generateLoaders('stylus'),\n styl: generateLoaders('stylus')\n }\n}\n\n\u002F\u002F Generate loaders for standalone style files (outside of .vue)\nexports.styleLoaders = function (options) {\n const output = []\n const loaders = exports.cssLoaders(options)\n\n for (const extension in loaders) {\n const loader = loaders[extension]\n output.push({\n test: new RegExp('\\\\.' + extension + '
),\n use: loader\n })\n }\n\n return output\n}\n\nexports.createNotifierCallback = () =\u003E {\n const notifier = require('node-notifier')\n\n return (severity, errors) =\u003E {\n if (severity !== 'error') return\n\n const error = errors[0]\n const filename = error.file && error.file.split('!').pop()\n\n notifier.notify({\n title: packageConfig.name,\n message: severity + ': ' + error.name,\n subtitle: filename || '',\n icon: path.join(__dirname, 'logo.png')\n })\n }\n}\n","id":"mod_5U4wrADvSBBM92RhfF3CU3","is_binary":false,"title":"utils.js","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"r1elO2prQ3Q","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":"Skgd3aSm3m"},{"code":"https:\u002F\u002Frawcdn.githack.com\u002FKrutie\u002Fsmashing-mag-tdf-tutorial\u002F870994f88727ea136e8b1692ef052a2c87d126cb\u002Fbuild\u002Flogo.png","id":"mod_941LdJtxquyGDHqfmKTren","is_binary":true,"title":"logo.png","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"Byyxu26rm3m","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":"Skgd3aSm3m"},{"code":"'use strict'\nconst chalk = require('chalk')\nconst semver = require('semver')\nconst packageConfig = require('..\u002Fpackage.json')\nconst shell = require('shelljs')\n\nfunction exec (cmd) {\n return require('child_process').execSync(cmd).toString().trim()\n}\n\nconst versionRequirements = [\n {\n name: 'node',\n currentVersion: semver.clean(process.version),\n versionRequirement: packageConfig.engines.node\n }\n]\n\nif (shell.which('npm')) {\n versionRequirements.push({\n name: 'npm',\n currentVersion: exec('npm --version'),\n versionRequirement: packageConfig.engines.npm\n })\n}\n\nmodule.exports = function () {\n const warnings = []\n\n for (let i = 0; i \u003C versionRequirements.length; i++) {\n const mod = versionRequirements[i]\n\n if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {\n warnings.push(mod.name + ': ' +\n chalk.red(mod.currentVersion) + ' should be ' +\n chalk.green(mod.versionRequirement)\n )\n }\n }\n\n if (warnings.length) {\n console.log('')\n console.log(chalk.yellow('To use this template, you must update following to modules:'))\n console.log()\n\n for (let i = 0; i \u003C warnings.length; i++) {\n const warning = warnings[i]\n console.log(' ' + warning)\n }\n\n console.log()\n process.exit(1)\n }\n}\n","id":"mod_MKXyRinier9JjGcdFjht6p","is_binary":false,"title":"check-versions.js","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"SyAOnaHQ3m","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":"Skgd3aSm3m"},{"code":"'use strict'\nrequire('.\u002Fcheck-versions')()\n\nprocess.env.NODE_ENV = 'production'\n\nconst ora = require('ora')\nconst rm = require('rimraf')\nconst path = require('path')\nconst chalk = require('chalk')\nconst webpack = require('webpack')\nconst config = require('..\u002Fconfig')\nconst webpackConfig = require('.\u002Fwebpack.prod.conf')\n\nconst spinner = ora('building for production...')\nspinner.start()\n\nrm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err =\u003E {\n if (err) throw err\n webpack(webpackConfig, (err, stats) =\u003E {\n spinner.stop()\n if (err) throw err\n process.stdout.write(stats.toString({\n colors: true,\n modules: false,\n children: false, \u002F\u002F If you are using ts-loader, setting this to true will make TypeScript errors show up during build.\n chunks: false,\n chunkModules: false\n }) + '\\n\\n')\n\n if (stats.hasErrors()) {\n console.log(chalk.red(' Build failed with errors.\\n'))\n process.exit(1)\n }\n\n console.log(chalk.cyan(' Build complete.\\n'))\n console.log(chalk.yellow(\n ' Tip: built files are meant to be served over an HTTP server.\\n' +\n ' Opening index.html over file:\u002F\u002F won\\'t work.\\n'\n ))\n })\n})\n","id":"mod_AhcSF3cLhT29sfEmRkVrW4","is_binary":false,"title":"build.js","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"ByTdhTHXhQ","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":"Skgd3aSm3m"},{"code":"\u002F\u002F https:\u002F\u002Fgithub.com\u002Fmichael-ciniawsky\u002Fpostcss-load-config\n\nmodule.exports = {\n \"plugins\": {\n \"postcss-import\": {},\n \"postcss-url\": {},\n \u002F\u002F to edit target browsers: use \"browserslist\" field in package.json\n \"autoprefixer\": {}\n }\n}\n","id":"mod_Cii4XrajRVffF5QqLJU3bF","is_binary":false,"title":".postcssrc.js","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"ByoO2aSQ37","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":null},{"code":".DS_Store\nnode_modules\u002F\n\u002Fdist\u002F\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\u002Ftest\u002Funit\u002Fcoverage\u002F\n\n# Editor directories and files\n.idea\n.vscode\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n","id":"mod_HLYjyZe6rE31Z7TKmHmpiu","is_binary":false,"title":".gitignore","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"ry9dn6SXnQ","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":null},{"code":"\u002F\u002F https:\u002F\u002Feslint.org\u002Fdocs\u002Fuser-guide\u002Fconfiguring\n\nmodule.exports = {\n root: true,\n parserOptions: {\n parser: 'babel-eslint'\n },\n env: {\n browser: true,\n },\n \u002F\u002F https:\u002F\u002Fgithub.com\u002Fvuejs\u002Feslint-plugin-vue#priority-a-essential-error-prevention\n \u002F\u002F consider switching to `plugin:vue\u002Fstrongly-recommended` or `plugin:vue\u002Frecommended` for stricter rules.\n extends: ['plugin:vue\u002Fessential', 'airbnb-base'],\n \u002F\u002F required to lint *.vue files\n plugins: [\n 'vue'\n ],\n \u002F\u002F check if imports actually resolve\n settings: {\n 'import\u002Fresolver': {\n webpack: {\n config: 'build\u002Fwebpack.base.conf.js'\n }\n }\n },\n \u002F\u002F add your custom rules here\n rules: {\n \u002F\u002F don't require .vue extension when importing\n 'import\u002Fextensions': ['error', 'always', {\n js: 'never',\n vue: 'never'\n }],\n \u002F\u002F disallow reassignment of function parameters\n \u002F\u002F disallow parameter object manipulation except for specific exclusions\n 'no-param-reassign': ['error', {\n props: true,\n ignorePropertyModificationsFor: [\n 'state', \u002F\u002F for vuex state\n 'acc', \u002F\u002F for reduce accumulators\n 'e' \u002F\u002F for e.returnvalue\n ]\n }],\n \u002F\u002F allow optionalDependencies\n 'import\u002Fno-extraneous-dependencies': ['error', {\n optionalDependencies: ['test\u002Funit\u002Findex.js']\n }],\n \u002F\u002F allow debugger during development\n 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'\n }\n}\n","id":"mod_2okPPN88FqrnVB1gsbyMbE","is_binary":false,"title":".eslintrc.js","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"rJF_h6S7hQ","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":null},{"code":"\u002Fbuild\u002F\n\u002Fconfig\u002F\n\u002Fdist\u002F\n\u002F*.js\n\u002Ftest\u002Funit\u002Fcoverage\u002F\n","id":"mod_RcMSxs9LvPxoZy9bnnw9me","is_binary":false,"title":".eslintignore","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"Sk_unaSQn7","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":null},{"code":"root = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n","id":"mod_UKKZTiUSQkAHqu3pzeg3Xg","is_binary":false,"title":".editorconfig","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"BJPO2TBX37","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":null},{"code":"{\n \"presets\": [\n [\"env\", {\n \"modules\": false,\n \"targets\": {\n \"browsers\": [\"\u003E 1%\", \"last 2 versions\", \"not ie \u003C= 8\"]\n }\n }],\n \"stage-2\"\n ],\n \"plugins\": [\"transform-vue-jsx\", \"transform-runtime\"],\n \"env\": {\n \"test\": {\n \"presets\": [\"env\", \"stage-2\"],\n \"plugins\": [\"transform-vue-jsx\", \"transform-es2015-modules-commonjs\", \"dynamic-import-node\"]\n }\n }\n}\n","id":"mod_MhqvX2BqW2VF7uUhN1CQQ1","is_binary":false,"title":".babelrc","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"S1UO3aSm3Q","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":null},{"code":null,"id":"mod_Dt23TqFZTVcoPhT5zPZJN","is_binary":false,"title":".keep","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","upload_id":null,"shortid":"Syrd2aSmh7","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":"HJunaBQ2Q"},{"code":"\u003Ctemplate\u003E\n \u003Cg\u003E\n \u003Cpath id=\"rear-text-path-outer\" fill=\"none\" stroke=\"none\" stroke-miterlimit=\"10\" d=\"M48.545,377.883\n\t\tc-44.914-44.914-44.914-117.715,0-162.628c44.914-44.914,117.715-44.914,162.628,0c44.914,44.913,44.914,117.715,0,162.628\n\t\tc-42.107,42.107-108.724,44.737-153.894,7.895\"\u002F\u003E\n\n \u003Ctext\u003E\n \u003CtextPath xlink:href=\"#rear-text-path-outer\" startOffset=\"0%\" class=\"stageDetail\" fill=\"#673AB7\" \u003E\n {{ stage.WINNER }} wins {{ stage.NAME }} - {{ stage.KEY_MOMENT }}\n \u003C\u002FtextPath\u003E\n \u003C\u002Ftext\u003E\n \n \u003Ctext id=\"title\" class=\"title\" transform=\"matrix(1 0 0 1 13.6172 31.4097)\" fill=\"#673AB7\" font-family=\"'MyriadPro-Regular'\" font-size=\"21\"\u003E\n TOUR DE FRANCE 2017 * 104th Edition * 3540 Kilometres\u003C\u002Ftext\u003E\n \u003Ctext id=\"route-detail\" class=\"route\" transform=\"matrix(1 0 0 1 15.6172 56.3921)\" fill=\"#E91E63\" font-family=\"'MyriadPro-Regular'\" font-size=\"14\"\u003E\n {{ stage.DISTANCE }} KM * {{ stage.ROUTE }} * {{ stage.TYPE }} Route \n \u003C\u002Ftext\u003E\n\n \u003Ctext id=\"date\" class=\"date\" transform=\"matrix(1 0 0 1 15.6172 80.8945)\" fill=\"#79CDF7\" font-family=\"'MyriadPro-Regular'\" font-size=\"14\"\u003E\n {{ stage.DATE }}\n \u003C\u002Ftext\u003E\n\n \u003Crect x=\"15\" y=\"65\" class=\"distance\" :width=\"stage.DISTANCE\" height=\"2\" rx=\"1\" fill=\"#59b9f5\" \u002F\u003E\n \u003C\u002Fg\u003E\n\u003C\u002Ftemplate\u003E\n\n\u003Cscript\u003E\nimport { mapGetters } from 'vuex'\nexport default {\n name: 'stagedetail',\n computed: {\n ...mapGetters({\n stage: 'getActiveStage'\n })\n }\n}\n\u003C\u002Fscript\u003E\n\n\u003C!-- Add \"scoped\" attribute to limit CSS to this component only --\u003E\n\u003Cstyle scoped\u003E\n.title { fill: #673AB7; }\ntext { fill:#232321; font-size: 12px; }\n.route, .date, .stageDetail { opacity: 0; font-size: 10px;}\n\u003C\u002Fstyle\u003E","id":"mod_44NxooCAax7ejg9rkDwZm5","is_binary":false,"title":"stagedetail.vue","sha":null,"inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-29T14:00:05","upload_id":null,"shortid":"Byb-dnaHQ2X","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":"SkEd36H7hm"}],"ai_consent":false,"fork_count":38,"tags":[],"forked_from_sandbox":{"alias":"immutable-mountain-mm12nk798y","id":"mm12nk798y","title":"tdf2017-interactive-infographic","template":"vue-cli","inserted_at":"2018-10-28T14:54:40","updated_at":"2019-06-13T22:33:48","git":{"path":"","branch":"master","repo":"smashing-mag-tdf-tutorial","username":"Krutie","commit_sha":"5745c590f00ede30c66991c720c0279ce44c5c30"},"privacy":0,"custom_template":null},"inserted_at":"2018-10-28T14:55:55","version":14,"restrictions":{"free_plan_editing_restricted":false,"live_sessions_restricted":true},"npm_registries":[],"original_git":{"path":"","branch":"master","repo":"smashing-mag-tdf-tutorial","username":"Krutie","commit_sha":"5745c590f00ede30c66991c720c0279ce44c5c30"},"room_id":null,"view_count":13122,"screenshot_url":"https:\u002F\u002Fscreenshots.codesandbox.io\u002Fy2kx79mnrv\u002F14.png","npm_dependencies":{},"privacy":0,"preview_secret":null,"original_git_commit_sha":"bce18dde585961a8a06252188bfae52a8102707e","git":null,"external_resources":[],"alias":null,"feature_flags":{"comments":false,"container_lsp":false},"base_git":null,"template":"vue-cli","v2":false,"forked_template":null,"authorization":"read","entry":"src\u002Fmain.js","author":{"id":"user_4Gd8rW5DXAiEBC4fydqxDJ","name":"Krutie Patel","username":"Krutie","avatar_url":"https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F19180970?v=4","personal_workspace_id":"ws_SfiXF5ZdpBcGrbAny5jp1x","subscription_plan":null,"subscription_since":null},"title":"tdf2017-interactive-infographic","custom_template":null,"id":"y2kx79mnrv","restricted":false,"forked_template_sandbox":null,"pr_number":null,"permissions":{"prevent_sandbox_export":false,"prevent_sandbox_leaving":false},"directories":[{"id":"dir_6DRvchaKvxShZGNJFCXXWd","title":"components","inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","shortid":"SkEd36H7hm","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":"B1fu26Bm27"},{"id":"dir_C6yGaFT6H4NBTNseufitEt","title":"assets","inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","shortid":"rkQOhaS737","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":"B1fu26Bm27"},{"id":"dir_3xEuUotQhdY4ru399uWdhh","title":"src","inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","shortid":"B1fu26Bm27","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":null},{"id":"dir_CzU1J9n4WhFkhJpokiDrhu","title":"config","inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","shortid":"BJWOharX3X","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":null},{"id":"dir_84Jgs5jPSSb8GDH58pscRK","title":"build","inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","shortid":"Skgd3aSm3m","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":null},{"id":"dir_8gbe8kxp8DBKycBYvYqNrj","title":"static","inserted_at":"2018-10-28T14:55:55","updated_at":"2018-10-28T14:55:55","shortid":"HJunaBQ2Q","source_id":"src_Ea8tnAm52cMcrHUre2UE7c","directory_shortid":null}],"source_id":"src_Ea8tnAm52cMcrHUre2UE7c","owned":false,"is_sse":false,"like_count":21,"collection":false,"draft":false,"user_liked":false,"is_frozen":true,"always_on":false};