├── .gitignore
├── README.md
├── build
├── setup-dev-server.js
├── vue-loader.config.js
├── webpack.base.config.js
├── webpack.client.config.js
└── webpack.server.config.js
├── dist
├── service-worker.js
├── vendor.87c5eed709b22da7e20a.js
├── vue-ssr-client-manifest.json
└── vue-ssr-server-bundle.json
├── manifest.json
├── package.json
├── public
├── logo-120.png
├── logo-144.png
├── logo-152.png
├── logo-192.png
├── logo-256.png
├── logo-384.png
├── logo-48.png
└── logo-512.png
├── server.js
├── src
├── App.vue
├── api
│ ├── create-api-client.ts
│ ├── create-api-server.ts
│ └── index.ts
├── app.ts
├── components
│ ├── Comment.vue
│ ├── Item.vue
│ ├── ProgressBar.vue
│ └── Spinner.vue
├── entry-client.ts
├── entry-server.ts
├── index.template.html
├── public
│ ├── logo-120.png
│ ├── logo-144.png
│ ├── logo-152.png
│ ├── logo-192.png
│ ├── logo-256.png
│ ├── logo-384.png
│ ├── logo-48.png
│ └── logo-512.png
├── router
│ └── index.ts
├── store
│ ├── actions.ts
│ ├── getters.ts
│ ├── index.ts
│ └── mutations.ts
├── util
│ ├── filters.ts
│ └── title.ts
├── views
│ ├── CreateListView.ts
│ ├── ItemList.vue
│ ├── ItemView.vue
│ └── UserView.vue
└── vue-shims.d.ts
├── tsconfig.json
├── tslint.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log
5 | yarn-error.log
6 | .idea
7 | *.iml
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-hackernews-2.0 with TypeScript
2 |
3 | HackerNews clone built with TypeScript + Vue 2.0 + vue-router + vuex, with server-side rendering.
4 |
5 |
6 |
7 |
8 |
9 | Live Demo
10 |
11 |
12 |
13 | ## Features
14 |
15 | > Note: in practice, it is unnecessary to code-split for an app of this size (where each async chunk is only a few kilobytes), nor is it optimal to extract an extra CSS file (which is only 1kb) -- they are used simply because this is a demo app showcasing all the supported features. In real apps, you should always measure and optimize based on your actual app constraints.
16 |
17 | - Server Side Rendering
18 | - Vue + vue-router + vuex working together
19 | - Server-side data pre-fetching
20 | - Client-side state & DOM hydration
21 | - Automatically inlines CSS used by rendered components only
22 | - Preload / prefetch resource hints
23 | - Route-level code splitting
24 | - Progressive Web App
25 | - App manifest
26 | - Service worker
27 | - 100/100 Lighthouse score
28 | - Single-file Vue Components
29 | - Hot-reload in development
30 | - CSS extraction for production
31 | - Animation
32 | - Effects when switching route views
33 | - Real-time list updates with FLIP Animation
34 |
35 | ## Architecture Overview
36 |
37 |
38 |
39 | **A detailed Vue SSR guide can be found [here](https://ssr.vuejs.org).**
40 |
41 | ## Build Setup
42 |
43 | **Requires Node.js 7+**
44 |
45 | ``` bash
46 | # install dependencies
47 | npm install # or yarn
48 |
49 | # serve in dev mode, with hot reload at localhost:8080
50 | npm run dev
51 |
52 | # build for production
53 | npm run build
54 |
55 | # serve in production mode
56 | npm start
57 | ```
58 |
59 | ## License
60 |
61 | MIT
62 |
--------------------------------------------------------------------------------
/build/setup-dev-server.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const MFS = require('memory-fs')
4 | const webpack = require('webpack')
5 | const chokidar = require('chokidar')
6 | const clientConfig = require('./webpack.client.config')
7 | const serverConfig = require('./webpack.server.config')
8 |
9 | const readFile = (fs, file) => {
10 | try {
11 | return fs.readFileSync(path.join(clientConfig.output.path, file), 'utf-8')
12 | } catch (e) {}
13 | }
14 |
15 | module.exports = function setupDevServer (app, templatePath, cb) {
16 | let bundle
17 | let template
18 | let clientManifest
19 |
20 | let ready
21 | const readyPromise = new Promise(r => { ready = r })
22 | const update = () => {
23 | if (bundle && clientManifest) {
24 | ready()
25 | cb(bundle, {
26 | template,
27 | clientManifest
28 | })
29 | }
30 | }
31 |
32 | // read template from disk and watch
33 | template = fs.readFileSync(templatePath, 'utf-8')
34 | chokidar.watch(templatePath).on('change', () => {
35 | template = fs.readFileSync(templatePath, 'utf-8')
36 | console.log('index.html template updated.')
37 | update()
38 | })
39 |
40 | // modify client config to work with hot middleware
41 | clientConfig.entry.app = ['webpack-hot-middleware/client', clientConfig.entry.app]
42 | clientConfig.output.filename = '[name].js'
43 | clientConfig.plugins.push(
44 | new webpack.HotModuleReplacementPlugin(),
45 | new webpack.NoEmitOnErrorsPlugin()
46 | )
47 |
48 | // dev middleware
49 | const clientCompiler = webpack(clientConfig)
50 | const devMiddleware = require('webpack-dev-middleware')(clientCompiler, {
51 | publicPath: clientConfig.output.publicPath,
52 | noInfo: true
53 | })
54 | app.use(devMiddleware)
55 | clientCompiler.plugin('done', stats => {
56 | stats = stats.toJson()
57 | stats.errors.forEach(err => console.error(err))
58 | stats.warnings.forEach(err => console.warn(err))
59 | if (stats.errors.length) return
60 | clientManifest = JSON.parse(readFile(
61 | devMiddleware.fileSystem,
62 | 'vue-ssr-client-manifest.json'
63 | ))
64 | update()
65 | })
66 |
67 | // hot middleware
68 | app.use(require('webpack-hot-middleware')(clientCompiler, { heartbeat: 5000 }))
69 |
70 | // watch and update server renderer
71 | const serverCompiler = webpack(serverConfig)
72 | const mfs = new MFS()
73 | serverCompiler.outputFileSystem = mfs
74 | serverCompiler.watch({}, (err, stats) => {
75 | if (err) throw err
76 | stats = stats.toJson()
77 | if (stats.errors.length) return
78 |
79 | // read bundle generated by vue-ssr-webpack-plugin
80 | bundle = JSON.parse(readFile(mfs, 'vue-ssr-server-bundle.json'))
81 | update()
82 | })
83 |
84 | return readyPromise
85 | }
86 |
--------------------------------------------------------------------------------
/build/vue-loader.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | loaders: {
3 | // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
4 | // the "scss" and "sass" values for the lang attribute to the right configs here.
5 | // other preprocessors should work out of the box, no loader config like this necessary.
6 | 'scss': 'vue-style-loader!css-loader!sass-loader',
7 | 'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
8 | },
9 | // other vue-loader options go here
10 | // from vue config
11 | extractCSS: process.env.NODE_ENV === 'production',
12 | preserveWhitespace: false,
13 | postcss: [
14 | require('autoprefixer')({
15 | browsers: ['last 3 versions']
16 | })
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/build/webpack.base.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const vueConfig = require('./vue-loader.config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
6 |
7 | const isProd = process.env.NODE_ENV === 'production'
8 |
9 | module.exports = {
10 | devtool: isProd
11 | ? false
12 | : '#cheap-module-source-map',
13 | output: {
14 | path: path.resolve(__dirname, '../dist'),
15 | publicPath: '/dist/',
16 | filename: '[name].[chunkhash].js'
17 | },
18 | resolve: {
19 | alias: {
20 | 'public': path.resolve(__dirname, '../public')
21 | }
22 | },
23 | module: {
24 | noParse: /es6-promise\.js$/, // avoid webpack shimming process
25 | rules: [
26 | {
27 | test: /\.vue$/,
28 | loader: 'vue-loader',
29 | options: vueConfig
30 | },
31 | {
32 | test: /\.tsx?$/,
33 | loader: 'ts-loader',
34 | exclude: /node_modules/,
35 | options: {
36 | appendTsSuffixTo: [/\.vue$/],
37 | }
38 | },
39 | {
40 | test: /\.js$/,
41 | loader: 'babel-loader',
42 | exclude: /node_modules/
43 | },
44 | {
45 | test: /\.(png|jpg|gif|svg)$/,
46 | loader: 'url-loader',
47 | options: {
48 | limit: 10000,
49 | name: '[name].[ext]?[hash]'
50 | }
51 | },
52 | {
53 | test: /\.css$/,
54 | use: isProd
55 | ? ExtractTextPlugin.extract({
56 | use: 'css-loader?minimize',
57 | fallback: 'vue-style-loader'
58 | })
59 | : ['vue-style-loader', 'css-loader']
60 | }
61 | ]
62 | },
63 | resolve: {
64 | extensions: ['.ts', '.js', '.vue', '.json'],
65 | alias: {
66 | 'vue$': 'vue/dist/vue.esm.js'
67 | }
68 | },
69 | performance: {
70 | maxEntrypointSize: 300000,
71 | hints: isProd ? 'warning' : false
72 | },
73 | plugins: isProd
74 | ? [
75 | new webpack.optimize.UglifyJsPlugin({
76 | compress: { warnings: false }
77 | }),
78 | new webpack.optimize.ModuleConcatenationPlugin(),
79 | new ExtractTextPlugin({
80 | filename: 'common.[chunkhash].css'
81 | })
82 | ]
83 | : [
84 | new FriendlyErrorsPlugin()
85 | ]
86 | }
87 |
--------------------------------------------------------------------------------
/build/webpack.client.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const merge = require('webpack-merge')
3 | const base = require('./webpack.base.config')
4 | const SWPrecachePlugin = require('sw-precache-webpack-plugin')
5 | const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
6 |
7 | const config = merge(base, {
8 | entry: {
9 | app: './src/entry-client.ts'
10 | },
11 | resolve: {
12 | alias: {
13 | 'create-api': './create-api-client.ts'
14 | }
15 | },
16 | plugins: [
17 | // strip dev-only code in Vue source
18 | new webpack.DefinePlugin({
19 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
20 | 'process.env.VUE_ENV': '"client"'
21 | }),
22 | // extract vendor chunks for better caching
23 | new webpack.optimize.CommonsChunkPlugin({
24 | name: 'vendor',
25 | minChunks: function (module) {
26 | // a module is extracted into the vendor chunk if...
27 | return (
28 | // it's inside node_modules
29 | /node_modules/.test(module.context) &&
30 | // and not a CSS file (due to extract-text-webpack-plugin limitation)
31 | !/\.css$/.test(module.request)
32 | )
33 | }
34 | }),
35 | // extract webpack runtime & manifest to avoid vendor chunk hash changing
36 | // on every build.
37 | new webpack.optimize.CommonsChunkPlugin({
38 | name: 'manifest'
39 | }),
40 | new VueSSRClientPlugin()
41 | ]
42 | })
43 |
44 | if (process.env.NODE_ENV === 'production') {
45 | config.plugins.push(
46 | // auto generate service worker
47 | new SWPrecachePlugin({
48 | cacheId: 'vue-hn',
49 | filename: 'service-worker.js',
50 | minify: true,
51 | dontCacheBustUrlsMatching: /./,
52 | staticFileGlobsIgnorePatterns: [/\.map$/, /\.json$/],
53 | runtimeCaching: [
54 | {
55 | urlPattern: '/',
56 | handler: 'networkFirst'
57 | },
58 | {
59 | urlPattern: /\/(top|new|show|ask|jobs)/,
60 | handler: 'networkFirst'
61 | },
62 | {
63 | urlPattern: '/item/:id',
64 | handler: 'networkFirst'
65 | },
66 | {
67 | urlPattern: '/user/:id',
68 | handler: 'networkFirst'
69 | }
70 | ]
71 | })
72 | )
73 | }
74 |
75 | module.exports = config
76 |
--------------------------------------------------------------------------------
/build/webpack.server.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const merge = require('webpack-merge')
3 | const base = require('./webpack.base.config')
4 | const nodeExternals = require('webpack-node-externals')
5 | const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')
6 |
7 | module.exports = merge(base, {
8 | target: 'node',
9 | devtool: '#source-map',
10 | entry: './src/entry-server.ts',
11 | output: {
12 | filename: 'server-bundle.js',
13 | libraryTarget: 'commonjs2'
14 | },
15 | resolve: {
16 | alias: {
17 | 'create-api': './create-api-server.ts'
18 | }
19 | },
20 | // https://webpack.js.org/configuration/externals/#externals
21 | // https://github.com/liady/webpack-node-externals
22 | externals: nodeExternals({
23 | // do not externalize CSS files in case we need to import it from a dep
24 | whitelist: /\.css$/
25 | }),
26 | plugins: [
27 | new webpack.DefinePlugin({
28 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
29 | 'process.env.VUE_ENV': '"server"'
30 | }),
31 | new VueSSRServerPlugin()
32 | ]
33 | })
34 |
--------------------------------------------------------------------------------
/dist/service-worker.js:
--------------------------------------------------------------------------------
1 | "use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/dist/0.2f24aad406604a1cb8f6.js","517c26c1e33c0fe622c51593542e1046"],["/dist/1.a394bb868e28da65444d.js","f25dd6bd70766f6aeeb47ea5b2bd0586"],["/dist/2.6162be221be2a6f3574b.js","a7b401488e7db310895bbbe764e589de"],["/dist/app.22a57857d70ec6affd9f.js","6e6f0563098cf868f7605170c1bbcc36"],["/dist/common.22a57857d70ec6affd9f.css","94102f54b8f8a3d2fa68f67390d0e18d"],["/dist/manifest.2a797793b2b38824bdbb.js","7892db841ebe2b2d0b77a28234b41a21"],["/dist/vendor.87c5eed709b22da7e20a.js","b64d3f58de192911d7fd5ba250c9466f"]],cacheName="sw-precache-v3-vue-hn-"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){if(!e.redirected)return Promise.resolve(e);return("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})})},createCacheKey=function(e,t,n,r){var o=new URL(e);return r&&o.pathname.match(r)||(o.search+=(o.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),o.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),o=createCacheKey(r,hashParamName,n,/./);return[r.toString(),o]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching),r="index.html";(t=urlsToCacheKeys.has(n))||(n=addDirectoryIndex(n,r),t=urlsToCacheKeys.has(n));0,t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).toolbox=e()}}(function(){return function e(t,n,r){function o(i,s){if(!n[i]){if(!t[i]){var c="function"==typeof require&&require;if(!s&&c)return c(i,!0);if(a)return a(i,!0);var u=new Error("Cannot find module '"+i+"'");throw u.code="MODULE_NOT_FOUND",u}var f=n[i]={exports:{}};t[i][0].call(f.exports,function(e){var n=t[i][1][e];return o(n||e)},f,f.exports,e,t,n,r)}return n[i].exports}for(var a="function"==typeof require&&require,i=0;it.value[s]){var r=t.value[i];u.push(r),h.delete(r),t.continue()}},f.oncomplete=function(){r(u)},f.onabort=o}):Promise.resolve([])}(e,n,r).then(function(n){return function(e,t){return t?new Promise(function(n,r){var o=[],c=e.transaction(a,"readwrite"),u=c.objectStore(a),f=u.index(s),h=f.count();f.count().onsuccess=function(){var e=h.result;e>t&&(f.openCursor().onsuccess=function(n){var r=n.target.result;if(r){var a=r.value[i];o.push(a),u.delete(a),e-o.length>t&&r.continue()}})},c.oncomplete=function(){n(o)},c.onabort=r}):Promise.resolve([])}(e,t).then(function(e){return n.concat(e)})})}}},{}],3:[function(e,t,n){function r(e){return e.reduce(function(e,t){return e.concat(t)},[])}e("serviceworker-cache-polyfill");var o=e("./helpers"),a=e("./router"),i=e("./options");t.exports={fetchListener:function(e){var t=a.match(e.request);t?e.respondWith(t(e.request)):a.default&&"GET"===e.request.method&&0===e.request.url.indexOf("http")&&e.respondWith(a.default(e.request))},activateListener:function(e){o.debug("activate event fired");var t=i.cache.name+"$$$inactive$$$";e.waitUntil(o.renameCache(t,i.cache.name))},installListener:function(e){var t=i.cache.name+"$$$inactive$$$";o.debug("install event fired"),o.debug("creating cache ["+t+"]"),e.waitUntil(o.openCache({cache:{name:t}}).then(function(e){return Promise.all(i.preCacheItems).then(r).then(o.validatePrecacheInput).then(function(t){return o.debug("preCache list: "+(t.join(", ")||"(none)")),e.addAll(t)})}))}}},{"./helpers":1,"./options":4,"./router":6,"serviceworker-cache-polyfill":16}],4:[function(e,t,n){var r;r=self.registration?self.registration.scope:self.scope||new URL("./",self.location).href,t.exports={cache:{name:"$$$toolbox-cache$$$"+r+"$$$",maxAgeSeconds:null,maxEntries:null},debug:!1,networkTimeoutSeconds:null,preCacheItems:[],successResponses:/^0|([123]\d\d)|(40[14567])|410$/}},{}],5:[function(e,t,n){var r=new URL("./",self.location).pathname,o=e("path-to-regexp"),a=function(e,t,n,a){t instanceof RegExp?this.fullUrlRegExp=t:(0!==t.indexOf("/")&&(t=r+t),this.keys=[],this.regexp=o(t,this.keys)),this.method=e,this.options=a,this.handler=n};a.prototype.makeHandler=function(e){var t;if(this.regexp){var n=this.regexp.exec(e);t={},this.keys.forEach(function(e,r){t[e.name]=n[r+1]})}return function(e){return this.handler(e,t,this.options)}.bind(this)},t.exports=a},{"path-to-regexp":15}],6:[function(e,t,n){var r=e("./route"),o=e("./helpers"),a=function(e,t){for(var n=e.entries(),r=n.next(),o=[];!r.done;){new RegExp(r.value[0]).test(t)&&o.push(r.value[1]),r=n.next()}return o},i=function(){this.routes=new Map,this.routes.set(RegExp,new Map),this.default=null};["get","post","put","delete","head","any"].forEach(function(e){i.prototype[e]=function(t,n,r){return this.add(e,t,n,r)}}),i.prototype.add=function(e,t,n,a){a=a||{};var i;t instanceof RegExp?i=RegExp:(i=a.origin||self.location.origin,i=i instanceof RegExp?i.source:function(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}(i)),e=e.toLowerCase();var s=new r(e,t,n,a);this.routes.has(i)||this.routes.set(i,new Map);var c=this.routes.get(i);c.has(e)||c.set(e,new Map);var u=c.get(e),f=s.regexp||s.fullUrlRegExp;u.has(f.source)&&o.debug('"'+t+'" resolves to same regex as existing route.'),u.set(f.source,s)},i.prototype.matchMethod=function(e,t){var n=new URL(t),r=n.origin,o=n.pathname;return this._match(e,a(this.routes,r),o)||this._match(e,[this.routes.get(RegExp)],t)},i.prototype._match=function(e,t,n){if(0===t.length)return null;for(var r=0;r0)return s[0].makeHandler(n)}}return null},i.prototype.match=function(e){return this.matchMethod(e.method,e.url)||this.matchMethod("any",e.url)},t.exports=new i},{"./helpers":1,"./route":5}],7:[function(e,t,n){var r=e("../options"),o=e("../helpers");t.exports=function(e,t,n){return n=n||{},o.debug("Strategy: cache first ["+e.url+"]",n),o.openCache(n).then(function(t){return t.match(e).then(function(t){var a=n.cache||r.cache,i=Date.now();return o.isResponseFresh(t,a.maxAgeSeconds,i)?t:o.fetchAndCache(e,n)})})}},{"../helpers":1,"../options":4}],8:[function(e,t,n){var r=e("../options"),o=e("../helpers");t.exports=function(e,t,n){return n=n||{},o.debug("Strategy: cache only ["+e.url+"]",n),o.openCache(n).then(function(t){return t.match(e).then(function(e){var t=n.cache||r.cache,a=Date.now();if(o.isResponseFresh(e,t.maxAgeSeconds,a))return e})})}},{"../helpers":1,"../options":4}],9:[function(e,t,n){var r=e("../helpers"),o=e("./cacheOnly");t.exports=function(e,t,n){return r.debug("Strategy: fastest ["+e.url+"]",n),new Promise(function(a,i){var s=!1,c=[],u=function(e){c.push(e.toString()),s?i(new Error('Both cache and network failed: "'+c.join('", "')+'"')):s=!0},f=function(e){e instanceof Response?a(e):u("No result returned")};r.fetchAndCache(e.clone(),n).then(f,u),o(e,t,n).then(f,u)})}},{"../helpers":1,"./cacheOnly":8}],10:[function(e,t,n){t.exports={networkOnly:e("./networkOnly"),networkFirst:e("./networkFirst"),cacheOnly:e("./cacheOnly"),cacheFirst:e("./cacheFirst"),fastest:e("./fastest")}},{"./cacheFirst":7,"./cacheOnly":8,"./fastest":9,"./networkFirst":11,"./networkOnly":12}],11:[function(e,t,n){var r=e("../options"),o=e("../helpers");t.exports=function(e,t,n){var a=(n=n||{}).successResponses||r.successResponses,i=n.networkTimeoutSeconds||r.networkTimeoutSeconds;return o.debug("Strategy: network first ["+e.url+"]",n),o.openCache(n).then(function(t){var s,c,u=[];if(i){var f=new Promise(function(a){s=setTimeout(function(){t.match(e).then(function(e){var t=n.cache||r.cache,i=Date.now(),s=t.maxAgeSeconds;o.isResponseFresh(e,s,i)&&a(e)})},1e3*i)});u.push(f)}var h=o.fetchAndCache(e,n).then(function(e){if(s&&clearTimeout(s),a.test(e.status))return e;throw o.debug("Response was an HTTP error: "+e.statusText,n),c=e,new Error("Bad response")}).catch(function(r){return o.debug("Network or response error, fallback to cache ["+e.url+"]",n),t.match(e).then(function(e){if(e)return e;if(c)return c;throw r})});return u.push(h),Promise.race(u)})}},{"../helpers":1,"../options":4}],12:[function(e,t,n){var r=e("../helpers");t.exports=function(e,t,n){return r.debug("Strategy: network only ["+e.url+"]",n),fetch(e)}},{"../helpers":1}],13:[function(e,t,n){var r=e("./options"),o=e("./router"),a=e("./helpers"),i=e("./strategies"),s=e("./listeners");a.debug("Service Worker Toolbox is loading"),self.addEventListener("install",s.installListener),self.addEventListener("activate",s.activateListener),self.addEventListener("fetch",s.fetchListener),t.exports={networkOnly:i.networkOnly,networkFirst:i.networkFirst,cacheOnly:i.cacheOnly,cacheFirst:i.cacheFirst,fastest:i.fastest,router:o,options:r,cache:a.cache,uncache:a.uncache,precache:a.precache}},{"./helpers":1,"./listeners":3,"./options":4,"./router":6,"./strategies":10}],14:[function(e,t,n){t.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},{}],15:[function(e,t,n){function r(e,t){for(var n,r=[],o=0,a=0,i="",c=t&&t.delimiter||"/";null!=(n=p.exec(e));){var u=n[0],f=n[1],h=n.index;if(i+=e.slice(a,h),a=h+u.length,f)i+=f[1];else{var l=e[a],d=n[2],m=n[3],g=n[4],v=n[5],w=n[6],x=n[7];i&&(r.push(i),i="");var b=null!=d&&null!=l&&l!==d,y="+"===w||"*"===w,E="?"===w||"*"===w,R=n[2]||c,C=g||v;r.push({name:m||o++,prefix:d||"",delimiter:R,optional:E,repeat:y,partial:b,asterisk:!!x,pattern:C?function(e){return e.replace(/([=!:$\/()])/g,"\\$1")}(C):x?".*":"[^"+s(R)+"]+?"})}}return a=46||"Chrome"===n&&r>=50)||(Cache.prototype.addAll=function(e){function t(e){this.name="NetworkError",this.code=19,this.message=e}var n=this;return t.prototype=Object.create(Error.prototype),Promise.resolve().then(function(){if(arguments.length<1)throw new TypeError;return e=e.map(function(e){return e instanceof Request?e:String(e)}),Promise.all(e.map(function(e){"string"==typeof e&&(e=new Request(e));var n=new URL(e.url).protocol;if("http:"!==n&&"https:"!==n)throw new t("Invalid scheme");return fetch(e.clone())}))}).then(function(r){if(r.some(function(e){return!e.ok}))throw new t("Incorrect response status");return Promise.all(r.map(function(t,r){return n.put(e[r],t)}))}).then(function(){})},Cache.prototype.add=function(e){return this.addAll([e])})}()},{}]},{},[13])(13)}),toolbox.router.get("/",toolbox.networkFirst,{}),toolbox.router.get(/\/(top|new|show|ask|jobs)/,toolbox.networkFirst,{}),toolbox.router.get("/item/:id",toolbox.networkFirst,{}),toolbox.router.get("/user/:id",toolbox.networkFirst,{});
--------------------------------------------------------------------------------
/dist/vue-ssr-client-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "publicPath": "/dist/",
3 | "all": [
4 | "0.2f24aad406604a1cb8f6.js",
5 | "1.a394bb868e28da65444d.js",
6 | "2.6162be221be2a6f3574b.js",
7 | "vendor.87c5eed709b22da7e20a.js",
8 | "app.22a57857d70ec6affd9f.js",
9 | "manifest.2a797793b2b38824bdbb.js",
10 | "common.22a57857d70ec6affd9f.css"
11 | ],
12 | "initial": [
13 | "manifest.2a797793b2b38824bdbb.js",
14 | "vendor.87c5eed709b22da7e20a.js",
15 | "app.22a57857d70ec6affd9f.js"
16 | ],
17 | "async": [
18 | "0.2f24aad406604a1cb8f6.js",
19 | "1.a394bb868e28da65444d.js",
20 | "2.6162be221be2a6f3574b.js"
21 | ],
22 | "modules": {
23 | "18554856": [
24 | 3
25 | ],
26 | "26107428": [
27 | 3
28 | ],
29 | "60681088": [
30 | 3
31 | ],
32 | "63589835": [
33 | 3
34 | ],
35 | "64837578": [
36 | 3
37 | ],
38 | "72321131": [
39 | 3
40 | ],
41 | "92237446": [
42 | 3
43 | ],
44 | "63d8a00e": [
45 | 3
46 | ],
47 | "7488318b": [
48 | 3
49 | ],
50 | "a1228330": [
51 | 3
52 | ],
53 | "3211f81a": [
54 | 3
55 | ],
56 | "595c1b98": [
57 | 3
58 | ],
59 | "7eaa0333": [
60 | 3
61 | ],
62 | "f6240d98": [
63 | 3
64 | ],
65 | "0c0e89ca": [
66 | 3
67 | ],
68 | "3010b740": [
69 | 3
70 | ],
71 | "25d9db1e": [
72 | 3
73 | ],
74 | "3c577b5a": [
75 | 3
76 | ],
77 | "253dde61": [
78 | 3
79 | ],
80 | "2dd3a353": [
81 | 3
82 | ],
83 | "69b8167f": [
84 | 3
85 | ],
86 | "27da0154": [
87 | 3
88 | ],
89 | "3c53b216": [
90 | 3
91 | ],
92 | "6312a17c": [
93 | 3
94 | ],
95 | "04235362": [
96 | 3
97 | ],
98 | "f38fefcc": [
99 | 3
100 | ],
101 | "07605bf4": [
102 | 3
103 | ],
104 | "943864de": [
105 | 3
106 | ],
107 | "72c566ee": [
108 | 3
109 | ],
110 | "1a82c847": [
111 | 3
112 | ],
113 | "4da1107e": [
114 | 3
115 | ],
116 | "4acfefde": [
117 | 3
118 | ],
119 | "8de629d4": [
120 | 3
121 | ],
122 | "7c16d37f": [
123 | 3
124 | ],
125 | "ee158976": [
126 | 3
127 | ],
128 | "5db76d60": [
129 | 3
130 | ],
131 | "2e2cc7fd": [
132 | 3
133 | ],
134 | "e3298586": [
135 | 3
136 | ],
137 | "28b2b3ca": [
138 | 3
139 | ],
140 | "0f2f8214": [
141 | 3
142 | ],
143 | "7fa7b23a": [
144 | 3
145 | ],
146 | "f03f18be": [
147 | 3
148 | ],
149 | "6c3e7254": [
150 | 3
151 | ],
152 | "ea7f8e0c": [
153 | 3
154 | ],
155 | "97b9bd5e": [
156 | 3
157 | ],
158 | "2216748b": [
159 | 3
160 | ],
161 | "44f3f8b6": [
162 | 3
163 | ],
164 | "fb7653ea": [
165 | 3
166 | ],
167 | "e68143a2": [
168 | 3
169 | ],
170 | "5e36a3c8": [
171 | 3
172 | ],
173 | "6546b21b": [
174 | 3
175 | ],
176 | "4c384370": [
177 | 3
178 | ],
179 | "4a3de75c": [
180 | 3
181 | ],
182 | "45514fce": [
183 | 3
184 | ],
185 | "09b6a312": [
186 | 3
187 | ],
188 | "0ad593b6": [
189 | 3
190 | ],
191 | "650eee41": [
192 | 3
193 | ],
194 | "940c6b52": [
195 | 3
196 | ],
197 | "19e4dd1f": [
198 | 3
199 | ],
200 | "d6d9128e": [
201 | 3
202 | ],
203 | "521f4902": [
204 | 3
205 | ],
206 | "8618bf6e": [
207 | 3
208 | ],
209 | "f9ce2dae": [
210 | 3
211 | ],
212 | "2f06d400": [
213 | 3
214 | ],
215 | "5b7b1476": [
216 | 4,
217 | 6
218 | ],
219 | "026a70b9": [
220 | 4,
221 | 6
222 | ],
223 | "02ec155f": [
224 | 4,
225 | 6
226 | ],
227 | "6e17334a": [
228 | 3
229 | ],
230 | "20b0aae6": [
231 | 3
232 | ],
233 | "4422b14f": [
234 | 3
235 | ],
236 | "42da7efd": [
237 | 4,
238 | 6
239 | ],
240 | "2310b18a": [
241 | 3
242 | ],
243 | "2c02bf74": [
244 | 3
245 | ],
246 | "8084914e": [
247 | 4,
248 | 6
249 | ],
250 | "f764188e": [
251 | 3
252 | ],
253 | "1cdd45e8": [
254 | 3
255 | ],
256 | "7fb78e35": [
257 | 3
258 | ],
259 | "0b2ae428": [
260 | 3
261 | ],
262 | "2961e65b": [
263 | 3
264 | ],
265 | "55ad5e21": [
266 | 3
267 | ],
268 | "588e4fe2": [
269 | 3
270 | ],
271 | "30e4adc4": [
272 | 3
273 | ],
274 | "09ee3910": [
275 | 3
276 | ],
277 | "18f1c490": [
278 | 3
279 | ],
280 | "07d3c044": [
281 | 3
282 | ],
283 | "8d2828ba": [
284 | 3
285 | ],
286 | "97cf2e44": [
287 | 3
288 | ],
289 | "2eca343e": [
290 | 3
291 | ],
292 | "b96ac82c": [
293 | 3
294 | ],
295 | "32a8aaf2": [
296 | 3
297 | ],
298 | "fd710bda": [
299 | 3
300 | ],
301 | "5c9ff047": [
302 | 3
303 | ],
304 | "b6d71d58": [
305 | 3
306 | ],
307 | "ed0ee3d8": [
308 | 3
309 | ],
310 | "0435b99e": [
311 | 3
312 | ],
313 | "28a38085": [
314 | 3
315 | ],
316 | "0e039a2a": [
317 | 3
318 | ],
319 | "6a207438": [
320 | 3
321 | ],
322 | "5c6e4e1b": [
323 | 3
324 | ],
325 | "b0b463fe": [
326 | 3
327 | ],
328 | "584a70cc": [
329 | 3
330 | ],
331 | "6354dc2a": [
332 | 3
333 | ],
334 | "29574f8b": [
335 | 3
336 | ],
337 | "347b1654": [
338 | 3
339 | ],
340 | "5f2dfc60": [
341 | 3
342 | ],
343 | "5ac3a5d2": [
344 | 3
345 | ],
346 | "1a3d78bd": [
347 | 3
348 | ],
349 | "200679f4": [
350 | 3
351 | ],
352 | "370e3178": [
353 | 3
354 | ],
355 | "6686e9a6": [
356 | 3
357 | ],
358 | "57eb1f0a": [
359 | 3
360 | ],
361 | "6ac500ce": [
362 | 3
363 | ],
364 | "0ef44fce": [
365 | 3
366 | ],
367 | "466de31a": [
368 | 3
369 | ],
370 | "7d67231c": [
371 | 3
372 | ],
373 | "27528dda": [
374 | 3
375 | ],
376 | "263a3e50": [
377 | 3
378 | ],
379 | "8b63dd56": [
380 | 3
381 | ],
382 | "7570d163": [
383 | 3
384 | ],
385 | "c1955f62": [
386 | 3
387 | ],
388 | "6f8d35d8": [
389 | 3
390 | ],
391 | "0e857228": [
392 | 3
393 | ],
394 | "5b7fb14a": [
395 | 3
396 | ],
397 | "9c5e9ba4": [
398 | 3
399 | ],
400 | "c4345e5a": [
401 | 4,
402 | 6
403 | ],
404 | "6a384e62": [
405 | 3
406 | ],
407 | "231cbf2a": [
408 | 3
409 | ],
410 | "2c30cb6a": [
411 | 1
412 | ],
413 | "5b4045b8": [
414 | 1
415 | ],
416 | "083adcf4": [
417 | 1
418 | ],
419 | "a27b3e10": [
420 | 1
421 | ],
422 | "c425ac3a": [
423 | 0
424 | ],
425 | "6606b79e": [
426 | 0
427 | ],
428 | "4fb61960": [
429 | 0
430 | ],
431 | "1ac3bcae": [
432 | 0
433 | ],
434 | "0bdd6e24": [
435 | 0
436 | ],
437 | "5229dd1c": [
438 | 0
439 | ],
440 | "62944f18": [
441 | 2
442 | ],
443 | "dcb86d34": [
444 | 2
445 | ],
446 | "06fec79e": [
447 | 1
448 | ],
449 | "fcaed122": [
450 | 0
451 | ],
452 | "e1717f6e": [
453 | 2
454 | ]
455 | }
456 | }
--------------------------------------------------------------------------------
/dist/vue-ssr-server-bundle.json:
--------------------------------------------------------------------------------
1 | {
2 | "entry": "server-bundle.js",
3 | "files": {
4 | "0.server-bundle.js": "exports.ids=[0],exports.modules={19:function(e,t,s){var n=s(20);\"string\"==typeof n&&(n=[[e.i,n,\"\"]]),n.locals&&(e.exports=n.locals);var i=s(14);e.exports.__inject__=function(e){i(\"0b48fd67\",n,!0,e)}},20:function(e,t,s){t=e.exports=s(13)(void 0),t.push([e.i,\".item-view-header{background-color:#fff;padding:1.8em 2em 1em;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.1);box-shadow:0 1px 2px rgba(0,0,0,.1)}.item-view-header h1{display:inline;font-size:1.5em;margin:0;margin-right:.5em}.item-view-header .host,.item-view-header .meta,.item-view-header .meta a{color:#828282}.item-view-header .meta a{text-decoration:underline}.item-view-comments{background-color:#fff;margin-top:10px;padding:0 2em .5em}.item-view-comments-header{margin:0;font-size:1.1em;padding:1em 0;position:relative}.item-view-comments-header .spinner{display:inline-block;margin:-15px 0}.comment-children{list-style-type:none;padding:0;margin:0}@media (max-width:600px){.item-view-header h1{font-size:1.25em}}\",\"\"])},21:function(e,t,s){var n=s(22);\"string\"==typeof n&&(n=[[e.i,n,\"\"]]),n.locals&&(e.exports=n.locals);var i=s(14);e.exports.__inject__=function(e){i(\"aa38e5f4\",n,!0,e)}},22:function(e,t,s){t=e.exports=s(13)(void 0),t.push([e.i,\".spinner{-webkit-transition:opacity .15s ease;-o-transition:opacity .15s ease;transition:opacity .15s ease;-webkit-animation:rotator 1.4s linear infinite;animation:rotator 1.4s linear infinite;-webkit-animation-play-state:paused;animation-play-state:paused}.spinner.show{-webkit-animation-play-state:running;animation-play-state:running}.spinner.v-enter,.spinner.v-leave-active{opacity:0}.spinner.v-enter-active,.spinner.v-leave{opacity:1}.spinner .path{stroke:#f60;stroke-dasharray:126;stroke-dashoffset:0;-webkit-transform-origin:center;-ms-transform-origin:center;transform-origin:center;-webkit-animation:dash 1.4s ease-in-out infinite;animation:dash 1.4s ease-in-out infinite}@-webkit-keyframes rotator{0%{-webkit-transform:scale(.5) rotate(0deg);transform:scale(.5) rotate(0deg)}to{-webkit-transform:scale(.5) rotate(270deg);transform:scale(.5) rotate(270deg)}}@keyframes rotator{0%{-webkit-transform:scale(.5) rotate(0deg);transform:scale(.5) rotate(0deg)}to{-webkit-transform:scale(.5) rotate(270deg);transform:scale(.5) rotate(270deg)}}@-webkit-keyframes dash{0%{stroke-dashoffset:126}50%{stroke-dashoffset:63;-webkit-transform:rotate(135deg);transform:rotate(135deg)}to{stroke-dashoffset:126;-webkit-transform:rotate(450deg);transform:rotate(450deg)}}@keyframes dash{0%{stroke-dashoffset:126}50%{stroke-dashoffset:63;-webkit-transform:rotate(135deg);transform:rotate(135deg)}to{stroke-dashoffset:126;-webkit-transform:rotate(450deg);transform:rotate(450deg)}}\",\"\"])},23:function(e,t,s){var n=s(24);\"string\"==typeof n&&(n=[[e.i,n,\"\"]]),n.locals&&(e.exports=n.locals);var i=s(14);e.exports.__inject__=function(e){i(\"c2a61e7c\",n,!0,e)}},24:function(e,t,s){t=e.exports=s(13)(void 0),t.push([e.i,\".comment-children .comment-children{margin-left:1.5em}.comment{border-top:1px solid #eee;position:relative}.comment .by,.comment .text,.comment .toggle{font-size:.9em;margin:1em 0}.comment .by{color:#828282}.comment .by a{color:#828282;text-decoration:underline}.comment .text{overflow-wrap:break-word}.comment .text a:hover{color:#f60}.comment .text pre{white-space:pre-wrap}.comment .toggle{background-color:#fffbf2;padding:.3em .5em;border-radius:4px}.comment .toggle a{color:#828282;cursor:pointer}.comment .toggle.open{padding:0;background-color:transparent;margin-bottom:-.5em}\",\"\"])},28:function(e,t,s){\"use strict\";function n(e){var t;t=s(21),t.__inject__&&t.__inject__(e)}function i(e){var t;t=s(23),t.__inject__&&t.__inject__(e)}function o(e,t){if(t&&t.kids)return e.dispatch(\"FETCH_ITEMS\",{ids:t.kids}).then(function(){return Promise.all(t.kids.map(function(t){return o(e,e.state.items[t])}))})}function r(e){var t;t=s(19),t.__inject__&&t.__inject__(e)}Object.defineProperty(t,\"__esModule\",{value:!0});var a={name:\"spinner\",props:[\"show\"],serverCacheKey:function(e){return e.show}},m=function(){var e=this,t=e.$createElement,s=e._self._c||t;return s(\"transition\",[s(\"svg\",{directives:[{name:\"show\",rawName:\"v-show\",value:e.show,expression:\"show\"}],staticClass:\"spinner\",class:{show:e.show},attrs:{width:\"44px\",height:\"44px\",viewBox:\"0 0 44 44\"}},[s(\"circle\",{staticClass:\"path\",attrs:{fill:\"none\",\"stroke-width\":\"4\",\"stroke-linecap\":\"round\",cx:\"22\",cy:\"22\",r:\"20\"}})])])},c=[],d={render:m,staticRenderFns:c},l=d,p=s(1),f=n,u=p(a,l,!1,f,null,\"75d339dc\"),_=u.exports,h={name:\"comment\",props:[\"id\"],data:function(){return{open:!0}},computed:{comment:function(){return this.$store.state.items[this.id]}},methods:{pluralize:function(e){return e+(1===e?\" reply\":\" replies\")}}},g=function(){var e=this,t=e.$createElement,s=e._self._c||t;return e.comment?s(\"li\",{staticClass:\"comment\"},[e._ssrNode('',\"
\",[s(\"router-link\",{attrs:{to:\"/user/\"+e.comment.by}},[e._v(e._s(e.comment.by))]),e._ssrNode(e._ssrEscape(\"\\n \"+e._s(e._f(\"timeAgo\")(e.comment.time))+\" ago\\n \"))],2),e._ssrNode(''+e._s(e.comment.text)+\"
\"+(e.comment.kids&&e.comment.kids.length?\"\":\"\\x3c!----\\x3e\")),e._ssrNode('\",e._l(e.comment.kids,function(e){return s(\"comment\",{key:e,attrs:{id:e}})}))],2):e._e()},v=[],w={render:g,staticRenderFns:v},k=w,b=s(1),x=i,y=b(h,k,!1,x,null,\"4fcee322\"),N=y.exports,E={name:\"item-view\",components:{Spinner:_,Comment:N},data:function(){return{loading:!0}},computed:{item:function(){return this.$store.state.items[this.$route.params.id]}},asyncData:function(e){var t=e.store,s=e.route.params.id;return t.dispatch(\"FETCH_ITEMS\",{ids:[s]})},title:function(){return this.item.title},beforeMount:function(){this.fetchComments()},watch:{item:\"fetchComments\"},methods:{fetchComments:function(){var e=this;this.item&&this.item.kids&&(this.loading=!0,o(this.$store,this.item).then(function(){e.loading=!1}))}}},C=function(){var e=this,t=e.$createElement,s=e._self._c||t;return e.item?s(\"div\",{staticClass:\"item-view\"},[e.item?[e._ssrNode('\",[e._ssrNode(\"'+e._ssrEscape(e._s(e.item.title))+\"
\"+(e.item.url?''+e._ssrEscape(\"\\n (\"+e._s(e._f(\"host\")(e.item.url))+\")\\n \")+\"\":\"\\x3c!----\\x3e\")),e._ssrNode('',\"
\",[e._ssrNode(e._ssrEscape(\"\\n \"+e._s(e.item.score)+\" points\\n | by \")),s(\"router-link\",{attrs:{to:\"/user/\"+e.item.by}},[e._v(e._s(e.item.by))]),e._ssrNode(e._ssrEscape(\"\\n \"+e._s(e._f(\"timeAgo\")(e.item.time))+\" ago\\n \"))],2)],2),e._ssrNode('\",[e._ssrNode('\",[e._ssrNode(e._ssrEscape(\"\\n \"+e._s(e.item.kids?e.item.descendants+\" comments\":\"No comments yet.\")+\"\\n \")),s(\"spinner\",{attrs:{show:e.loading}})],2),e.loading?e._e():e._ssrNode('\",e._l(e.item.kids,function(e){return s(\"comment\",{key:e,attrs:{id:e}})}))])]:e._e()],2):e._e()},j=[],$={render:C,staticRenderFns:j},z=$,F=s(1),M=r,S=F(E,z,!1,M,null,\"5fe69b56\");t.default=S.exports}};",
5 | "1.server-bundle.js": "exports.ids=[1],exports.modules={15:function(t,e,s){var i=s(16);\"string\"==typeof i&&(i=[[t.i,i,\"\"]]),i.locals&&(t.exports=i.locals);var a=s(14);t.exports.__inject__=function(t){a(\"43656ec8\",i,!0,t)}},16:function(t,e,s){e=t.exports=s(13)(void 0),e.push([t.i,\".news-view{padding-top:45px}.news-list,.news-list-nav{background-color:#fff;border-radius:2px}.news-list-nav{padding:15px 30px;position:fixed;text-align:center;top:55px;left:0;right:0;z-index:998;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.1);box-shadow:0 1px 2px rgba(0,0,0,.1)}.news-list-nav a{margin:0 1em}.news-list-nav .disabled{color:#ccc}.news-list{position:absolute;margin:30px 0;width:100%;-webkit-transition:all .5s cubic-bezier(.55,0,.1,1);-o-transition:all .5s cubic-bezier(.55,0,.1,1);transition:all .5s cubic-bezier(.55,0,.1,1)}.news-list ul{list-style-type:none;padding:0;margin:0}.slide-left-enter,.slide-right-leave-to{opacity:0;-webkit-transform:translate(30px);-ms-transform:translate(30px);transform:translate(30px)}.slide-left-leave-to,.slide-right-enter{opacity:0;-webkit-transform:translate(-30px);-ms-transform:translate(-30px);transform:translate(-30px)}.item-enter-active,.item-leave-active,.item-move{-webkit-transition:all .5s cubic-bezier(.55,0,.1,1);-o-transition:all .5s cubic-bezier(.55,0,.1,1);transition:all .5s cubic-bezier(.55,0,.1,1)}.item-enter,.item-leave-active{opacity:0;-webkit-transform:translate(30px);-ms-transform:translate(30px);transform:translate(30px)}.item-leave-active{position:absolute}@media (max-width:600px){.news-list{margin:10px 0}}\",\"\"])},17:function(t,e,s){var i=s(18);\"string\"==typeof i&&(i=[[t.i,i,\"\"]]),i.locals&&(t.exports=i.locals);var a=s(14);t.exports.__inject__=function(t){a(\"70084b98\",i,!0,t)}},18:function(t,e,s){e=t.exports=s(13)(void 0),e.push([t.i,\".news-item{background-color:#fff;padding:20px 30px 20px 80px;border-bottom:1px solid #eee;position:relative;line-height:20px}.news-item .score{color:#f60;font-size:1.1em;font-weight:700;position:absolute;top:50%;left:0;width:80px;text-align:center;margin-top:-10px}.news-item .host,.news-item .meta{font-size:.85em;color:#828282}.news-item .host a,.news-item .meta a{color:#828282;text-decoration:underline}.news-item .host a:hover,.news-item .meta a:hover{color:#f60}\",\"\"])},27:function(t,e,s){\"use strict\";function i(t){var e;e=s(17),e.__inject__&&e.__inject__(t)}function a(t){var e;e=s(15),e.__inject__&&e.__inject__(t)}function n(t){return{name:t+\"-stories-view\",asyncData:function(e){return e.store.dispatch(\"FETCH_LIST_DATA\",{type:t})},title:E(t),render:function(e){return e(N,{props:{type:t}})}}}Object.defineProperty(e,\"__esModule\",{value:!0});var r=s(2),o=s(3),l={name:\"news-item\",props:[\"item\"],serverCacheKey:function(t){var e=t.item,s=e.id,i=e.__lastUpdated,a=e.time;return s+\"::\"+i+\"::\"+Object(o.timeAgo)(a)}},p=function(){var t=this,e=t.$createElement,s=t._self._c||e;return s(\"li\",{staticClass:\"news-item\"},[t._ssrNode(''+t._ssrEscape(t._s(t.item.score))+\"\"),t._ssrNode('',\"\",[t.item.url?[t._ssrNode(\"'+t._ssrEscape(t._s(t.item.title))+''+t._ssrEscape(\" (\"+t._s(t._f(\"host\")(t.item.url))+\")\")+\"\")]:[s(\"router-link\",{attrs:{to:\"/item/\"+t.item.id}},[t._v(t._s(t.item.title))])]],2),t._ssrNode(\"
\"),t._ssrNode('',\"\",[\"job\"!==t.item.type?t._ssrNode('',\"\",[t._ssrNode(\"\\n by \"),s(\"router-link\",{attrs:{to:\"/user/\"+t.item.by}},[t._v(t._s(t.item.by))])],2):t._e(),t._ssrNode(''+t._ssrEscape(\"\\n \"+t._s(t._f(\"timeAgo\")(t.item.time))+\" ago\\n \")+\"\"),\"job\"!==t.item.type?t._ssrNode('\",[t._ssrNode(\"\\n | \"),s(\"router-link\",{attrs:{to:\"/item/\"+t.item.id}},[t._v(t._s(t.item.descendants)+\" comments\")])],2):t._e()],2),t._ssrNode(\"story\"!==t.item.type?''+t._ssrEscape(t._s(t.item.type))+\"\":\"\\x3c!----\\x3e\")],2)},c=[],m={render:p,staticRenderFns:c},d=m,u=s(1),_=i,f=u(l,d,!1,_,null,\"4ec58b40\"),h=f.exports,v={name:\"item-list\",components:{Item:h},props:{type:String},data:function(){return{transition:\"slide-right\",displayedPage:Number(this.$route.params.page)||1,displayedItems:this.$store.getters.activeItems}},computed:{page:function(){return Number(this.$route.params.page)||1},maxPage:function(){var t=this.$store.state,e=t.itemsPerPage,s=t.lists;return Math.ceil(s[this.type].length/e)},hasMore:function(){return this.pages.maxPage)return void s.$router.replace(\"/\"+s.type+\"/1\");s.transition=-1===e?null:t>e?\"slide-left\":\"slide-right\",s.displayedPage=t,s.displayedItems=s.$store.getters.activeItems,s.$bar.finish()})}}},g=function(){var t=this,e=t.$createElement,s=t._self._c||e;return s(\"div\",{staticClass:\"news-view\"},[t._ssrNode('',\"
\",[t.page>1?s(\"router-link\",{attrs:{to:\"/\"+t.type+\"/\"+(t.page-1)}},[t._v(\"< prev\")]):s(\"a\",{staticClass:\"disabled\"},[t._v(\"< prev\")]),t._ssrNode(\"\"+t._ssrEscape(t._s(t.page)+\"/\"+t._s(t.maxPage))+\"\"),t.hasMore?s(\"router-link\",{attrs:{to:\"/\"+t.type+\"/\"+(t.page+1)}},[t._v(\"more >\")]):s(\"a\",{staticClass:\"disabled\"},[t._v(\"more >\")])],2),s(\"transition\",{attrs:{name:t.transition}},[t.displayedPage>0?s(\"div\",{key:t.displayedPage,staticClass:\"news-list\"},[s(\"transition-group\",{attrs:{tag:\"ul\",name:\"item\"}},t._l(t.displayedItems,function(t){return s(\"item\",{key:t.id,attrs:{item:t}})}))],1):t._e()])],1)},b=[],x={render:g,staticRenderFns:b},y=x,w=s(1),k=a,I=w(v,y,!1,k,null,\"4e0af864\"),N=I.exports;e.default=n;var E=function(t){return t.charAt(0).toUpperCase()+t.slice(1)}}};",
6 | "2.server-bundle.js": "exports.ids=[2],exports.modules={25:function(e,s,r){var t=r(26);\"string\"==typeof t&&(t=[[e.i,t,\"\"]]),t.locals&&(e.exports=t.locals);var i=r(14);e.exports.__inject__=function(e){i(\"45ff866c\",t,!0,e)}},26:function(e,s,r){s=e.exports=r(13)(void 0),s.push([e.i,\".user-view{background-color:#fff;-webkit-box-sizing:border-box;box-sizing:border-box;padding:2em 3em}.user-view h1{margin:0;font-size:1.5em}.user-view .meta{list-style-type:none;padding:0}.user-view .label{display:inline-block;min-width:4em}.user-view .about{margin:1em 0}.user-view .links a{text-decoration:underline}\",\"\"])},29:function(e,s,r){\"use strict\";function t(e){var s;s=r(25),s.__inject__&&s.__inject__(e)}Object.defineProperty(s,\"__esModule\",{value:!0});var i={name:\"user-view\",computed:{user:function(){return this.$store.state.users[this.$route.params.id]}},asyncData:function(e){var s=e.store,r=e.route.params.id;return s.dispatch(\"FETCH_USER\",{id:r})},title:function(){return this.user?this.user.id:\"User not found\"}},a=function(){var e=this,s=e.$createElement;return(e._self._c||s)(\"div\",{staticClass:\"user-view\"},[e._ssrNode(e.user?\"\"+e._ssrEscape(\"User : \"+e._s(e.user.id))+'
submissions |\\n comments
\":!1===e.user?\"User not found.
\":\"\\x3c!----\\x3e\")])},n=[],o={render:a,staticRenderFns:n},u=o,c=r(1),l=t,d=c(i,u,!1,l,null,\"7cd1eb0d\");s.default=d.exports}};",
7 | "server-bundle.js": "module.exports=function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={},r={3:0};return t.e=function(t){if(0!==r[t]){var n=require(\"./\"+t+\".server-bundle.js\"),o=n.modules,i=n.ids;for(var s in o)e[s]=o[s];for(var a=0;a