76 | {
77 | require.ensure([], require => {
78 | cb(null, require('./pages/App/Vote').default);
79 | }, 'Vote');
80 | }}/>
81 |
82 |
83 | ```
84 |
85 | ``` javascript
86 | import connectDataFetchers from '../../utils/connectDataFetchers';
87 | import * as ACTIONS from '../../actions/vote';
88 |
89 | @connect(function mapStateToProps(state) {
90 | return {
91 | message: state.vote.message
92 | };
93 | })
94 | @connectDataFetchers([ACTIONS.loadData])
95 | class Vote extends Component {
96 | static pageConfig = {
97 | pageId: 'Vote'
98 | };
99 | render() {
100 | return (
101 |
102 | this is vote
103 | about
104 | test
105 | message: { this.props.message }
106 |
107 | );
108 | }
109 | }
110 | ```
111 | fetch data according to connectDataFetchers.
112 |
113 | ``` javascript
114 | import fetchList from '../../../fetchList';
115 |
116 | export const LOAD_VOTE_SUCCESS = 'LOAD_VOTE_SUCCESS';
117 | export const LOAD_VOTE_FAILED = 'LOAD_VOTE_FAILED';
118 |
119 | export function loadData(opts, req){
120 | return (dispatch) => {
121 | return fetchList.getVote(opts, req).then((resp) => {
122 | dispatch({
123 | type: LOAD_VOTE_SUCCESS,
124 | payload: resp.data
125 | });
126 | }).catch(() => {
127 | dispatch({
128 | type: LOAD_VOTE_FAILED
129 | });
130 | });
131 | };
132 | }
133 | ```
134 |
135 | ## TodoList
136 | * add docker support
137 |
138 |
--------------------------------------------------------------------------------
/client/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-size: 16px;
3 | }
--------------------------------------------------------------------------------
/client/js/pages/async.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Immutable from 'immutable';
3 |
4 | import createRender from '../utils/createApp';
5 | import Page from '../../../common/pages/async/Page.jsx';
6 | import rootReducer from '../../../common/reducers/async';
7 |
8 | import '../../css/main.css';
9 |
10 | let createApp = createRender({
11 | transformer: Immutable.fromJS
12 | });
13 |
14 | createApp({
15 | rootReducer,
16 | component:
17 | }).then((store) => {
18 | if (process.env.NODE_ENV !== 'production' && module.hot) {
19 | // Enable Webpack hot module replacement for reducers
20 | module.hot.accept(['../../../common/pages/async/Page.jsx', '../../../common/reducers/async'], () => {
21 | const NewPage = require('../../../common/pages/async/Page.jsx').default;
22 | const newRootReducer = require('../../../common/reducers/async').default;
23 | createApp({
24 | rootReducer: newRootReducer,
25 | component:
26 | });
27 | });
28 | }
29 | });
30 |
--------------------------------------------------------------------------------
/client/js/pages/chat.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import createRender from '../utils/createApp';
4 | import Page from '../../../common/pages/chat/Page.jsx';
5 | // import rootReducer from '../../../common/pages/chat/reducers';
6 |
7 | import '../../css/main.css';
8 |
9 | let createApp = createRender();
10 |
11 | createApp({
12 | component:
13 | });
14 |
--------------------------------------------------------------------------------
/client/js/pages/todo.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Immutable from 'immutable';
3 |
4 | import createRender from '../utils/createApp';
5 | import Page from '../../../common/pages/todo/Todo.jsx';
6 | import rootReducer from '../../../common/reducers/todo';
7 |
8 | import '../../css/main.css';
9 |
10 | let createApp = createRender({
11 | transformer: Immutable.fromJS
12 | });
13 |
14 | createApp({
15 | rootReducer,
16 | component:
17 | });
18 |
--------------------------------------------------------------------------------
/client/js/utils/createApp.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {render} from 'react-dom';
3 | import {Provider} from 'react-redux';
4 | import fastclick from 'fastclick';
5 |
6 | import App from '../../../common/App.jsx';
7 | import configureStore from '../../../common/store/index';
8 |
9 | if (process.env.NODE_ENV !== 'production') {
10 | var whyDidYouUpdate = require('why-did-you-update').default;
11 | whyDidYouUpdate(React);
12 | var ReactPerf = require('react-addons-perf');
13 | window.ReactPerf = ReactPerf;
14 | }
15 |
16 | // fastclick解决ios和部分安卓click事件的问题
17 | fastclick.attach(document.body);
18 |
19 | export default function createRender(middlewareConfig = {}){
20 | let store = null;
21 | let page = document.getElementById('page');
22 | let onRenderCompleted = typeof middlewareConfig.onRenderCompleted === 'function' && middlewareConfig.onRenderCompleted;
23 |
24 | if (process.env.NODE_ENV !== 'production') {
25 | // React.addons.Perf性能分析使用
26 | if (window.ReactPerf) {
27 | ReactPerf.start();
28 | }
29 | }
30 |
31 | return function ({
32 | rootReducer = (() => {
33 | }),
34 | component = null
35 | }) {
36 | let transformedData = typeof middlewareConfig.transformer === 'function'
37 | ? middlewareConfig.transformer(window.__INITIAL_STATE__) : window.__INITIAL_STATE__;
38 | if (!store) {
39 | store = configureStore(transformedData, rootReducer);
40 | }
41 | // hot load from hmr
42 | else if (process.env.NODE_ENV !== 'production') {
43 | store.replaceReducer(rootReducer);
44 | }
45 |
46 | render((
47 |
48 |
49 | { component }
50 |
51 |
52 | ), page, onRenderCompleted);
53 |
54 | return Promise.resolve(store);
55 | };
56 | }
57 |
--------------------------------------------------------------------------------
/client/js/utils/spaRenderer.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from 'react-dom';
3 | import { Provider } from 'react-redux';
4 | import { match, Router, browserHistory } from 'react-router';
5 | import createRoutes from '../../../common/routes';
6 | import configureStore from '../../../common/store/spaStore';
7 | import App from '../../../common/App';
8 |
9 |
10 | const store = configureStore(window.__INITIAL_STATE__, browserHistory);
11 | const routes = createRoutes(store);
12 |
13 | function onUpdate(){
14 | window.scrollTo(0, 0);
15 | }
16 |
17 | match({ history: browserHistory, routes }, (error, redirectLocation, renderProps) => {
18 | render(
19 |
20 |
21 |
22 |
23 | , document.getElementById('page')
24 | );
25 | });
26 |
--------------------------------------------------------------------------------
/client/js/utils/sw.js:
--------------------------------------------------------------------------------
1 | var config = {
2 | db: 'sw_gamPportal_201612011014'
3 | };
4 |
5 | var urlsToCache = [
6 |
7 | ];
8 |
9 | var addToCache = function (req) {
10 | return fetch(req.clone()).then(function (resp) {
11 | var cacheResp = resp.clone();
12 | if (resp.status !== 200 || (resp.type !== 'basic' && resp.type !== 'cors')) {
13 | return resp;
14 | }
15 | caches.open(config.db).then(function (cache) {
16 | cache.put(req.clone(), cacheResp);
17 | });
18 | return resp;
19 | });
20 | };
21 |
22 |
23 | // self.addEventListener('install', function (e) {
24 | // // See https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-global-scope-skipwaiting
25 | // if (typeof self.skipWaiting === 'function') {
26 | // e.waitUntil(self.skipWaiting());
27 | // }
28 |
29 | // });
30 |
31 | self.addEventListener('activate', function (event) {
32 | // event.waitUntil(Promise.all([
33 | // caches.keys().then(function (cacheNames) {
34 | // return Promise.all(cacheNames.map(function (cacheName) {
35 | // if (cacheName !== config.db) {
36 | // return caches.delete(cacheName);
37 | // }
38 | // }));
39 | // }),
40 | // typeof self.clients.claim === 'function' && self.clients.claim()
41 | // ]));
42 |
43 | // 内核的cache.delete有bug,这里先注释
44 | event.waitUntil(caches.keys().then(function (cacheNames) {
45 | return Promise.all(cacheNames.map(function (cacheName) {
46 | if (cacheName !== config.db) {
47 | return caches.delete(cacheName);
48 | }
49 | }));
50 | }));
51 | });
52 |
53 | self.addEventListener('fetch', function (event) {
54 | var requestUrl = event.request.url;
55 |
56 | var match = false;
57 | for (var i = 0; i < urlsToCache.length; ++i) {
58 | var url = urlsToCache[i];
59 | if (url instanceof RegExp) {
60 | match = url.test(requestUrl);
61 | } else if (requestUrl.indexOf(url) >= 0) {
62 | match = true;
63 | break;
64 | }
65 | }
66 |
67 | if (!match) {
68 | // event.respondWith(fetch(event.request.clone()));
69 | return;
70 | }
71 |
72 | var promise, req, url = event.request.url;
73 |
74 | if (url.indexOf('/ajax/') !== -1 || url.indexOf('bypass=1') !== -1 || url.indexOf('http:') === 0) {
75 | event.respondWith(fetch(event.request.clone()));
76 | return;
77 | }
78 |
79 | // if (url.indexOf('cors=1') !== -1) {
80 | req = new Request(url, {
81 | mode: 'cors'
82 | });
83 | // } else {
84 | // req = event.request.clone();
85 | // }
86 |
87 | promise = caches.open(config.db).then(function (cache) {
88 | return cache.match(req);
89 | }).then(function (response) {
90 | if (response) {
91 | return response;
92 | } else {
93 | return addToCache(req);
94 | }
95 | });
96 |
97 | event.respondWith(promise);
98 |
99 | });
100 |
--------------------------------------------------------------------------------
/common/App.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import EventEmitter from 'events';
3 |
4 | let mediator = new EventEmitter();
5 |
6 | class App extends Component {
7 | constructor(props, context) {
8 | super(props, context);
9 | }
10 |
11 | getChildContext(){
12 | return {
13 | $eventBus: mediator,
14 | $appConfig: this.props.appConfig
15 | }
16 | }
17 |
18 | componentDidMount(){
19 | }
20 |
21 | componentDidUpdate(){
22 | }
23 |
24 | componentWillUnmount(){
25 | }
26 |
27 | render() {
28 | return React.Children.only(this.props.children);
29 | }
30 | }
31 | App.defaultProps = {
32 | appConfig: null
33 | };
34 | App.propTypes = {
35 | appConfig: PropTypes.object
36 | };
37 | App.childContextTypes = {
38 | $eventBus: PropTypes.instanceOf(EventEmitter),
39 | $appConfig: PropTypes.object
40 | };
41 |
42 | export default App;
43 |
--------------------------------------------------------------------------------
/common/actions/async.js:
--------------------------------------------------------------------------------
1 | import fetch from 'isomorphic-fetch'
2 | import Immutable from 'immutable';
3 |
4 | export const REQUEST_POSTS = 'REQUEST_POSTS'
5 | export const RECEIVE_POSTS = 'RECEIVE_POSTS'
6 | export const SELECT_REDDIT = 'SELECT_REDDIT'
7 | export const INVALIDATE_REDDIT = 'INVALIDATE_REDDIT'
8 |
9 | export function selectReddit(reddit) {
10 | return {
11 | type: SELECT_REDDIT,
12 | reddit
13 | }
14 | }
15 |
16 | export function invalidateReddit(reddit) {
17 | return {
18 | type: INVALIDATE_REDDIT,
19 | reddit
20 | }
21 | }
22 |
23 | function requestPosts(reddit) {
24 | return {
25 | type: REQUEST_POSTS,
26 | reddit
27 | }
28 | }
29 |
30 | function receivePosts(reddit, json) {
31 | return {
32 | type: RECEIVE_POSTS,
33 | reddit,
34 | posts: Immutable.fromJS(json.data.children.map(child => child.data)),
35 | receivedAt: Date.now()
36 | }
37 | }
38 |
39 | function fetchPosts(reddit) {
40 | return async function(dispatch) {
41 | dispatch(requestPosts(reddit))
42 | try {
43 | let response = await fetch(`https://www.reddit.com/r/${reddit}.json`, {
44 | method: 'GET',
45 | timeout: 5000
46 | }).then(response => response.json());
47 | dispatch(receivePosts(reddit, response))
48 | } catch(ex){
49 | console.error(ex);
50 | }
51 | }
52 | }
53 |
54 | function shouldFetchPosts(state, reddit) {
55 | const posts = state.get('postsByReddit').get(reddit)
56 | if (!posts) {
57 | return true
58 | }
59 | if (posts.get('isFetching')) {
60 | return false
61 | }
62 | return posts.get('didInvalidate')
63 | }
64 |
65 | export function fetchPostsIfNeeded(reddit) {
66 | return (dispatch, getState) => {
67 | if (shouldFetchPosts(getState(), reddit)) {
68 | return dispatch(fetchPosts(reddit))
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/common/actions/todo.js:
--------------------------------------------------------------------------------
1 | /*
2 | * action 类型
3 | */
4 |
5 | export const ADD_TODO = 'ADD_TODO';
6 | export const COMPLETE_TODO = 'COMPLETE_TODO';
7 | export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'
8 |
9 | /*
10 | * 其它的常量
11 | */
12 |
13 | export const VisibilityFilters = {
14 | SHOW_ALL: 'SHOW_ALL',
15 | SHOW_COMPLETED: 'SHOW_COMPLETED',
16 | SHOW_ACTIVE: 'SHOW_ACTIVE'
17 | };
18 |
19 | /*
20 | * action 创建函数
21 | */
22 |
23 | export function addTodo(text) {
24 | return { type: ADD_TODO, text }
25 | }
26 |
27 | export function completeTodo(index) {
28 | return { type: COMPLETE_TODO, index }
29 | }
30 |
31 | export function setVisibilityFilter(filter) {
32 | return { type: SET_VISIBILITY_FILTER, filter }
33 | }
34 |
--------------------------------------------------------------------------------
/common/actions/vote.js:
--------------------------------------------------------------------------------
1 | import fetchList from '../fetchList';
2 |
3 | export const LOAD_VOTE_SUCCESS = 'LOAD_VOTE_SUCCESS';
4 | export const LOAD_VOTE_FAILED = 'LOAD_VOTE_FAILED';
5 |
6 | export function loadData(opts, req){
7 | return (dispatch) => {
8 | return fetchList.getVote(opts, req).then((resp) => {
9 | dispatch({
10 | type: LOAD_VOTE_SUCCESS,
11 | payload: resp.data
12 | });
13 | }).catch(() => {
14 | dispatch({
15 | type: LOAD_VOTE_FAILED
16 | });
17 | });
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/common/components/async/Picker.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import Immutable from 'immutable';
3 | import ImmutablePropTypes from 'react-immutable-proptypes';
4 | import Base from '../../pages/Base';
5 |
6 | export default class Picker extends Base {
7 | constructor(props, context) {
8 | super(props, context);
9 | }
10 |
11 | onChange(e) {
12 | this.props.onChange(e.target.value)
13 | }
14 |
15 | render() {
16 | const { value, onChange, options } = this.props
17 |
18 | return (
19 |
20 | {value}
21 |
29 |
30 | )
31 | }
32 | }
33 |
34 | Picker.propTypes = {
35 | options: PropTypes.arrayOf(
36 | PropTypes.string.isRequired
37 | ).isRequired,
38 | value: PropTypes.string.isRequired,
39 | onChange: PropTypes.func.isRequired
40 | }
41 |
--------------------------------------------------------------------------------
/common/components/async/Posts.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes, Component } from 'react'
2 | import ImmutablePropTypes from 'react-immutable-proptypes';
3 | import Base from '../../pages/Base';
4 |
5 | export default class Posts extends Base {
6 | render() {
7 | return (
8 |
9 | {this.props.posts.map((post, i) =>
10 | - {post.get('title')}
11 | )}
12 |
13 | )
14 | }
15 | }
16 |
17 | Posts.propTypes = {
18 | posts: ImmutablePropTypes.list.isRequired
19 | }
20 |
--------------------------------------------------------------------------------
/common/components/chat/ChangeNameForm.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Base from '../../pages/Base';
3 |
4 |
5 | export default class ChangeNameForm extends Base {
6 | constructor(props, context) {
7 | super(props, context);
8 |
9 | this.state = {newName: ''};
10 | }
11 |
12 | onKey(e) {
13 | this.setState({ newName : e.target.value });
14 | }
15 |
16 | onSubmit(e) {
17 | e.preventDefault();
18 | var newName = this.state.newName;
19 | this.props.onChangeName(newName);
20 | this.setState({ newName: '' });
21 | }
22 |
23 | render() {
24 | return(
25 |
26 |
Change Name
27 |
33 |
34 | );
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/common/components/chat/Messages.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import Base from '../../pages/Base';
3 |
4 | export class Message extends Base {
5 | constructor(props, context) {
6 | super(props, context);
7 | }
8 |
9 | render() {
10 | return (
11 |
12 | {this.props.user} :
13 | {this.props.text}
14 |
15 | );
16 | }
17 | }
18 | Message.defaultProps = {
19 | user: '',
20 | text: ''
21 | };
22 | Message.propTypes = {
23 | user: PropTypes.string.isRequired,
24 | text: PropTypes.string.isRequired
25 | };
26 |
27 | export class MessageList extends Base {
28 | constructor(props, context) {
29 | super(props, context);
30 | }
31 |
32 | render() {
33 | return (
34 |
35 |
Conversation:
36 | {
37 | this.props.messages.map((message, i) => {
38 | return (
39 |
44 | );
45 | })
46 | }
47 |
48 | );
49 | }
50 | }
51 |
52 |
53 | export class MessageForm extends Base {
54 | constructor(props, context) {
55 | super(props, context);
56 |
57 | this.state = {text: ''};
58 | }
59 |
60 | onSubmit(e) {
61 | e.preventDefault();
62 | if(!this.state.text) return;
63 |
64 | let message = {
65 | user : this.props.user,
66 | text : this.state.text
67 | };
68 | this.props.onMessageSubmit(message);
69 | this.setState({ text: '' });
70 | }
71 |
72 | onChange(e) {
73 | this.setState({ text : e.target.value });
74 | }
75 |
76 | render() {
77 | return(
78 |
79 |
Write New Message
80 |
86 |
87 | );
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/common/components/chat/UsersList.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Base from '../../pages/Base';
3 |
4 | export default class UsersList extends Base {
5 | constructor(props, context) {
6 | super(props, context);
7 | }
8 |
9 | render() {
10 | return (
11 |
12 |
Online Users
13 |
14 | {
15 | this.props.users.map((user, i) => {
16 | return (
17 | -
18 | {user}
19 |
20 | );
21 | })
22 | }
23 |
24 |
25 | );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/common/components/common/Tab.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import classnames from 'classnames';
3 | import Base from '../../pages/Base';
4 |
5 | export default class Tabs extends Base {
6 | constructor(props, context) {
7 | super(props, context);
8 |
9 | this.state = {
10 | selectedTab: props.defaultSelectedTab || null
11 | };
12 |
13 | this.firstTabLabel = null;
14 | }
15 |
16 | getChildContext(){
17 | return {
18 | onSelect: this.onSelect.bind(this),
19 | selectedTab: this.state.selectedTab || this.props.defaultSelectedTab,
20 | activeStyle: this.props.activeLinkStyle || defaultActiveStyle,
21 | firstTabLabel: this.firstTabLabel
22 | };
23 | }
24 |
25 | onSelect(tab, ...rest) {
26 | if(this.state.selectedTab === tab) return;
27 |
28 | this.setState({
29 | selectedTab: tab
30 | });
31 |
32 | if(typeof this.props.onSelect === 'function') {
33 | this.props.onSelect(tab, ...rest);
34 | }
35 | }
36 |
37 | findFirstTabLabel(children){
38 | if (typeof children !== 'object' || this.firstTabLabel) {
39 | return;
40 | }
41 |
42 | React.Children.forEach(children, (child) => {
43 | if(child.props && child.props.label) {
44 | if(this.firstTabLabel == null){
45 | this.firstTabLabel = child.props.label;
46 | return;
47 | }
48 | }
49 |
50 | this.findFirstTabLabel(child.props && child.props.children);
51 | });
52 | }
53 |
54 | render() {
55 | this.findFirstTabLabel(this.props.children);
56 |
57 | return (
58 |
59 | {this.props.children}
60 |
61 | );
62 | }
63 | }
64 | Tabs.defaultProps = {
65 | onSelect: null,
66 | activeLinkStyle: null,
67 | defaultSelectedTab: '',
68 | className: '',
69 | style: null
70 | };
71 | Tabs.propTypes = {
72 | onSelect: PropTypes.func,
73 | activeLinkStyle: PropTypes.object,
74 | defaultSelectedTab: PropTypes.string,
75 | className: PropTypes.string,
76 | style: PropTypes.object
77 | };
78 | Tabs.childContextTypes = {
79 | onSelect: PropTypes.func,
80 | selectedTab: PropTypes.string,
81 | activeStyle: PropTypes.object,
82 | firstTabLabel: PropTypes.string
83 | };
84 |
85 | const defaultActiveStyle = {
86 | fontWeight: 'bold'
87 | };
88 |
89 | export class TabTitle extends Component {
90 | constructor(props, context){
91 | super(props, context);
92 |
93 | this.onSelect = this.onSelect.bind(this);
94 | }
95 |
96 | onSelect(){
97 | this.context.onSelect(this.props.label);
98 | }
99 |
100 | componentDidMount() {
101 | if (this.context.selectedTab === this.props.label || (!this.context.selectedTab && this.context.firstTabLabel === this.props.label)) {
102 | this.context.onSelect(this.props.label);
103 | }
104 | }
105 |
106 | render() {
107 | let style = null;
108 | let isActive = this.context.selectedTab === this.props.label;
109 | if (isActive) {
110 | style = this.context.activeStyle;
111 | }
112 | let clsNames = classnames(this.props.className, { active: isActive });
113 |
114 | return (
115 |
120 | {this.props.children}
121 |
122 | );
123 | }
124 | }
125 | TabTitle.defaultProps = {
126 | label: '',
127 | className: 'tab-link'
128 | };
129 | TabTitle.propTypes = {
130 | label: PropTypes.string.isRequired,
131 | className: PropTypes.string
132 | };
133 | TabTitle.contextTypes = {
134 | onSelect: PropTypes.func,
135 | firstTabLabel: PropTypes.string,
136 | activeStyle: PropTypes.object,
137 | selectedTab: PropTypes.string
138 | };
139 |
140 | const styles = {
141 | visible: {
142 | display: 'block'
143 | },
144 | hidden: {
145 | display: 'none'
146 | }
147 | };
148 |
149 | export class TabPanel extends Component {
150 | constructor(props, context){
151 | super(props, context);
152 |
153 | for(let style in styles){
154 | if(styles.hasOwnProperty(style)){
155 | Object.assign(styles[style], this.props.style);
156 | }
157 | }
158 | }
159 |
160 | render() {
161 | let displayStyle = this.context.selectedTab === this.props.for
162 | ? styles.visible : styles.hidden;
163 |
164 | return (
165 |
168 | {this.props.children}
169 |
170 | );
171 | }
172 | }
173 | TabPanel.defaultProps = {
174 | for: '',
175 | className: 'tab-content',
176 | style: null
177 | };
178 | TabPanel.propTypes = {
179 | for: PropTypes.string.isRequired,
180 | className: PropTypes.string,
181 | style: PropTypes.object
182 | };
183 | TabPanel.contextTypes = {
184 | selectedTab: PropTypes.string
185 | };
186 |
--------------------------------------------------------------------------------
/common/components/todo/AddTodo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import Base from '../../pages/Base';
3 |
4 | export default class AddTodo extends Base {
5 | constructor(props, context) {
6 | super(props, context);
7 | }
8 |
9 | render() {
10 | return (
11 |
12 |
13 |
14 |
15 | )
16 | }
17 |
18 | onClick(e) {
19 | const node = this.refs.input;
20 | const text = node.value.trim();
21 | this.props.onAddClick(text);
22 | node.value = '';
23 | }
24 | }
25 |
26 | AddTodo.propTypes = {
27 | onAddClick: PropTypes.func.isRequired
28 | };
29 |
--------------------------------------------------------------------------------
/common/components/todo/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import Base from '../../pages/Base';
3 |
4 | export default class Footer extends Base {
5 | constructor(props, context) {
6 | super(props, context);
7 | }
8 |
9 | renderFilter(filter, name) {
10 | if (filter === this.props.filter) {
11 | return name
12 | }
13 |
14 | return (
15 | {
16 | e.preventDefault()
17 | this.props.onFilterChange(filter)
18 | } }>
19 | {name}
20 |
21 | )
22 | }
23 |
24 | render() {
25 | return (
26 |
27 | Show:
28 | {' '}
29 | {this.renderFilter('SHOW_ALL', 'All') }
30 | {', '}
31 | {this.renderFilter('SHOW_COMPLETED', 'Completed') }
32 | {', '}
33 | {this.renderFilter('SHOW_ACTIVE', 'Active') }
34 | .
35 |
36 | )
37 | }
38 | }
39 |
40 | Footer.propTypes = {
41 | onFilterChange: PropTypes.func.isRequired,
42 | filter: PropTypes.oneOf([
43 | 'SHOW_ALL',
44 | 'SHOW_COMPLETED',
45 | 'SHOW_ACTIVE'
46 | ]).isRequired
47 | }
48 |
--------------------------------------------------------------------------------
/common/components/todo/Todo.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component, PropTypes} from 'react';
2 | import Base from '../../pages/Base';
3 |
4 | let styles = {
5 | completed: {
6 | textDecoration: 'line-through',
7 | cursor: 'default'
8 | },
9 | uncompleted: {
10 | textDecoration: 'none',
11 | cursor: 'pointer'
12 | }
13 | };
14 |
15 | export default class Todo extends Base {
16 | constructor(props, context) {
17 | super(props, context);
18 | }
19 |
20 | componentDidMount() {
21 | this.on('test', function () {
22 | console.log('test event bus');
23 | });
24 | }
25 |
26 | componentWillUnmount(){
27 | // unregister subscribe
28 | super.componentWillUnmount();
29 | }
30 |
31 | render() {
32 | return (
33 |
35 | { this.props.text }
36 |
37 | )
38 | }
39 | }
40 | Todo.defaultProps = {
41 | onClick: function(){},
42 | text: '',
43 | completed: false
44 | };
45 | Todo.propTypes = {
46 | onClick: PropTypes.func.isRequired,
47 | text: PropTypes.string.isRequired,
48 | completed: PropTypes.bool.isRequired
49 | };
50 |
--------------------------------------------------------------------------------
/common/components/todo/TodoList.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import { List } from 'immutable';
3 | import ImmutablePropTypes from 'react-immutable-proptypes';
4 | import Todo from './Todo'
5 | import Base from '../../pages/Base';
6 |
7 | export default class TodoList extends Base {
8 | constructor(props, context) {
9 | super(props, context);
10 | }
11 |
12 | render() {
13 | return (
14 |
15 | { this.props.todos.map((todo, index) =>
16 | this.props.onTodoClick(index) } />
20 | ) }
21 |
22 | )
23 | }
24 | }
25 |
26 | TodoList.propTypes = {
27 | onTodoClick: PropTypes.func.isRequired,
28 | todos: ImmutablePropTypes.listOf(ImmutablePropTypes.contains({
29 | text: PropTypes.string.isRequired,
30 | completed: PropTypes.bool.isRequired
31 | }))
32 | };
33 |
--------------------------------------------------------------------------------
/common/config.js:
--------------------------------------------------------------------------------
1 | export const VERSION = 'v3';
2 | export const READY = 0;
3 | export const START = 1;
4 | export const SUCCESS = 2;
5 | export const FAILED = 3;
6 | export const NOMORE = 4;
7 |
8 | export default {
9 | "VERSION": VERSION,
10 |
11 | "READY": READY,
12 | "START": START,
13 | "SUCCESS": SUCCESS,
14 | "FAILED": FAILED,
15 | "NOMORE": NOMORE
16 | };
17 |
--------------------------------------------------------------------------------
/common/fetchList/clientFetch.js:
--------------------------------------------------------------------------------
1 |
2 | export default {
3 | getVote(opts){
4 | return new Promise((resolve, reject) => {
5 | setTimeout(() => {
6 | resolve({
7 | data: {
8 | message: 123
9 | }
10 | });
11 | }, 500);
12 | });
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/common/fetchList/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fetch-list",
3 | "version": "0.0.1",
4 | "browser": "clientFetch.js",
5 | "main": "serverFetch.js"
6 | }
7 |
--------------------------------------------------------------------------------
/common/fetchList/serverFetch.js:
--------------------------------------------------------------------------------
1 |
2 | export default {
3 | getVote(opts, req){
4 | return new Promise((resolve, reject) => {
5 | setTimeout(() => {
6 | resolve({
7 | data: {
8 | message: 123
9 | }
10 | });
11 | }, 500);
12 | });
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/common/pages/App/About.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Link } from 'react-router';
3 | import { connect } from 'react-redux';
4 |
5 | function mapStateToProps(state) {
6 | return {
7 | text: state.about
8 | };
9 | }
10 |
11 | @connect(mapStateToProps)
12 | class About extends Component {
13 | static pageConfig = {
14 | pageId: 'About'
15 | };
16 |
17 | render() {
18 | return (
19 |
20 | this is about page
21 | vote
22 | text: {this.props.text}
23 |
24 | );
25 | }
26 | }
27 |
28 | export default About;
29 |
--------------------------------------------------------------------------------
/common/pages/App/App.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 |
3 | let App = ({children}) => {
4 | return (
5 | React.Children.only(children)
6 | );
7 | };
8 |
9 | App.propTypes = {
10 | children: PropTypes.object
11 | };
12 |
13 | export default App;
14 |
--------------------------------------------------------------------------------
/common/pages/App/Vote.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import { connect } from 'react-redux';
3 | import { Link } from 'react-router';
4 |
5 | import connectDataFetchers from '../../utils/connectDataFetchers';
6 | import * as ACTIONS from '../../actions/vote';
7 |
8 | @connect(function mapStateToProps(state) {
9 | return {
10 | message: state.vote.message
11 | };
12 | })
13 | @connectDataFetchers([ACTIONS.loadData])
14 | class Vote extends Component {
15 | static pageConfig = {
16 | pageId: 'Vote'
17 | };
18 | render() {
19 | return (
20 |
21 | this is vote
22 | about
23 | test
24 | message: { this.props.message }
25 |
26 | );
27 | }
28 | }
29 |
30 | export default Vote;
31 |
--------------------------------------------------------------------------------
/common/pages/Base.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes, Component } from 'react';
2 | import shallowEqual from '../utils/shallowEqual';
3 | import EventEmitter from 'events';
4 |
5 | const eventMatchReg = /^on[A-Z]/;
6 | function getEventMethodsProps(instance){
7 | let methods = Object.getOwnPropertyNames(instance)
8 | .filter((prop) => {
9 | return eventMatchReg.test(prop)
10 | && typeof instance[prop] === 'function';
11 | });
12 |
13 | let instancePrototype = Object.getPrototypeOf(instance);
14 | if(instancePrototype !== Object.prototype) {
15 | methods = methods.concat(getEventMethodsProps(instancePrototype));
16 | }
17 |
18 | return methods
19 | }
20 |
21 |
22 | export default class Base extends Component {
23 | constructor(props, context){
24 | super(props, context);
25 |
26 | this.__eventNames = {};
27 |
28 | this.__bindFunctions();
29 | }
30 |
31 | __bindFunctions(){
32 | let props = getEventMethodsProps(this);
33 | for(let prop of props){
34 | if(!this[prop].funcBinded){
35 | this[prop] = this[prop].bind(this);
36 | this[prop].funcBinded = true;
37 | }
38 | }
39 | }
40 |
41 | on(eventName, fn){
42 | if(typeof fn !== 'function') throw new Error('fn should be a function');
43 |
44 | if(!this.__eventNames[eventName]){
45 | this.__eventNames[eventName] = [fn];
46 | } else {
47 | this.__eventNames[eventName].push(fn);
48 | }
49 |
50 | return this.context.$eventBus.addListener(eventName, fn);
51 | }
52 |
53 | emit(eventName, ...args){
54 | return this.context.$eventBus.emit(eventName, ...args);
55 | }
56 |
57 | off(eventName, fn){
58 | let events = this.__eventNames[eventName];
59 | if(events){
60 | let index = events.indexOf(fn);
61 |
62 | if(index >= 0) {
63 | this.context.$eventBus.removeListener(eventName, fn);
64 |
65 | events.splice(index, 1);
66 |
67 | if(!events.length) {
68 | delete this.__eventNames[eventName];
69 | }
70 | } else {
71 | console.warn('event: ' + eventName + ' is not registered in ' + this._reactInternalInstance.getName() + ' Component');
72 | }
73 |
74 | return true;
75 | } else {
76 | console.warn('event: ' + eventName + ' is not registered in ' + this.constructor.name + ' Component');
77 |
78 | return false;
79 | }
80 | }
81 |
82 |
83 | /**
84 | * 检验组件更新
85 | * @param nextProps
86 | * @param nextState
87 | * @returns {*}
88 | */
89 | shouldComponentUpdate(nextProps, nextState){
90 | let shouldUpdate = !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState);
91 |
92 | if(shouldUpdate && process.env.NODE_ENV !== 'production') {
93 | console.log('Component: ' + this.constructor.name + ' will update');
94 | }
95 |
96 | return shouldUpdate;
97 | }
98 |
99 | componentWillUnmount(){
100 | for(let eventName in this.__eventNames){
101 | if(this.__eventNames.hasOwnProperty(eventName)){
102 | for(let fn of this.__eventNames[eventName]){
103 | this.off(eventName, fn);
104 | }
105 | }
106 | }
107 | }
108 | }
109 | Base.contextTypes = {
110 | $eventBus: PropTypes.instanceOf(EventEmitter)
111 | };
112 |
--------------------------------------------------------------------------------
/common/pages/async/Page.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component, PropTypes} from 'react'
2 | import {connect} from 'react-redux'
3 | import Immutable from 'immutable';
4 | import ImmutablePropTypes from 'react-immutable-proptypes';
5 | import {selectReddit, fetchPostsIfNeeded, invalidateReddit} from '../../actions/async'
6 | import Picker from '../../components/async/Picker.jsx'
7 | import Posts from '../../components/async/Posts.jsx'
8 | import Base from '../Base.jsx';
9 |
10 | class AsyncPage extends Base {
11 | constructor(props, context) {
12 | super(props, context);
13 | }
14 |
15 | componentDidMount() {
16 | const {dispatch, selectedReddit} = this.props
17 | dispatch(fetchPostsIfNeeded(selectedReddit))
18 | }
19 |
20 | componentWillReceiveProps(nextProps) {
21 | if (nextProps.selectedReddit !== this.props.selectedReddit) {
22 | const {dispatch, selectedReddit} = nextProps
23 | dispatch(fetchPostsIfNeeded(selectedReddit))
24 | }
25 | }
26 |
27 | onHandleChange(nextReddit) {
28 | this.props.dispatch(selectReddit(nextReddit))
29 | }
30 |
31 | onHandleRefreshClick(e) {
32 | e.preventDefault()
33 |
34 | const {dispatch, selectedReddit} = this.props
35 | dispatch(invalidateReddit(selectedReddit))
36 | dispatch(fetchPostsIfNeeded(selectedReddit))
37 | }
38 |
39 | render() {
40 | const {selectedReddit, posts, isFetching, lastUpdated} = this.props
41 | const isEmpty = posts.size === 0
42 | return (
43 |
44 |
47 |
48 | {
49 | lastUpdated ? (
50 |
51 | Last updated at {new Date(lastUpdated).toLocaleTimeString('en-US', {
52 | hour12: false
53 | })}.
54 | {' '}
55 |
56 | ) : ''
57 | }
58 | {!isFetching &&
59 |
61 | Refresh
62 |
63 | }
64 |
65 | {isEmpty
66 | ? (isFetching ?
Loading...
:
Empty.
)
67 | :
70 | }
71 |
72 | )
73 | }
74 | }
75 | AsyncPage.defaultProps = {
76 | selectedReddit: '',
77 | posts: new Immutable.List(),
78 | isFetching: false,
79 | lastUpdated: 0
80 |
81 | };
82 | AsyncPage.propTypes = {
83 | selectedReddit: PropTypes.string.isRequired,
84 | posts: ImmutablePropTypes.list.isRequired,
85 | isFetching: PropTypes.bool.isRequired,
86 | lastUpdated: PropTypes.number
87 | }
88 |
89 | const defaultOptions = ['reactjs', 'frontend'];
90 |
91 | function mapStateToProps(state) {
92 | const selectedReddit = state.get('selectedReddit');
93 | const postsByReddit = state.get('postsByReddit');
94 | const data = postsByReddit.get(state.get('selectedReddit')) || new Immutable.Map({
95 | isFetching: true,
96 | items: new Immutable.List()
97 | });
98 | const isFetching = data.get('isFetching');
99 | const lastUpdated = data.get('lastUpdated');
100 | const posts = data.get('items');
101 |
102 | return {
103 | selectedReddit,
104 | posts,
105 | isFetching,
106 | lastUpdated
107 | }
108 | }
109 |
110 | export default connect(mapStateToProps)(AsyncPage)
111 |
--------------------------------------------------------------------------------
/common/pages/chat/Page.jsx:
--------------------------------------------------------------------------------
1 | import React, {Component, PropTypes} from 'react'
2 | import {connect} from 'react-redux'
3 |
4 | import Base from '../Base.jsx';
5 | import UsersList from '../../components/chat/UsersList';
6 | import { MessageForm, MessageList } from '../../components/chat/Messages';
7 | import ChangeNameForm from '../../components/chat/ChangeNameForm';
8 |
9 | if(process.browser){
10 | var socket = io.connect();
11 | }
12 |
13 | class Page extends Base {
14 | constructor(props, context) {
15 | super(props, context);
16 |
17 | this.state = {
18 | users: [],
19 | messages: [],
20 | text: ''
21 | };
22 | }
23 |
24 | componentDidMount() {
25 | socket.on('init', this.initialize.bind(this));
26 | socket.on('send:message', this.messageRecieve.bind(this));
27 | socket.on('user:join', this.userJoined.bind(this));
28 | socket.on('user:left', this.userLeft.bind(this));
29 | socket.on('change:name', this.userChangedName.bind(this));
30 | }
31 |
32 | initialize(data) {
33 | let {users, name} = data;
34 | this.setState({users, user: name});
35 | }
36 |
37 | messageRecieve(message) {
38 | let {messages} = this.state;
39 |
40 | this.setState({
41 | messages: [
42 | ...messages,
43 | message
44 | ]
45 | });
46 | }
47 |
48 | userJoined(data) {
49 | let {users, messages} = this.state;
50 | let {name} = data;
51 |
52 | this.setState({
53 | users: [
54 | users,
55 | name
56 | ],
57 | messages: [
58 | ...messages,
59 | {
60 | user: 'APPLICATION BOT',
61 | text : name +' Joined'
62 | }
63 | ]
64 | });
65 | }
66 |
67 | userLeft(data) {
68 | let {users, messages} = this.state;
69 | let {name} = data;
70 | let index = users.indexOf(name);
71 | users.splice(index, 1);
72 |
73 | this.setState({
74 | users: [
75 | ...users
76 | ],
77 | messages: [
78 | ...messages,
79 | {
80 | user: 'APPLICATION BOT',
81 | text : name +' Left'
82 | }
83 | ]
84 | });
85 | }
86 |
87 | userChangedName(data) {
88 | let {oldName, newName} = data;
89 | let {users, messages} = this.state;
90 | let index = users.indexOf(oldName);
91 | users.splice(index, 1, newName);
92 |
93 | this.setState({
94 | users: [
95 | ...users
96 | ],
97 | messages: [
98 | ...messages,
99 | {
100 | user: 'APPLICATION BOT',
101 | text : 'Change Name : ' + oldName + ' ==> '+ newName
102 | }
103 | ]
104 | });
105 | }
106 |
107 | onMessageSubmit(message) {
108 | let {messages} = this.state;
109 |
110 | this.setState({
111 | messages: [
112 | ...messages,
113 | message
114 | ]
115 | });
116 | socket.emit('send:message', message);
117 | }
118 |
119 | onChangeName(newName) {
120 | let oldName = this.state.user;
121 | let {messages} = this.state;
122 |
123 | socket.emit('change:name', { name : newName}, (result) => {
124 | if(!result) {
125 | return alert('There was an error changing your name');
126 | }
127 | let {users} = this.state;
128 | let index = users.indexOf(oldName);
129 | users.splice(index, 1, newName);
130 |
131 | messages = messages.map((message) => {
132 | if(message.user === oldName) {
133 | return Object.assign({}, message, {
134 | user: newName
135 | });
136 | } else {
137 | return message;
138 | }
139 | });
140 |
141 | this.setState({
142 | users: [
143 | ...users
144 | ],
145 | user: newName,
146 | messages
147 | });
148 | });
149 | }
150 |
151 | render() {
152 | return (
153 |
154 |
157 |
160 |
164 |
167 |
168 | );
169 | }
170 | }
171 | export default Page;
172 |
--------------------------------------------------------------------------------
/common/pages/todo/Todo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import { connect } from 'react-redux'
3 | import { List } from 'immutable';
4 | import Base from '../Base.jsx';
5 | import { addTodo, completeTodo, setVisibilityFilter, VisibilityFilters } from '../../actions/todo'
6 | import AddTodo from '../../components/todo/AddTodo'
7 | import TodoList from '../../components/todo/TodoList'
8 | import Footer from '../../components/todo/Footer';
9 | import Tabs, { TabTitle, TabPanel } from '../../components/common/Tab';
10 |
11 | class Page extends Base {
12 | constructor(props, context) {
13 | super(props, context);
14 | }
15 |
16 | componentDidMount(){
17 | console.log(this.context.$appConfig.user);
18 |
19 | this.emit('test');
20 | }
21 |
22 | render() {
23 | // Injected by connect() call:
24 | const { dispatch, visibleTodos, visibilityFilter } = this.props
25 | return (
26 |
27 |
29 | dispatch(addTodo(text))
30 | } />
31 |
34 | dispatch(completeTodo(index))
35 | } />
36 |
56 | )
57 | }
58 | }
59 |
60 | Page.propTypes = {
61 | visibleTodos: PropTypes.instanceOf(List).isRequired,
62 | visibilityFilter: PropTypes.oneOf([
63 | 'SHOW_ALL',
64 | 'SHOW_COMPLETED',
65 | 'SHOW_ACTIVE'
66 | ]).isRequired
67 | };
68 | Page.contextTypes = {
69 | $appConfig: PropTypes.object,
70 | $eventBus: PropTypes.object
71 | };
72 |
73 | function selectTodos(todos, filter) {
74 | switch (filter) {
75 | case VisibilityFilters.SHOW_ALL:
76 | return todos
77 | case VisibilityFilters.SHOW_COMPLETED:
78 | return todos.filter(todo => todo.get('completed'))
79 | case VisibilityFilters.SHOW_ACTIVE:
80 | return todos.filter(todo => !todo.get('completed'))
81 | }
82 | }
83 |
84 | // Which props do we want to inject, given the global state?
85 | // Note: use https://github.com/faassen/reselect for better performance.
86 | function select(state) {
87 | return {
88 | visibleTodos: selectTodos(state.get('todos'), state.get('visibilityFilter')),
89 | visibilityFilter: state.get('visibilityFilter')
90 | }
91 | }
92 |
93 | // 包装 component ,注入 dispatch 和 state 到其默认的 connect(select)(App) 中;
94 | export default connect(select)(Page);
95 |
--------------------------------------------------------------------------------
/common/reducers/about.js:
--------------------------------------------------------------------------------
1 |
2 | import { combineReducers } from 'redux';
3 |
4 | export default function text(state = 'test'){
5 | return state;
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/common/reducers/async.js:
--------------------------------------------------------------------------------
1 | // import { combineReducers } from 'redux'
2 | import Immutable from 'immutable';
3 | import { combineReducers } from 'redux-immutablejs';
4 | import {
5 | SELECT_REDDIT, INVALIDATE_REDDIT,
6 | REQUEST_POSTS, RECEIVE_POSTS
7 | } from '../actions/async'
8 |
9 | function selectedReddit(state = 'reactjs', action) {
10 | switch (action.type) {
11 | case SELECT_REDDIT:
12 | return action.reddit
13 | default:
14 | return state
15 | }
16 | }
17 |
18 | function posts(state = new Immutable.Map({
19 | isFetching: false,
20 | didInvalidate: false,
21 | items: new Immutable.List()
22 | }), action) {
23 | switch (action.type) {
24 | case INVALIDATE_REDDIT:
25 | return state.set('didInvalidate', true)
26 | case REQUEST_POSTS:
27 | return state.merge({
28 | isFetching: true,
29 | didInvalidate: false
30 | });
31 | case RECEIVE_POSTS:
32 | return state.merge({
33 | isFetching: false,
34 | didInvalidate: false,
35 | items: action.posts,
36 | lastUpdated: action.receivedAt
37 | });
38 | default:
39 | return state
40 | }
41 | }
42 |
43 | function postsByReddit(state = new Immutable.Map(), action) {
44 | switch (action.type) {
45 | case INVALIDATE_REDDIT:
46 | case RECEIVE_POSTS:
47 | case REQUEST_POSTS:
48 | return state.set(action.reddit, posts(state[action.reddit], action));
49 | default:
50 | return state
51 | }
52 | }
53 |
54 | const rootReducer = combineReducers({
55 | postsByReddit,
56 | selectedReddit
57 | })
58 |
59 | export default rootReducer
60 |
--------------------------------------------------------------------------------
/common/reducers/spaReducers.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux';
2 | import about from './about';
3 | import vote from './vote';
4 |
5 | const rootReducer = combineReducers({
6 | about,
7 | vote
8 | });
9 |
10 | export default rootReducer;
11 |
--------------------------------------------------------------------------------
/common/reducers/todo.js:
--------------------------------------------------------------------------------
1 | // import { combineReducers } from 'redux'
2 | import { List, Map } from 'immutable';
3 | import { combineReducers } from 'redux-immutablejs';
4 | import { ADD_TODO, COMPLETE_TODO, SET_VISIBILITY_FILTER, VisibilityFilters } from '../actions/todo'
5 | const { SHOW_ALL } = VisibilityFilters
6 |
7 | function visibilityFilter(state = SHOW_ALL, action) {
8 | switch (action.type) {
9 | case SET_VISIBILITY_FILTER:
10 | return action.filter
11 | default:
12 | return state
13 | }
14 | }
15 |
16 | function todos(state = new List(), action) {
17 | switch (action.type) {
18 | case ADD_TODO:
19 | return state.push(new Map({
20 | text: action.text,
21 | completed: false
22 | }))
23 | case COMPLETE_TODO:
24 | return state.update(action.index, function(item){
25 | return item.set('completed', true);
26 | });
27 | default:
28 | return state
29 | }
30 | }
31 |
32 | const todoApp = combineReducers({
33 | visibilityFilter,
34 | todos
35 | })
36 |
37 | export default todoApp
38 |
--------------------------------------------------------------------------------
/common/reducers/vote.js:
--------------------------------------------------------------------------------
1 | import * as ACTIONS from '../actions/vote';
2 |
3 |
4 | export default function Vote(state = {}, action = {}) {
5 | switch (action.type) {
6 | case ACTIONS.LOAD_VOTE_SUCCESS:
7 | return action.payload;
8 | default:
9 | return state;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/common/routes.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Route, IndexRoute } from 'react-router';
3 |
4 | import connectDataFetchers from './utils/connectDataFetchers';
5 | import App from './pages/App/App';
6 | // import Vote from './universalPage/Vote';
7 | import About from './pages/App/About';
8 |
9 | // require.ensure polyfill for node
10 | if (typeof require.ensure !== 'function') {
11 | require.ensure = function requireModule(deps, callback) {
12 | callback(require);
13 | };
14 | }
15 |
16 | function onChange(prevState, nextState, replace, cb){
17 | let lastRoute = nextState.routes[nextState.routes.length - 1];
18 |
19 | if(lastRoute.component) {
20 | let component = lastRoute.component.WrappedComponent;
21 | let location = nextState.location;
22 | let pageComponent = component.OriginalPage ? component.OriginalPage : component;
23 |
24 | Object.assign(window.__APP_CONFIG__, {
25 | pageId: location.query.pageId || (pageComponent.pageConfig && pageComponent.pageConfig.pageId)
26 | });
27 | }
28 |
29 | cb();
30 | }
31 |
32 |
33 | export default (store) => {
34 | const requireAuth = (nextState, replace, callback) => {
35 | const { user: { authenticated }} = store.getState();
36 | if (!authenticated) {
37 | replace({
38 | pathname: '/login',
39 | state: { nextPathname: nextState.location.pathname }
40 | });
41 | }
42 | callback();
43 | };
44 |
45 | const redirectAuth = (nextState, replace, callback) => {
46 | const { user: { authenticated }} = store.getState();
47 | if (authenticated) {
48 | replace({
49 | pathname: '/'
50 | });
51 | }
52 | callback();
53 | };
54 | return (
55 |
56 | {
57 | require.ensure([], require => {
58 | cb(null, require('./pages/App/Vote').default);
59 | }, 'Vote');
60 | }}/>
61 | {
62 | require.ensure([], require => {
63 | cb(null, require('./pages/App/Vote').default);
64 | }, 'Vote');
65 | }}/>
66 |
67 |
68 | );
69 | };
70 |
--------------------------------------------------------------------------------
/common/store/index.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware, compose } from 'redux';
2 | import thunk from 'redux-thunk';
3 |
4 | if(process.env.NODE_ENV !== 'production' && process.browser){
5 | var createLogger = require('redux-logger');
6 | }
7 |
8 | const middlewareBuilder = () => {
9 | let middleware = applyMiddleware(thunk);
10 |
11 | if(process.env.NODE_ENV !== 'production' && process.browser){
12 | if(!window.devToolsExtension) {
13 | middleware = applyMiddleware(thunk, createLogger());
14 | }
15 | }
16 |
17 | let allComposeElements = [
18 | middleware
19 | ];
20 |
21 | if(process.env.NODE_ENV !== 'production' && process.browser){
22 | if(window.devToolsExtension){
23 | allComposeElements.push(window.devToolsExtension());
24 | }
25 | }
26 |
27 | return allComposeElements;
28 | };
29 |
30 | const finalCreateStore = compose(...middlewareBuilder())(createStore);
31 |
32 | export default function configureStore(initialState, rootReducer) {
33 | const store = finalCreateStore(rootReducer, initialState);
34 |
35 | return store;
36 | }
37 |
--------------------------------------------------------------------------------
/common/store/spaStore.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware, compose } from 'redux';
2 | // import { routerMiddleware } from 'react-router-redux';
3 | import thunk from 'redux-thunk';
4 | import rootReducer from '../reducers/spaReducers';
5 |
6 | if(process.env.NODE_ENV !== 'production' && process.browser){
7 | var createLogger = require('redux-logger');
8 | }
9 |
10 | export default function configureStore(initialState, history) {
11 | const middleware = [
12 | thunk
13 | ];
14 | let store;
15 |
16 | if (process.browser) {
17 | if(process.env.NODE_ENV !== 'production') {
18 | middleware.push(createLogger());
19 |
20 | store = createStore(rootReducer, initialState, compose(
21 | applyMiddleware(...middleware),
22 | typeof window.devToolsExtension !== 'undefined' ? window.devToolsExtension() : f => f
23 | ));
24 | } else {
25 | store = createStore(rootReducer, initialState, compose(
26 | applyMiddleware(...middleware)
27 | ));
28 | }
29 |
30 | } else {
31 | store = createStore(rootReducer, initialState, compose(applyMiddleware(...middleware), f => f));
32 | }
33 |
34 | if (module.hot) {
35 | // Enable Webpack hot module replacement for reducers
36 | module.hot.accept('../reducers/spaReducers', () => {
37 | const nextReducer = require('../reducers/spaReducers');
38 | store.replaceReducer(nextReducer);
39 | });
40 | }
41 |
42 | return store;
43 | }
44 |
--------------------------------------------------------------------------------
/common/utils/connectDataFetchers.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | PropTypes
3 | } from 'react';
4 | import Base from '../pages/Base';
5 |
6 | let IS_FIRST_MOUNT_AFTER_LOAD = true;
7 | if (process.browser) {
8 | var FIRST_PAGE_ID = window.__APP_CONFIG__.pageId;
9 | }
10 |
11 | export default function connectDataFetchers(actionCreators, cache) {
12 | return function (Page) {
13 | if (process.browser) {
14 | if (!Page.pageConfig) {
15 | console.error(`Page Component static propery pageConfig.pageId required!`);
16 | } else {
17 | IS_FIRST_MOUNT_AFTER_LOAD = Page.pageConfig.pageId === FIRST_PAGE_ID;
18 | }
19 | }
20 |
21 | class DataFetchersWrapper extends Base {
22 | static propTypes = {
23 | dispatch: PropTypes.func.isRequired,
24 | params: PropTypes.object,
25 | location: PropTypes.shape({
26 | pathname: PropTypes.string.required,
27 | search: PropTypes.string,
28 | query: PropTypes.string.object
29 | }).isRequired
30 | };
31 |
32 | static contextTypes = {
33 | $appConfig: PropTypes.object
34 | };
35 |
36 | static OriginalPage = Page;
37 |
38 | static fetchData({
39 | dispatch,
40 | location,
41 | params,
42 | appConfig,
43 | pageConfig
44 | }, req) {
45 | return Promise.all(
46 | actionCreators.map(actionCreator => dispatch(actionCreator({
47 | dispatch,
48 | location,
49 | params,
50 | appConfig,
51 | pageConfig
52 | }, req)))
53 | );
54 | }
55 |
56 | shouldComponentUpdate(nextProps) {
57 | return this.props !== nextProps;
58 | }
59 |
60 | componentDidUpdate(prevProps) {
61 | const {
62 | location
63 | } = this.props;
64 | const {
65 | location: prevLocation
66 | } = prevProps;
67 |
68 | const isUrlChanged = (location.pathname !== prevLocation.pathname) ||
69 | (location.search.slice(1) !== prevLocation.search.slice(1));
70 |
71 | if (isUrlChanged) {
72 | this._fetchDataOnClient();
73 | }
74 | }
75 |
76 | componentDidMount() {
77 | if (!cache) {
78 | if (!IS_FIRST_MOUNT_AFTER_LOAD) {
79 | this._fetchDataOnClient();
80 | }
81 |
82 | IS_FIRST_MOUNT_AFTER_LOAD = false;
83 | } else {
84 | if (!IS_FIRST_MOUNT_AFTER_LOAD && !Page.DATA_LOADED) {
85 | this._fetchDataOnClient();
86 | }
87 |
88 | Page.DATA_LOADED = true;
89 | IS_FIRST_MOUNT_AFTER_LOAD = false;
90 | }
91 | }
92 |
93 | _fetchDataOnClient() {
94 | this.constructor.fetchData({
95 | dispatch: this.props.dispatch,
96 | params: this.props.params,
97 | location: this.props.location,
98 | appConfig: this.context.$appConfig
99 | });
100 | }
101 |
102 | render() {
103 | return (
104 |
105 | );
106 | }
107 | }
108 |
109 | return DataFetchersWrapper;
110 | };
111 | }
112 |
--------------------------------------------------------------------------------
/common/utils/shallowEqual.js:
--------------------------------------------------------------------------------
1 | // modified
2 | /**
3 | * Copyright (c) 2013-present, Facebook, Inc.
4 | * All rights reserved.
5 | *
6 | * This source code is licensed under the BSD-style license found in the
7 | * LICENSE file in the root directory of this source tree. An additional grant
8 | * of patent rights can be found in the PATENTS file in the same directory.
9 | *
10 | * @typechecks
11 | *
12 | */
13 |
14 | /*eslint-disable no-self-compare */
15 |
16 | 'use strict';
17 |
18 | var hasOwnProperty = Object.prototype.hasOwnProperty;
19 |
20 | /**
21 | * inlined Object.is polyfill to avoid requiring consumers ship their own
22 | * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
23 | */
24 | function is(x, y) {
25 | // SameValue algorithm
26 | if (x === y) {
27 | return true;
28 | } else {
29 | if(typeof x === 'function' && typeof y === 'function'){
30 | return x.toString() === y.toString();
31 | }
32 | return false;
33 | }
34 | }
35 |
36 | /**
37 | * Performs equality by iterating through keys on an object and returning false
38 | * when any key has values which are not strictly equal between the arguments.
39 | * Returns true when the values of all keys are strictly equal.
40 | */
41 | function shallowEqual(objA, objB) {
42 | if (is(objA, objB)) {
43 | return true;
44 | }
45 |
46 | if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
47 | return false;
48 | }
49 |
50 | var keysA = Object.keys(objA);
51 | var keysB = Object.keys(objB);
52 |
53 | if (keysA.length !== keysB.length) {
54 | return false;
55 | }
56 |
57 | // Test for A's keys different from B.
58 | for (var i = 0; i < keysA.length; i++) {
59 | if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
60 | return false;
61 | }
62 | }
63 |
64 | return true;
65 | }
66 |
67 | module.exports = shallowEqual;
68 |
--------------------------------------------------------------------------------
/create-webpack-libs.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Devicalin on 2015/11/15.
3 | */
4 | 'use strict';
5 |
6 | let webpack = require('webpack');
7 | let path = require('path');
8 | let fs = require('fs');
9 | let ProgressBarPlugin = require('progress-bar-webpack-plugin');
10 | let HappyPack = require('happypack');
11 |
12 | module.exports = function(DEBUG){
13 | let happyId = DEBUG ? 'libs-debug' : 'libs';
14 |
15 | let plugins = [
16 | new HappyPack({ id: happyId }),
17 | new webpack.optimize.OccurrenceOrderPlugin(),
18 | new ProgressBarPlugin({
19 | format: ' build libs [:bar] :percent (:elapsed seconds)',
20 | clear: false
21 | }),
22 | new webpack.DllPlugin({
23 | path: DEBUG ? 'manifest-debug.json' : 'manifest.json',
24 | name: '[name]_lib',
25 | context: __dirname
26 | })
27 | ];
28 | if (!DEBUG) {
29 | plugins.push(
30 | new webpack.optimize.UglifyJsPlugin({
31 | output: {
32 | comments: false
33 | },
34 | compress: {
35 | warnings: false
36 | },
37 | sourceMap: false
38 | }),
39 | new webpack.optimize.DedupePlugin(),
40 | new webpack.DefinePlugin({
41 | 'process.env': {
42 | NODE_ENV: JSON.stringify('production')
43 | }
44 | }),
45 | new webpack.NoErrorsPlugin()
46 | );
47 | }
48 |
49 | let libs = [
50 | 'react',
51 | 'react-dom',
52 | 'redux',
53 | 'react-redux',
54 | 'redux-thunk',
55 | 'react-router',
56 | 'react-router-redux',
57 | 'immutable',
58 | 'redux-immutablejs',
59 | 'react-immutable-proptypes',
60 | 'fastclick'
61 | ];
62 | if(DEBUG) {
63 | libs.push(
64 | 'why-did-you-update',
65 | 'redux-logger',
66 | 'react-addons-perf'
67 | );
68 | }
69 |
70 | let loaders = [
71 | // Load ES6/JSX
72 | {
73 | test: /\.jsx?$/,
74 | exclude: /(node_modules|bower_components)/,
75 | loader: 'babel',
76 | query: {
77 | cacheDirectory: true,
78 | // "presets": ["es2015"],
79 | // "plugins": ["transform-runtime"]
80 | },
81 | happy: { id: happyId }
82 | }
83 | ];
84 |
85 | return {
86 | target: 'web',
87 | entry: {
88 | libs: libs
89 | },
90 | output: {
91 | path: './public/',
92 | filename: DEBUG ? "./js/[name]-debug.js" : "./js/[name]-min.js",
93 | chunkFilename: DEBUG ? "./js/[name]-debug.js" : "./js/[name]-min.js",
94 | publicPath: '',
95 | pathinfo: false,
96 | libraryTarget: 'umd',
97 | library: '[name]_lib'
98 | },
99 |
100 | cache: true,
101 | debug: DEBUG,
102 |
103 | // For options, see http://webpack.github.io/docs/configuration.html#devtool
104 | devtool: DEBUG && "eval-source-map",
105 | // devtool: DEBUG && "cheap-module-eval-source-map",
106 |
107 | module: {
108 | loaders: loaders,
109 | noParse: []
110 | },
111 |
112 | plugins: plugins,
113 |
114 | externals: {
115 | },
116 |
117 | resolve: {
118 | root: path.resolve('/'),
119 | modulesDirectories: [
120 | "node_modules",
121 |
122 | // https://github.com/webpack/webpack-dev-server/issues/60
123 | "web_modules"
124 | ],
125 |
126 | // Allow to omit extensions when requiring these files
127 | extensions: ["", ".js", ".jsx", ".es6", '.json'],
128 |
129 | alias: {}
130 | }
131 | };
132 |
133 | };
134 |
--------------------------------------------------------------------------------
/create-webpack.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by Devicalin on 2015/11/15.
3 | */
4 | 'use strict';
5 |
6 | let webpack = require('webpack');
7 | let path = require('path');
8 | let fs = require('fs');
9 | let ExtractTextPlugin = require('extract-text-webpack-plugin');
10 | let ProgressBarPlugin = require('progress-bar-webpack-plugin');
11 | let HappyPack = require('happypack');
12 |
13 |
14 | module.exports = function (DEBUG) {
15 | let happyId = DEBUG ? 'app-debug' : 'app';
16 |
17 |
18 | let plugins = [
19 | new HappyPack({id: happyId}),
20 | new webpack.optimize.OccurrenceOrderPlugin(),
21 | //new NyanProgressPlugin()
22 | new ProgressBarPlugin({
23 | format: ' build [:bar] :percent (:elapsed seconds)',
24 | clear: false
25 | }),
26 | new webpack.DllReferencePlugin({
27 | context: __dirname,
28 | manifest: require('./' + (DEBUG ? 'manifest-debug.json' : 'manifest.json'))
29 | }),
30 | new ExtractTextPlugin(DEBUG ? './css/main.css' : './css/main-min.css', {
31 | allChunks: true
32 | })
33 | ];
34 | if (DEBUG) {
35 | plugins.push(
36 | new webpack.HotModuleReplacementPlugin()
37 | );
38 | } else {
39 | plugins.push(
40 | new webpack.optimize.UglifyJsPlugin({
41 | output: {
42 | comments: false
43 | },
44 | compress: {
45 | warnings: false
46 | },
47 | sourceMap: false
48 | }),
49 | function () {
50 | this.plugin("done", function (stats) {
51 | let jsonStats = stats.toJson({
52 | chunkModules: true
53 | });
54 | let assetsByChunkName = jsonStats.assetsByChunkName;
55 | let obj = {};
56 | for (let key in assetsByChunkName) {
57 | if (!assetsByChunkName.hasOwnProperty(key)) continue;
58 |
59 | let value = assetsByChunkName[key];
60 | let match = value[0].match(/-(\w+)\.js$/);
61 | if (match) {
62 | obj[key] = match[1];
63 | }
64 | }
65 |
66 | fs.writeFileSync(
67 | __dirname + "/webpack-assets.json",
68 | JSON.stringify(obj)
69 | );
70 | });
71 | },
72 | new webpack.optimize.DedupePlugin(),
73 | new webpack.DefinePlugin({
74 | 'process.env': {
75 | NODE_ENV: JSON.stringify('production')
76 | }
77 | }),
78 | new webpack.NoErrorsPlugin()
79 | );
80 | }
81 |
82 | function getPagesNames(dirPath) {
83 | let filesNames = fs.readdirSync(dirPath);
84 | let entries = {
85 | app: __dirname + '/client/js/utils/spaRenderer.js'
86 | };
87 |
88 | for (let fileName of filesNames) {
89 | if (DEBUG) {
90 | entries[fileName.split('.').shift() || fileName] = [
91 | // 'webpack-hot-middleware/client',
92 | `${dirPath}/${fileName}`
93 | ];
94 | } else {
95 | entries[fileName.split('.').shift() || fileName] = [`${dirPath}/${fileName}`];
96 | }
97 | }
98 |
99 | return entries;
100 | }
101 |
102 | let babelPlugins = [
103 | "syntax-async-functions",
104 | 'transform-regenerator',
105 | "transform-decorators-legacy",
106 | "transform-class-properties",
107 |
108 | ["transform-runtime", {
109 | // "helpers": false,
110 | "polyfill": false,
111 | "regenerator": true
112 | }]
113 | ];
114 | if (!DEBUG) {
115 | babelPlugins.push(
116 | 'transform-react-remove-prop-types',
117 | 'transform-react-constant-elements',
118 | 'transform-react-inline-elements'
119 | );
120 | }
121 |
122 | return {
123 | target: 'web',
124 | entry: getPagesNames(__dirname + '/client/js/pages'),
125 | output: {
126 | path: __dirname + '/public/',
127 | filename: DEBUG ? "/js/debug/[name].js" : "/js/min/[name]-[chunkhash].js",
128 | // filename: DEBUG ? "./js/debug/[name].js" : "./js/min/[name].js",
129 | chunkFilename: DEBUG ? "/js/debug/[name].js" : "/js/min/[name]-[chunkhash].js",
130 | // chunkFilename: DEBUG ? "./js/debug/[name].js" : "./js/min/[name].js",
131 | publicPath: '/static',
132 | pathinfo: true
133 | },
134 |
135 | cache: true,
136 | debug: DEBUG,
137 |
138 | // For options, see http://webpack.github.io/docs/configuration.html#devtool
139 | //devtool: DEBUG && "eval-source-map",
140 | devtool: DEBUG && "#inline-source-map",
141 |
142 | module: {
143 | loaders: [
144 | // Load ES6/JSX
145 | {
146 | test: /\.jsx?$/,
147 | exclude: /(node_modules|bower_components)/,
148 | loader: require.resolve('babel-loader'),
149 | query: {
150 | cacheDirectory: true,
151 | // fixed resolve path in parent directory error
152 | "presets": [
153 | "react",
154 | [
155 | "es2015",
156 | { loose: true }
157 | ]
158 | ].map((preset) => {
159 | if (typeof preset === 'string')
160 | return require.resolve(`babel-preset-${preset}`);
161 | else if (Array.isArray(preset))
162 | return [require.resolve(`babel-preset-${preset[0]}`), preset[1]];
163 | }),
164 | "plugins": babelPlugins.map((preset) => {
165 | if (typeof preset === 'string')
166 | return require.resolve(`babel-plugin-${preset}`);
167 | else if (Array.isArray(preset))
168 | return [require.resolve(`babel-plugin-${preset[0]}`), preset[1]];
169 | })
170 | },
171 | happy: {id: happyId}
172 | },
173 |
174 | {
175 | test: /\.json$/,
176 | exclude: /node_modules/,
177 | loaders: ['json-loader']
178 | },
179 |
180 | // Load styles
181 | {
182 | test: /\.css$/,
183 | loader: //DEBUG
184 | //? "style!css" :
185 | ExtractTextPlugin.extract("style-loader", "css-loader")
186 | },
187 |
188 | // Load images
189 | {test: /\.jpg/, loader: "url-loader?limit=1024&mimetype=image/jpg&name=./img/[name].[ext]"},
190 | {test: /\.gif/, loader: "url-loader?limit=1024&mimetype=image/gif&name=./img/[name].[ext]"},
191 | {test: /\.png/, loader: "url-loader?limit=1024&mimetype=image/png&name=./img/[name].[ext]"},
192 | {test: /\.svg/, loader: "url-loader?limit=1024&mimetype=image/svg&name=./img/[name].[ext]"},
193 |
194 | // Load fonts
195 | {
196 | test: /\.woff$/,
197 | loader: "url-loader?limit=1024&minetype=application/font-woff&name=./font/[name].[ext]"
198 | },
199 | {test: /\.(ttf|eot|svg)$/, loader: "file-loader?name=./font/[name].[ext]"}
200 | ],
201 | noParse: []
202 | },
203 |
204 | plugins: plugins,
205 |
206 | externals: {},
207 |
208 | resolve: {
209 | root: path.resolve('/'),
210 | modulesDirectories: [
211 | "node_modules",
212 |
213 | // https://github.com/webpack/webpack-dev-server/issues/60
214 | "web_modules"
215 | ],
216 |
217 | // Allow to omit extensions when requiring these files
218 | extensions: ["", ".js", ".jsx", ".es6", '.json'],
219 |
220 | alias: {
221 | // 'libs': path.join(__dirname, './common/libs')
222 | }
223 | }
224 | };
225 |
226 | };
227 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @Author Devicalin
3 | */
4 |
5 | var fs = require('fs');
6 | var gulp = require('gulp');
7 | var webpack = require('webpack');
8 | var createLibsWebpackConfig = require('./create-webpack-libs.config.js');
9 | var createWebpackConfig = require('./create-webpack.config.js');
10 | var del = require('del');
11 | var browserSync = require('browser-sync').create();
12 |
13 | gulp.task('default', ['build-dev', 'build']);
14 |
15 | gulp.task('clean', function (cb) {
16 | return del([
17 | './public/js/min/'
18 | ], {
19 | force: true
20 | });
21 | });
22 |
23 | gulp.task('clean:dev', function (cb) {
24 | return del([
25 | './public/js/debug/'
26 | ], {
27 | force: true
28 | });
29 | });
30 |
31 | gulp.task('build:lib', function(cb){
32 | webpack(createLibsWebpackConfig(), function (err, stats) {
33 | if (err) throw new Error(err);
34 |
35 | if (stats.compilation.errors.length) {
36 | console.log(stats.compilation.errors[0]);
37 | }
38 |
39 | console.log('webpack libs end');
40 | cb();
41 | });
42 | });
43 |
44 | gulp.task('build', ['clean'], function (cb) {
45 | webpack(createWebpackConfig(), function (err, stats) {
46 | if (err) throw new Error(err);
47 |
48 | if (stats.compilation.errors.length) {
49 | console.log(stats.compilation.errors[0]);
50 | }
51 |
52 | console.log('webpack end');
53 | cb();
54 | });
55 | });
56 |
57 | gulp.task('build:lib:dev', function(cb){
58 | webpack(createLibsWebpackConfig(true), function (err, stats) {
59 | if (err) throw new Error(err);
60 |
61 | if (stats.compilation.errors.length) {
62 | console.log(stats.compilation.errors[0]);
63 | }
64 |
65 | console.log('webpack libs dev end');
66 | cb();
67 | });
68 | });
69 |
70 | gulp.task('build:dev', ['clean:dev'], function (cb) {
71 | webpack(createWebpackConfig(true), function (err, stats) {
72 | if (err) throw new Error(err);
73 |
74 | if (stats.compilation.errors.length) {
75 | console.log(stats.compilation.errors[0].error);
76 | }
77 |
78 | console.log('webpack dev end');
79 |
80 | browserSync.reload();
81 |
82 | cb();
83 | });
84 | });
85 |
86 | gulp.task('watch', ['build:dev'], function(){
87 | browserSync.init({
88 | files: ['public/**/*.*'],
89 | proxy: 'http://127.0.0.1:3000',
90 | port: 4000,
91 | open: false
92 | });
93 |
94 | gulp.watch('client/**', ['build:dev']);
95 | gulp.watch('common/**', ['build:dev']);
96 | });
97 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | if(process.env.NODE_ENV !== 'production') {
2 | console.log('start server in development mode');
3 | require('babel-register');
4 | require('./server/app');
5 | } else {
6 | require('./dist/server');
7 | }
8 |
--------------------------------------------------------------------------------
/manifest-debug.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "libs_lib",
3 | "content": {
4 | "./node_modules/node-libs-browser/node_modules/process/browser.js": 1,
5 | "./node_modules/fbjs/lib/warning.js": 2,
6 | "./node_modules/fbjs/lib/invariant.js": 3,
7 | "./node_modules/react/lib/reactProdInvariant.js": 4,
8 | "./node_modules/object-assign/index.js": 5,
9 | "./node_modules/react/lib/ReactDOMComponentTree.js": 6,
10 | "./node_modules/react/react.js": 7,
11 | "./node_modules/fbjs/lib/ExecutionEnvironment.js": 8,
12 | "./node_modules/invariant/browser.js": 9,
13 | "./node_modules/react/lib/ReactInstrumentation.js": 10,
14 | "./node_modules/fbjs/lib/emptyFunction.js": 11,
15 | "./node_modules/react/lib/ReactComponentTreeHook.js": 12,
16 | "./node_modules/react/lib/ReactElement.js": 13,
17 | "./node_modules/react/lib/ReactUpdates.js": 14,
18 | "./node_modules/react/lib/EventConstants.js": 15,
19 | "./node_modules/react/lib/ReactCurrentOwner.js": 16,
20 | "./node_modules/react/lib/SyntheticEvent.js": 17,
21 | "./node_modules/why-did-you-update/node_modules/lodash/isArray.js": 18,
22 | "./node_modules/fbjs/lib/keyOf.js": 19,
23 | "./node_modules/history/lib/PathUtils.js": 20,
24 | "./node_modules/react-router/lib/RouteUtils.js": 21,
25 | "./node_modules/react/lib/PooledClass.js": 22,
26 | "./node_modules/warning/browser.js": 23,
27 | "./node_modules/react/lib/DOMProperty.js": 24,
28 | "./node_modules/why-did-you-update/node_modules/lodash/_root.js": 25,
29 | "./node_modules/why-did-you-update/node_modules/lodash/isObject.js": 26,
30 | "./node_modules/history/lib/LocationUtils.js": 27,
31 | "./node_modules/react-router/lib/PatternUtils.js": 28,
32 | "./node_modules/react-router/lib/routerWarning.js": 29,
33 | "./node_modules/react/lib/DOMLazyTree.js": 30,
34 | "./node_modules/react/lib/ReactReconciler.js": 31,
35 | "./node_modules/why-did-you-update/node_modules/lodash/_getNative.js": 32,
36 | "./node_modules/fbjs/lib/emptyObject.js": 33,
37 | "./node_modules/react-router/lib/InternalPropTypes.js": 34,
38 | "./node_modules/react/lib/EventPluginHub.js": 35,
39 | "./node_modules/react/lib/EventPropagators.js": 36,
40 | "./node_modules/react/lib/ReactInstanceMap.js": 37,
41 | "./node_modules/react/lib/SyntheticUIEvent.js": 38,
42 | "./node_modules/react/lib/Transaction.js": 39,
43 | "./node_modules/why-did-you-update/node_modules/lodash/isFunction.js": 40,
44 | "./node_modules/why-did-you-update/node_modules/lodash/isObjectLike.js": 41,
45 | "./node_modules/fbjs/lib/keyMirror.js": 42,
46 | "./node_modules/history/lib/Actions.js": 43,
47 | "./node_modules/history/lib/DOMUtils.js": 44,
48 | "./node_modules/immutable/dist/immutable.js": 45,
49 | "./node_modules/react/lib/DisabledInputUtils.js": 46,
50 | "./node_modules/react/lib/EventPluginRegistry.js": 47,
51 | "./node_modules/react/lib/ReactBrowserEventEmitter.js": 48,
52 | "./node_modules/react/lib/ReactPropTypeLocations.js": 49,
53 | "./node_modules/react/lib/SyntheticMouseEvent.js": 50,
54 | "./node_modules/react/lib/escapeTextContentForBrowser.js": 51,
55 | "./node_modules/react/lib/setInnerHTML.js": 52,
56 | "./node_modules/why-did-you-update/node_modules/lodash/_ListCache.js": 53,
57 | "./node_modules/why-did-you-update/node_modules/lodash/_assocIndexOf.js": 54,
58 | "./node_modules/why-did-you-update/node_modules/lodash/_getMapData.js": 55,
59 | "./node_modules/why-did-you-update/node_modules/lodash/_isKey.js": 56,
60 | "./node_modules/why-did-you-update/node_modules/lodash/_nativeCreate.js": 57,
61 | "./node_modules/why-did-you-update/node_modules/lodash/_toKey.js": 58,
62 | "./node_modules/why-did-you-update/node_modules/lodash/isArrayLike.js": 59,
63 | "./node_modules/why-did-you-update/node_modules/lodash/isLength.js": 60,
64 | "./node_modules/why-did-you-update/node_modules/lodash/isSymbol.js": 61,
65 | "./node_modules/why-did-you-update/node_modules/lodash/keys.js": 62,
66 | "./node_modules/fbjs/lib/shallowEqual.js": 63,
67 | "./node_modules/history/lib/BrowserProtocol.js": 64,
68 | "./node_modules/history/lib/ExecutionEnvironment.js": 65,
69 | "./node_modules/history/lib/createHistory.js": 66,
70 | "./node_modules/history/lib/runTransitionHook.js": 67,
71 | "./node_modules/lodash/isPlainObject.js": 68,
72 | "./node_modules/react-router/lib/AsyncUtils.js": 69,
73 | "./node_modules/react-router/lib/ContextUtils.js": 70,
74 | "./node_modules/react-router/lib/PropTypes.js": 71,
75 | "./node_modules/react-router/lib/RouterContext.js": 72,
76 | "./node_modules/react/lib/DOMChildrenOperations.js": 73,
77 | "./node_modules/react/lib/DOMNamespaces.js": 74,
78 | "./node_modules/react/lib/EventPluginUtils.js": 75,
79 | "./node_modules/react/lib/KeyEscapeUtils.js": 76,
80 | "./node_modules/react/lib/LinkedValueUtils.js": 77,
81 | "./node_modules/react/lib/ReactComponent.js": 78,
82 | "./node_modules/react/lib/ReactComponentEnvironment.js": 79,
83 | "./node_modules/react/lib/ReactErrorUtils.js": 80,
84 | "./node_modules/react/lib/ReactNoopUpdateQueue.js": 81,
85 | "./node_modules/react/lib/ReactPropTypeLocationNames.js": 82,
86 | "./node_modules/react/lib/ReactPropTypesSecret.js": 83,
87 | "./node_modules/react/lib/ReactUpdateQueue.js": 84,
88 | "./node_modules/react/lib/canDefineProperty.js": 85,
89 | "./node_modules/react/lib/createMicrosoftUnsafeLocalFunction.js": 86,
90 | "./node_modules/react/lib/getEventCharCode.js": 87,
91 | "./node_modules/react/lib/getEventModifierState.js": 88,
92 | "./node_modules/react/lib/getEventTarget.js": 89,
93 | "./node_modules/react/lib/getIteratorFn.js": 90,
94 | "./node_modules/react/lib/isEventSupported.js": 91,
95 | "./node_modules/react/lib/shouldUpdateReactComponent.js": 92,
96 | "./node_modules/react/lib/traverseAllChildren.js": 93,
97 | "./node_modules/react/lib/validateDOMNesting.js": 94,
98 | "./node_modules/why-did-you-update/node_modules/lodash/_MapCache.js": 95,
99 | "./node_modules/why-did-you-update/node_modules/lodash/_baseIsEqual.js": 96,
100 | "./node_modules/why-did-you-update/node_modules/lodash/_isIndex.js": 97,
101 | "./node_modules/why-did-you-update/node_modules/lodash/_setToArray.js": 98,
102 | "./node_modules/why-did-you-update/node_modules/lodash/isArguments.js": 99,
103 | "./node_modules/why-did-you-update/node_modules/lodash/isString.js": 100,
104 | "./node_modules/fbjs/lib/EventListener.js": 101,
105 | "./node_modules/fbjs/lib/focusNode.js": 102,
106 | "./node_modules/fbjs/lib/getActiveElement.js": 103,
107 | "./node_modules/history/lib/DOMStateStorage.js": 104,
108 | "./node_modules/history/lib/useBasename.js": 105,
109 | "./node_modules/history/lib/useQueries.js": 106,
110 | "./node_modules/hoist-non-react-statics/index.js": 107,
111 | "./node_modules/react-redux/lib/utils/storeShape.js": 108,
112 | "./node_modules/react-redux/lib/utils/warning.js": 109,
113 | "./node_modules/react-router-redux/lib/actions.js": 110,
114 | "./node_modules/react-router-redux/lib/reducer.js": 111,
115 | "./node_modules/react-router/lib/Link.js": 112,
116 | "./node_modules/react-router/lib/PromiseUtils.js": 113,
117 | "./node_modules/react-router/lib/Redirect.js": 114,
118 | "./node_modules/react-router/lib/RouterUtils.js": 115,
119 | "./node_modules/react-router/lib/createMemoryHistory.js": 116,
120 | "./node_modules/react-router/lib/createRouterHistory.js": 117,
121 | "./node_modules/react-router/lib/createTransitionManager.js": 118,
122 | "./node_modules/react-router/lib/useRouterHistory.js": 119,
123 | "./node_modules/react/lib/CSSProperty.js": 120,
124 | "./node_modules/react/lib/CallbackQueue.js": 121,
125 | "./node_modules/react/lib/DOMPropertyOperations.js": 122,
126 | "./node_modules/react/lib/ReactChildren.js": 123,
127 | "./node_modules/react/lib/ReactClass.js": 124,
128 | "./node_modules/react/lib/ReactDOMComponentFlags.js": 125,
129 | "./node_modules/react/lib/ReactDOMSelect.js": 126,
130 | "./node_modules/react/lib/ReactDebugTool.js": 127,
131 | "./node_modules/react/lib/ReactElementValidator.js": 128,
132 | "./node_modules/react/lib/ReactEmptyComponent.js": 129,
133 | "./node_modules/react/lib/ReactFeatureFlags.js": 130,
134 | "./node_modules/react/lib/ReactHostComponent.js": 131,
135 | "./node_modules/react/lib/ReactInputSelection.js": 132,
136 | "./node_modules/react/lib/ReactMount.js": 133,
137 | "./node_modules/react/lib/ReactMultiChildUpdateTypes.js": 134,
138 | "./node_modules/react/lib/ReactNodeTypes.js": 135,
139 | "./node_modules/react/lib/ReactPropTypes.js": 136,
140 | "./node_modules/react/lib/ReactVersion.js": 137,
141 | "./node_modules/react/lib/ViewportMetrics.js": 138,
142 | "./node_modules/react/lib/accumulateInto.js": 139,
143 | "./node_modules/react/lib/checkReactTypeSpec.js": 140,
144 | "./node_modules/react/lib/forEachAccumulated.js": 141,
145 | "./node_modules/react/lib/getHostComponentFromComposite.js": 142,
146 | "./node_modules/react/lib/getTextContentAccessor.js": 143,
147 | "./node_modules/react/lib/instantiateReactComponent.js": 144,
148 | "./node_modules/react/lib/isTextInputElement.js": 145,
149 | "./node_modules/react/lib/setTextContent.js": 146,
150 | "./node_modules/redux-logger/lib/helpers.js": 147,
151 | "./node_modules/redux/lib/compose.js": 148,
152 | "./node_modules/redux/lib/createStore.js": 149,
153 | "./node_modules/redux/lib/index.js": 150,
154 | "./node_modules/redux/lib/utils/warning.js": 151,
155 | "./node_modules/webpack/buildin/module.js": 152,
156 | "./node_modules/why-did-you-update/node_modules/lodash/_Map.js": 153,
157 | "./node_modules/why-did-you-update/node_modules/lodash/_Set.js": 154,
158 | "./node_modules/why-did-you-update/node_modules/lodash/_SetCache.js": 155,
159 | "./node_modules/why-did-you-update/node_modules/lodash/_Stack.js": 156,
160 | "./node_modules/why-did-you-update/node_modules/lodash/_Symbol.js": 157,
161 | "./node_modules/why-did-you-update/node_modules/lodash/_arraySome.js": 158,
162 | "./node_modules/why-did-you-update/node_modules/lodash/_baseGet.js": 159,
163 | "./node_modules/why-did-you-update/node_modules/lodash/_baseHas.js": 160,
164 | "./node_modules/why-did-you-update/node_modules/lodash/_baseProperty.js": 161,
165 | "./node_modules/why-did-you-update/node_modules/lodash/_castPath.js": 162,
166 | "./node_modules/why-did-you-update/node_modules/lodash/_equalArrays.js": 163,
167 | "./node_modules/why-did-you-update/node_modules/lodash/_getTag.js": 164,
168 | "./node_modules/why-did-you-update/node_modules/lodash/_isHostObject.js": 165,
169 | "./node_modules/why-did-you-update/node_modules/lodash/_isStrictComparable.js": 166,
170 | "./node_modules/why-did-you-update/node_modules/lodash/_mapToArray.js": 167,
171 | "./node_modules/why-did-you-update/node_modules/lodash/_matchesStrictComparable.js": 168,
172 | "./node_modules/why-did-you-update/node_modules/lodash/_toSource.js": 169,
173 | "./node_modules/why-did-you-update/node_modules/lodash/eq.js": 170,
174 | "./node_modules/why-did-you-update/node_modules/lodash/isArrayLikeObject.js": 171,
175 | "./node_modules/deep-diff/index.js": 172,
176 | "./node_modules/fastclick/lib/fastclick.js": 173,
177 | "./node_modules/fbjs/lib/camelize.js": 174,
178 | "./node_modules/fbjs/lib/camelizeStyleName.js": 175,
179 | "./node_modules/fbjs/lib/containsNode.js": 176,
180 | "./node_modules/fbjs/lib/createArrayFromMixed.js": 177,
181 | "./node_modules/fbjs/lib/createNodesFromMarkup.js": 178,
182 | "./node_modules/fbjs/lib/getMarkupWrap.js": 179,
183 | "./node_modules/fbjs/lib/getUnboundedScrollPosition.js": 180,
184 | "./node_modules/fbjs/lib/hyphenate.js": 181,
185 | "./node_modules/fbjs/lib/hyphenateStyleName.js": 182,
186 | "./node_modules/fbjs/lib/isNode.js": 183,
187 | "./node_modules/fbjs/lib/isTextNode.js": 184,
188 | "./node_modules/fbjs/lib/memoizeStringOnly.js": 185,
189 | "./node_modules/fbjs/lib/performance.js": 186,
190 | "./node_modules/fbjs/lib/performanceNow.js": 187,
191 | "./node_modules/history/lib/AsyncUtils.js": 188,
192 | "./node_modules/history/lib/HashProtocol.js": 189,
193 | "./node_modules/history/lib/RefreshProtocol.js": 190,
194 | "./node_modules/history/lib/createBrowserHistory.js": 191,
195 | "./node_modules/history/lib/createHashHistory.js": 192,
196 | "./node_modules/history/lib/createMemoryHistory.js": 193,
197 | "./node_modules/lodash/_getPrototype.js": 194,
198 | "./node_modules/lodash/_isHostObject.js": 195,
199 | "./node_modules/lodash/isObjectLike.js": 196,
200 | "./node_modules/query-string/index.js": 197,
201 | "./node_modules/react-addons-perf/index.js": 198,
202 | "./node_modules/react-dom/index.js": 199,
203 | "./node_modules/react-immutable-proptypes/dist/ImmutablePropTypes.js": 200,
204 | "./node_modules/react-redux/lib/components/Provider.js": 201,
205 | "./node_modules/react-redux/lib/components/connect.js": 202,
206 | "./node_modules/react-redux/lib/index.js": 203,
207 | "./node_modules/react-redux/lib/utils/shallowEqual.js": 204,
208 | "./node_modules/react-redux/lib/utils/wrapActionCreators.js": 205,
209 | "./node_modules/react-router-redux/lib/index.js": 206,
210 | "./node_modules/react-router-redux/lib/middleware.js": 207,
211 | "./node_modules/react-router-redux/lib/sync.js": 208,
212 | "./node_modules/react-router/lib/IndexLink.js": 209,
213 | "./node_modules/react-router/lib/IndexRedirect.js": 210,
214 | "./node_modules/react-router/lib/IndexRoute.js": 211,
215 | "./node_modules/react-router/lib/Route.js": 212,
216 | "./node_modules/react-router/lib/Router.js": 213,
217 | "./node_modules/react-router/lib/TransitionUtils.js": 214,
218 | "./node_modules/react-router/lib/applyRouterMiddleware.js": 215,
219 | "./node_modules/react-router/lib/browserHistory.js": 216,
220 | "./node_modules/react-router/lib/computeChangedRoutes.js": 217,
221 | "./node_modules/react-router/lib/getComponents.js": 218,
222 | "./node_modules/react-router/lib/getRouteParams.js": 219,
223 | "./node_modules/react-router/lib/hashHistory.js": 220,
224 | "./node_modules/react-router/lib/index.js": 221,
225 | "./node_modules/react-router/lib/isActive.js": 222,
226 | "./node_modules/react-router/lib/match.js": 223,
227 | "./node_modules/react-router/lib/matchRoutes.js": 224,
228 | "./node_modules/react-router/lib/withRouter.js": 225,
229 | "./node_modules/react/lib/AutoFocusUtils.js": 226,
230 | "./node_modules/react/lib/BeforeInputEventPlugin.js": 227,
231 | "./node_modules/react/lib/CSSPropertyOperations.js": 228,
232 | "./node_modules/react/lib/ChangeEventPlugin.js": 229,
233 | "./node_modules/react/lib/Danger.js": 230,
234 | "./node_modules/react/lib/DefaultEventPluginOrder.js": 231,
235 | "./node_modules/react/lib/EnterLeaveEventPlugin.js": 232,
236 | "./node_modules/react/lib/FallbackCompositionState.js": 233,
237 | "./node_modules/react/lib/HTMLDOMPropertyConfig.js": 234,
238 | "./node_modules/react/lib/React.js": 235,
239 | "./node_modules/react/lib/ReactChildReconciler.js": 236,
240 | "./node_modules/react/lib/ReactChildrenMutationWarningHook.js": 237,
241 | "./node_modules/react/lib/ReactComponentBrowserEnvironment.js": 238,
242 | "./node_modules/react/lib/ReactCompositeComponent.js": 239,
243 | "./node_modules/react/lib/ReactDOM.js": 240,
244 | "./node_modules/react/lib/ReactDOMButton.js": 241,
245 | "./node_modules/react/lib/ReactDOMComponent.js": 242,
246 | "./node_modules/react/lib/ReactDOMContainerInfo.js": 243,
247 | "./node_modules/react/lib/ReactDOMEmptyComponent.js": 244,
248 | "./node_modules/react/lib/ReactDOMFactories.js": 245,
249 | "./node_modules/react/lib/ReactDOMFeatureFlags.js": 246,
250 | "./node_modules/react/lib/ReactDOMIDOperations.js": 247,
251 | "./node_modules/react/lib/ReactDOMInput.js": 248,
252 | "./node_modules/react/lib/ReactDOMNullInputValuePropHook.js": 249,
253 | "./node_modules/react/lib/ReactDOMOption.js": 250,
254 | "./node_modules/react/lib/ReactDOMSelection.js": 251,
255 | "./node_modules/react/lib/ReactDOMTextComponent.js": 252,
256 | "./node_modules/react/lib/ReactDOMTextarea.js": 253,
257 | "./node_modules/react/lib/ReactDOMTreeTraversal.js": 254,
258 | "./node_modules/react/lib/ReactDOMUnknownPropertyHook.js": 255,
259 | "./node_modules/react/lib/ReactDefaultBatchingStrategy.js": 256,
260 | "./node_modules/react/lib/ReactDefaultInjection.js": 257,
261 | "./node_modules/react/lib/ReactEventEmitterMixin.js": 258,
262 | "./node_modules/react/lib/ReactEventListener.js": 259,
263 | "./node_modules/react/lib/ReactHostOperationHistoryHook.js": 260,
264 | "./node_modules/react/lib/ReactInjection.js": 261,
265 | "./node_modules/react/lib/ReactInvalidSetStateWarningHook.js": 262,
266 | "./node_modules/react/lib/ReactMarkupChecksum.js": 263,
267 | "./node_modules/react/lib/ReactMultiChild.js": 264,
268 | "./node_modules/react/lib/ReactOwner.js": 265,
269 | "./node_modules/react/lib/ReactPerf.js": 266,
270 | "./node_modules/react/lib/ReactPureComponent.js": 267,
271 | "./node_modules/react/lib/ReactReconcileTransaction.js": 268,
272 | "./node_modules/react/lib/ReactRef.js": 269,
273 | "./node_modules/react/lib/ReactServerRenderingTransaction.js": 270,
274 | "./node_modules/react/lib/ReactServerUpdateQueue.js": 271,
275 | "./node_modules/react/lib/SVGDOMPropertyConfig.js": 272,
276 | "./node_modules/react/lib/SelectEventPlugin.js": 273,
277 | "./node_modules/react/lib/SimpleEventPlugin.js": 274,
278 | "./node_modules/react/lib/SyntheticAnimationEvent.js": 275,
279 | "./node_modules/react/lib/SyntheticClipboardEvent.js": 276,
280 | "./node_modules/react/lib/SyntheticCompositionEvent.js": 277,
281 | "./node_modules/react/lib/SyntheticDragEvent.js": 278,
282 | "./node_modules/react/lib/SyntheticFocusEvent.js": 279,
283 | "./node_modules/react/lib/SyntheticInputEvent.js": 280,
284 | "./node_modules/react/lib/SyntheticKeyboardEvent.js": 281,
285 | "./node_modules/react/lib/SyntheticTouchEvent.js": 282,
286 | "./node_modules/react/lib/SyntheticTransitionEvent.js": 283,
287 | "./node_modules/react/lib/SyntheticWheelEvent.js": 284,
288 | "./node_modules/react/lib/adler32.js": 285,
289 | "./node_modules/react/lib/dangerousStyleValue.js": 286,
290 | "./node_modules/react/lib/findDOMNode.js": 287,
291 | "./node_modules/react/lib/flattenChildren.js": 288,
292 | "./node_modules/react/lib/getEventKey.js": 289,
293 | "./node_modules/react/lib/getNodeForCharacterOffset.js": 290,
294 | "./node_modules/react/lib/getVendorPrefixedEventName.js": 291,
295 | "./node_modules/react/lib/onlyChild.js": 292,
296 | "./node_modules/react/lib/quoteAttributeValueForBrowser.js": 293,
297 | "./node_modules/react/lib/renderSubtreeIntoContainer.js": 294,
298 | "./node_modules/redux-immutablejs/lib/index.js": 295,
299 | "./node_modules/redux-immutablejs/lib/utils/combineReducers.js": 296,
300 | "./node_modules/redux-immutablejs/lib/utils/createReducer.js": 297,
301 | "./node_modules/redux-logger/lib/core.js": 298,
302 | "./node_modules/redux-logger/lib/defaults.js": 299,
303 | "./node_modules/redux-logger/lib/diff.js": 300,
304 | "./node_modules/redux-logger/lib/index.js": 301,
305 | "./node_modules/redux-thunk/lib/index.js": 302,
306 | "./node_modules/redux/lib/applyMiddleware.js": 303,
307 | "./node_modules/redux/lib/bindActionCreators.js": 304,
308 | "./node_modules/redux/lib/combineReducers.js": 305,
309 | "./node_modules/strict-uri-encode/index.js": 306,
310 | "./node_modules/symbol-observable/index.js": 307,
311 | "./node_modules/symbol-observable/lib/index.js": 308,
312 | "./node_modules/symbol-observable/lib/ponyfill.js": 309,
313 | "./node_modules/why-did-you-update/lib/deepDiff.js": 310,
314 | "./node_modules/why-did-you-update/lib/getDisplayName.js": 311,
315 | "./node_modules/why-did-you-update/lib/index.js": 312,
316 | "./node_modules/why-did-you-update/lib/normalizeOptions.js": 313,
317 | "./node_modules/why-did-you-update/lib/shouldInclude.js": 314,
318 | "./node_modules/why-did-you-update/node_modules/lodash/_DataView.js": 315,
319 | "./node_modules/why-did-you-update/node_modules/lodash/_Hash.js": 316,
320 | "./node_modules/why-did-you-update/node_modules/lodash/_Promise.js": 317,
321 | "./node_modules/why-did-you-update/node_modules/lodash/_Uint8Array.js": 318,
322 | "./node_modules/why-did-you-update/node_modules/lodash/_WeakMap.js": 319,
323 | "./node_modules/why-did-you-update/node_modules/lodash/_apply.js": 320,
324 | "./node_modules/why-did-you-update/node_modules/lodash/_arrayIncludes.js": 321,
325 | "./node_modules/why-did-you-update/node_modules/lodash/_arrayIncludesWith.js": 322,
326 | "./node_modules/why-did-you-update/node_modules/lodash/_arrayMap.js": 323,
327 | "./node_modules/why-did-you-update/node_modules/lodash/_arrayPush.js": 324,
328 | "./node_modules/why-did-you-update/node_modules/lodash/_baseEach.js": 325,
329 | "./node_modules/why-did-you-update/node_modules/lodash/_baseFlatten.js": 326,
330 | "./node_modules/why-did-you-update/node_modules/lodash/_baseFor.js": 327,
331 | "./node_modules/why-did-you-update/node_modules/lodash/_baseForOwn.js": 328,
332 | "./node_modules/why-did-you-update/node_modules/lodash/_baseHasIn.js": 329,
333 | "./node_modules/why-did-you-update/node_modules/lodash/_baseIndexOf.js": 330,
334 | "./node_modules/why-did-you-update/node_modules/lodash/_baseIsEqualDeep.js": 331,
335 | "./node_modules/why-did-you-update/node_modules/lodash/_baseIsMatch.js": 332,
336 | "./node_modules/why-did-you-update/node_modules/lodash/_baseIteratee.js": 333,
337 | "./node_modules/why-did-you-update/node_modules/lodash/_baseKeys.js": 334,
338 | "./node_modules/why-did-you-update/node_modules/lodash/_baseMatches.js": 335,
339 | "./node_modules/why-did-you-update/node_modules/lodash/_baseMatchesProperty.js": 336,
340 | "./node_modules/why-did-you-update/node_modules/lodash/_basePropertyDeep.js": 337,
341 | "./node_modules/why-did-you-update/node_modules/lodash/_baseSome.js": 338,
342 | "./node_modules/why-did-you-update/node_modules/lodash/_baseTimes.js": 339,
343 | "./node_modules/why-did-you-update/node_modules/lodash/_baseToPairs.js": 340,
344 | "./node_modules/why-did-you-update/node_modules/lodash/_baseToString.js": 341,
345 | "./node_modules/why-did-you-update/node_modules/lodash/_baseUniq.js": 342,
346 | "./node_modules/why-did-you-update/node_modules/lodash/_cacheHas.js": 343,
347 | "./node_modules/why-did-you-update/node_modules/lodash/_checkGlobal.js": 344,
348 | "./node_modules/why-did-you-update/node_modules/lodash/_createBaseEach.js": 345,
349 | "./node_modules/why-did-you-update/node_modules/lodash/_createBaseFor.js": 346,
350 | "./node_modules/why-did-you-update/node_modules/lodash/_createSet.js": 347,
351 | "./node_modules/why-did-you-update/node_modules/lodash/_createToPairs.js": 348,
352 | "./node_modules/why-did-you-update/node_modules/lodash/_equalByTag.js": 349,
353 | "./node_modules/why-did-you-update/node_modules/lodash/_equalObjects.js": 350,
354 | "./node_modules/why-did-you-update/node_modules/lodash/_getLength.js": 351,
355 | "./node_modules/why-did-you-update/node_modules/lodash/_getMatchData.js": 352,
356 | "./node_modules/why-did-you-update/node_modules/lodash/_getPrototype.js": 353,
357 | "./node_modules/why-did-you-update/node_modules/lodash/_hasPath.js": 354,
358 | "./node_modules/why-did-you-update/node_modules/lodash/_hashClear.js": 355,
359 | "./node_modules/why-did-you-update/node_modules/lodash/_hashDelete.js": 356,
360 | "./node_modules/why-did-you-update/node_modules/lodash/_hashGet.js": 357,
361 | "./node_modules/why-did-you-update/node_modules/lodash/_hashHas.js": 358,
362 | "./node_modules/why-did-you-update/node_modules/lodash/_hashSet.js": 359,
363 | "./node_modules/why-did-you-update/node_modules/lodash/_indexKeys.js": 360,
364 | "./node_modules/why-did-you-update/node_modules/lodash/_indexOfNaN.js": 361,
365 | "./node_modules/why-did-you-update/node_modules/lodash/_isFlattenable.js": 362,
366 | "./node_modules/why-did-you-update/node_modules/lodash/_isIterateeCall.js": 363,
367 | "./node_modules/why-did-you-update/node_modules/lodash/_isKeyable.js": 364,
368 | "./node_modules/why-did-you-update/node_modules/lodash/_isPrototype.js": 365,
369 | "./node_modules/why-did-you-update/node_modules/lodash/_listCacheClear.js": 366,
370 | "./node_modules/why-did-you-update/node_modules/lodash/_listCacheDelete.js": 367,
371 | "./node_modules/why-did-you-update/node_modules/lodash/_listCacheGet.js": 368,
372 | "./node_modules/why-did-you-update/node_modules/lodash/_listCacheHas.js": 369,
373 | "./node_modules/why-did-you-update/node_modules/lodash/_listCacheSet.js": 370,
374 | "./node_modules/why-did-you-update/node_modules/lodash/_mapCacheClear.js": 371,
375 | "./node_modules/why-did-you-update/node_modules/lodash/_mapCacheDelete.js": 372,
376 | "./node_modules/why-did-you-update/node_modules/lodash/_mapCacheGet.js": 373,
377 | "./node_modules/why-did-you-update/node_modules/lodash/_mapCacheHas.js": 374,
378 | "./node_modules/why-did-you-update/node_modules/lodash/_mapCacheSet.js": 375,
379 | "./node_modules/why-did-you-update/node_modules/lodash/_setCacheAdd.js": 376,
380 | "./node_modules/why-did-you-update/node_modules/lodash/_setCacheHas.js": 377,
381 | "./node_modules/why-did-you-update/node_modules/lodash/_setToPairs.js": 378,
382 | "./node_modules/why-did-you-update/node_modules/lodash/_stackClear.js": 379,
383 | "./node_modules/why-did-you-update/node_modules/lodash/_stackDelete.js": 380,
384 | "./node_modules/why-did-you-update/node_modules/lodash/_stackGet.js": 381,
385 | "./node_modules/why-did-you-update/node_modules/lodash/_stackHas.js": 382,
386 | "./node_modules/why-did-you-update/node_modules/lodash/_stackSet.js": 383,
387 | "./node_modules/why-did-you-update/node_modules/lodash/_stringToPath.js": 384,
388 | "./node_modules/why-did-you-update/node_modules/lodash/get.js": 385,
389 | "./node_modules/why-did-you-update/node_modules/lodash/hasIn.js": 386,
390 | "./node_modules/why-did-you-update/node_modules/lodash/identity.js": 387,
391 | "./node_modules/why-did-you-update/node_modules/lodash/isEqual.js": 388,
392 | "./node_modules/why-did-you-update/node_modules/lodash/isNative.js": 389,
393 | "./node_modules/why-did-you-update/node_modules/lodash/isTypedArray.js": 390,
394 | "./node_modules/why-did-you-update/node_modules/lodash/memoize.js": 391,
395 | "./node_modules/why-did-you-update/node_modules/lodash/noop.js": 392,
396 | "./node_modules/why-did-you-update/node_modules/lodash/property.js": 393,
397 | "./node_modules/why-did-you-update/node_modules/lodash/rest.js": 394,
398 | "./node_modules/why-did-you-update/node_modules/lodash/some.js": 395,
399 | "./node_modules/why-did-you-update/node_modules/lodash/toFinite.js": 396,
400 | "./node_modules/why-did-you-update/node_modules/lodash/toInteger.js": 397,
401 | "./node_modules/why-did-you-update/node_modules/lodash/toNumber.js": 398,
402 | "./node_modules/why-did-you-update/node_modules/lodash/toPairs.js": 399,
403 | "./node_modules/why-did-you-update/node_modules/lodash/toString.js": 400,
404 | "./node_modules/why-did-you-update/node_modules/lodash/union.js": 401
405 | }
406 | }
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "libs_lib",
3 | "content": {
4 | "./node_modules/fbjs/lib/invariant.js": 1,
5 | "./node_modules/react/lib/reactProdInvariant.js": 2,
6 | "./node_modules/fbjs/lib/warning.js": 3,
7 | "./node_modules/object-assign/index.js": 4,
8 | "./node_modules/react/lib/ReactDOMComponentTree.js": 5,
9 | "./node_modules/react/react.js": 6,
10 | "./node_modules/invariant/browser.js": 7,
11 | "./node_modules/fbjs/lib/ExecutionEnvironment.js": 8,
12 | "./node_modules/fbjs/lib/emptyFunction.js": 9,
13 | "./node_modules/react/lib/ReactInstrumentation.js": 10,
14 | "./node_modules/react/lib/ReactElement.js": 11,
15 | "./node_modules/react/lib/ReactUpdates.js": 12,
16 | "./node_modules/react/lib/EventConstants.js": 13,
17 | "./node_modules/react/lib/SyntheticEvent.js": 14,
18 | "./node_modules/fbjs/lib/keyOf.js": 15,
19 | "./node_modules/history/lib/PathUtils.js": 16,
20 | "./node_modules/react-router/lib/RouteUtils.js": 17,
21 | "./node_modules/react/lib/PooledClass.js": 18,
22 | "./node_modules/react/lib/ReactCurrentOwner.js": 19,
23 | "./node_modules/warning/browser.js": 20,
24 | "./node_modules/history/lib/LocationUtils.js": 21,
25 | "./node_modules/react-router/lib/PatternUtils.js": 22,
26 | "./node_modules/react-router/lib/routerWarning.js": 23,
27 | "./node_modules/react/lib/DOMLazyTree.js": 24,
28 | "./node_modules/react/lib/DOMProperty.js": 25,
29 | "./node_modules/react/lib/ReactReconciler.js": 26,
30 | "./node_modules/fbjs/lib/emptyObject.js": 27,
31 | "./node_modules/react-router/lib/InternalPropTypes.js": 28,
32 | "./node_modules/react/lib/EventPluginHub.js": 29,
33 | "./node_modules/react/lib/EventPropagators.js": 30,
34 | "./node_modules/react/lib/ReactInstanceMap.js": 31,
35 | "./node_modules/react/lib/SyntheticUIEvent.js": 32,
36 | "./node_modules/react/lib/Transaction.js": 33,
37 | "./node_modules/fbjs/lib/keyMirror.js": 34,
38 | "./node_modules/history/lib/Actions.js": 35,
39 | "./node_modules/history/lib/DOMUtils.js": 36,
40 | "./node_modules/immutable/dist/immutable.js": 37,
41 | "./node_modules/react/lib/DisabledInputUtils.js": 38,
42 | "./node_modules/react/lib/ReactBrowserEventEmitter.js": 39,
43 | "./node_modules/react/lib/SyntheticMouseEvent.js": 40,
44 | "./node_modules/react/lib/escapeTextContentForBrowser.js": 41,
45 | "./node_modules/react/lib/setInnerHTML.js": 42,
46 | "./node_modules/fbjs/lib/shallowEqual.js": 43,
47 | "./node_modules/history/lib/BrowserProtocol.js": 44,
48 | "./node_modules/history/lib/ExecutionEnvironment.js": 45,
49 | "./node_modules/history/lib/createHistory.js": 46,
50 | "./node_modules/history/lib/runTransitionHook.js": 47,
51 | "./node_modules/lodash/isPlainObject.js": 48,
52 | "./node_modules/node-libs-browser/node_modules/process/browser.js": 49,
53 | "./node_modules/react-router/lib/AsyncUtils.js": 50,
54 | "./node_modules/react-router/lib/ContextUtils.js": 51,
55 | "./node_modules/react-router/lib/PropTypes.js": 52,
56 | "./node_modules/react-router/lib/RouterContext.js": 53,
57 | "./node_modules/react/lib/DOMChildrenOperations.js": 54,
58 | "./node_modules/react/lib/DOMNamespaces.js": 55,
59 | "./node_modules/react/lib/EventPluginRegistry.js": 56,
60 | "./node_modules/react/lib/EventPluginUtils.js": 57,
61 | "./node_modules/react/lib/KeyEscapeUtils.js": 58,
62 | "./node_modules/react/lib/LinkedValueUtils.js": 59,
63 | "./node_modules/react/lib/ReactComponent.js": 60,
64 | "./node_modules/react/lib/ReactComponentEnvironment.js": 61,
65 | "./node_modules/react/lib/ReactComponentTreeHook.js": 62,
66 | "./node_modules/react/lib/ReactErrorUtils.js": 63,
67 | "./node_modules/react/lib/ReactNoopUpdateQueue.js": 64,
68 | "./node_modules/react/lib/ReactPropTypeLocationNames.js": 65,
69 | "./node_modules/react/lib/ReactPropTypeLocations.js": 66,
70 | "./node_modules/react/lib/ReactPropTypesSecret.js": 67,
71 | "./node_modules/react/lib/ReactUpdateQueue.js": 68,
72 | "./node_modules/react/lib/createMicrosoftUnsafeLocalFunction.js": 69,
73 | "./node_modules/react/lib/getEventCharCode.js": 70,
74 | "./node_modules/react/lib/getEventModifierState.js": 71,
75 | "./node_modules/react/lib/getEventTarget.js": 72,
76 | "./node_modules/react/lib/isEventSupported.js": 73,
77 | "./node_modules/react/lib/shouldUpdateReactComponent.js": 74,
78 | "./node_modules/react/lib/traverseAllChildren.js": 75,
79 | "./node_modules/react/lib/validateDOMNesting.js": 76,
80 | "./node_modules/fbjs/lib/EventListener.js": 77,
81 | "./node_modules/fbjs/lib/focusNode.js": 78,
82 | "./node_modules/fbjs/lib/getActiveElement.js": 79,
83 | "./node_modules/history/lib/DOMStateStorage.js": 80,
84 | "./node_modules/history/lib/useBasename.js": 81,
85 | "./node_modules/history/lib/useQueries.js": 82,
86 | "./node_modules/hoist-non-react-statics/index.js": 83,
87 | "./node_modules/react-redux/lib/utils/storeShape.js": 84,
88 | "./node_modules/react-redux/lib/utils/warning.js": 85,
89 | "./node_modules/react-router-redux/lib/actions.js": 86,
90 | "./node_modules/react-router-redux/lib/reducer.js": 87,
91 | "./node_modules/react-router/lib/Link.js": 88,
92 | "./node_modules/react-router/lib/PromiseUtils.js": 89,
93 | "./node_modules/react-router/lib/Redirect.js": 90,
94 | "./node_modules/react-router/lib/RouterUtils.js": 91,
95 | "./node_modules/react-router/lib/createMemoryHistory.js": 92,
96 | "./node_modules/react-router/lib/createRouterHistory.js": 93,
97 | "./node_modules/react-router/lib/createTransitionManager.js": 94,
98 | "./node_modules/react-router/lib/useRouterHistory.js": 95,
99 | "./node_modules/react/lib/CSSProperty.js": 96,
100 | "./node_modules/react/lib/CallbackQueue.js": 97,
101 | "./node_modules/react/lib/DOMPropertyOperations.js": 98,
102 | "./node_modules/react/lib/ReactChildren.js": 99,
103 | "./node_modules/react/lib/ReactClass.js": 100,
104 | "./node_modules/react/lib/ReactDOMComponentFlags.js": 101,
105 | "./node_modules/react/lib/ReactDOMSelect.js": 102,
106 | "./node_modules/react/lib/ReactEmptyComponent.js": 103,
107 | "./node_modules/react/lib/ReactFeatureFlags.js": 104,
108 | "./node_modules/react/lib/ReactHostComponent.js": 105,
109 | "./node_modules/react/lib/ReactInputSelection.js": 106,
110 | "./node_modules/react/lib/ReactMount.js": 107,
111 | "./node_modules/react/lib/ReactMultiChildUpdateTypes.js": 108,
112 | "./node_modules/react/lib/ReactNodeTypes.js": 109,
113 | "./node_modules/react/lib/ReactPropTypes.js": 110,
114 | "./node_modules/react/lib/ReactVersion.js": 111,
115 | "./node_modules/react/lib/ViewportMetrics.js": 112,
116 | "./node_modules/react/lib/accumulateInto.js": 113,
117 | "./node_modules/react/lib/canDefineProperty.js": 114,
118 | "./node_modules/react/lib/forEachAccumulated.js": 115,
119 | "./node_modules/react/lib/getHostComponentFromComposite.js": 116,
120 | "./node_modules/react/lib/getIteratorFn.js": 117,
121 | "./node_modules/react/lib/getTextContentAccessor.js": 118,
122 | "./node_modules/react/lib/instantiateReactComponent.js": 119,
123 | "./node_modules/react/lib/isTextInputElement.js": 120,
124 | "./node_modules/react/lib/setTextContent.js": 121,
125 | "./node_modules/redux/lib/compose.js": 122,
126 | "./node_modules/redux/lib/createStore.js": 123,
127 | "./node_modules/redux/lib/index.js": 124,
128 | "./node_modules/redux/lib/utils/warning.js": 125,
129 | "./node_modules/fastclick/lib/fastclick.js": 126,
130 | "./node_modules/fbjs/lib/camelize.js": 127,
131 | "./node_modules/fbjs/lib/camelizeStyleName.js": 128,
132 | "./node_modules/fbjs/lib/containsNode.js": 129,
133 | "./node_modules/fbjs/lib/createArrayFromMixed.js": 130,
134 | "./node_modules/fbjs/lib/createNodesFromMarkup.js": 131,
135 | "./node_modules/fbjs/lib/getMarkupWrap.js": 132,
136 | "./node_modules/fbjs/lib/getUnboundedScrollPosition.js": 133,
137 | "./node_modules/fbjs/lib/hyphenate.js": 134,
138 | "./node_modules/fbjs/lib/hyphenateStyleName.js": 135,
139 | "./node_modules/fbjs/lib/isNode.js": 136,
140 | "./node_modules/fbjs/lib/isTextNode.js": 137,
141 | "./node_modules/fbjs/lib/memoizeStringOnly.js": 138,
142 | "./node_modules/history/lib/AsyncUtils.js": 139,
143 | "./node_modules/history/lib/HashProtocol.js": 140,
144 | "./node_modules/history/lib/RefreshProtocol.js": 141,
145 | "./node_modules/history/lib/createBrowserHistory.js": 142,
146 | "./node_modules/history/lib/createHashHistory.js": 143,
147 | "./node_modules/history/lib/createMemoryHistory.js": 144,
148 | "./node_modules/lodash/_getPrototype.js": 145,
149 | "./node_modules/lodash/_isHostObject.js": 146,
150 | "./node_modules/lodash/isObjectLike.js": 147,
151 | "./node_modules/query-string/index.js": 148,
152 | "./node_modules/react-dom/index.js": 149,
153 | "./node_modules/react-immutable-proptypes/dist/ImmutablePropTypes.js": 150,
154 | "./node_modules/react-redux/lib/components/Provider.js": 151,
155 | "./node_modules/react-redux/lib/components/connect.js": 152,
156 | "./node_modules/react-redux/lib/index.js": 153,
157 | "./node_modules/react-redux/lib/utils/shallowEqual.js": 154,
158 | "./node_modules/react-redux/lib/utils/wrapActionCreators.js": 155,
159 | "./node_modules/react-router-redux/lib/index.js": 156,
160 | "./node_modules/react-router-redux/lib/middleware.js": 157,
161 | "./node_modules/react-router-redux/lib/sync.js": 158,
162 | "./node_modules/react-router/lib/IndexLink.js": 159,
163 | "./node_modules/react-router/lib/IndexRedirect.js": 160,
164 | "./node_modules/react-router/lib/IndexRoute.js": 161,
165 | "./node_modules/react-router/lib/Route.js": 162,
166 | "./node_modules/react-router/lib/Router.js": 163,
167 | "./node_modules/react-router/lib/TransitionUtils.js": 164,
168 | "./node_modules/react-router/lib/applyRouterMiddleware.js": 165,
169 | "./node_modules/react-router/lib/browserHistory.js": 166,
170 | "./node_modules/react-router/lib/computeChangedRoutes.js": 167,
171 | "./node_modules/react-router/lib/getComponents.js": 168,
172 | "./node_modules/react-router/lib/getRouteParams.js": 169,
173 | "./node_modules/react-router/lib/hashHistory.js": 170,
174 | "./node_modules/react-router/lib/index.js": 171,
175 | "./node_modules/react-router/lib/isActive.js": 172,
176 | "./node_modules/react-router/lib/match.js": 173,
177 | "./node_modules/react-router/lib/matchRoutes.js": 174,
178 | "./node_modules/react-router/lib/withRouter.js": 175,
179 | "./node_modules/react/lib/AutoFocusUtils.js": 176,
180 | "./node_modules/react/lib/BeforeInputEventPlugin.js": 177,
181 | "./node_modules/react/lib/CSSPropertyOperations.js": 178,
182 | "./node_modules/react/lib/ChangeEventPlugin.js": 179,
183 | "./node_modules/react/lib/Danger.js": 180,
184 | "./node_modules/react/lib/DefaultEventPluginOrder.js": 181,
185 | "./node_modules/react/lib/EnterLeaveEventPlugin.js": 182,
186 | "./node_modules/react/lib/FallbackCompositionState.js": 183,
187 | "./node_modules/react/lib/HTMLDOMPropertyConfig.js": 184,
188 | "./node_modules/react/lib/React.js": 185,
189 | "./node_modules/react/lib/ReactChildReconciler.js": 186,
190 | "./node_modules/react/lib/ReactComponentBrowserEnvironment.js": 187,
191 | "./node_modules/react/lib/ReactCompositeComponent.js": 188,
192 | "./node_modules/react/lib/ReactDOM.js": 189,
193 | "./node_modules/react/lib/ReactDOMButton.js": 190,
194 | "./node_modules/react/lib/ReactDOMComponent.js": 191,
195 | "./node_modules/react/lib/ReactDOMContainerInfo.js": 192,
196 | "./node_modules/react/lib/ReactDOMEmptyComponent.js": 193,
197 | "./node_modules/react/lib/ReactDOMFactories.js": 194,
198 | "./node_modules/react/lib/ReactDOMFeatureFlags.js": 195,
199 | "./node_modules/react/lib/ReactDOMIDOperations.js": 196,
200 | "./node_modules/react/lib/ReactDOMInput.js": 197,
201 | "./node_modules/react/lib/ReactDOMOption.js": 198,
202 | "./node_modules/react/lib/ReactDOMSelection.js": 199,
203 | "./node_modules/react/lib/ReactDOMTextComponent.js": 200,
204 | "./node_modules/react/lib/ReactDOMTextarea.js": 201,
205 | "./node_modules/react/lib/ReactDOMTreeTraversal.js": 202,
206 | "./node_modules/react/lib/ReactDefaultBatchingStrategy.js": 203,
207 | "./node_modules/react/lib/ReactDefaultInjection.js": 204,
208 | "./node_modules/react/lib/ReactEventEmitterMixin.js": 205,
209 | "./node_modules/react/lib/ReactEventListener.js": 206,
210 | "./node_modules/react/lib/ReactInjection.js": 207,
211 | "./node_modules/react/lib/ReactMarkupChecksum.js": 208,
212 | "./node_modules/react/lib/ReactMultiChild.js": 209,
213 | "./node_modules/react/lib/ReactOwner.js": 210,
214 | "./node_modules/react/lib/ReactPureComponent.js": 211,
215 | "./node_modules/react/lib/ReactReconcileTransaction.js": 212,
216 | "./node_modules/react/lib/ReactRef.js": 213,
217 | "./node_modules/react/lib/ReactServerRenderingTransaction.js": 214,
218 | "./node_modules/react/lib/ReactServerUpdateQueue.js": 215,
219 | "./node_modules/react/lib/SVGDOMPropertyConfig.js": 216,
220 | "./node_modules/react/lib/SelectEventPlugin.js": 217,
221 | "./node_modules/react/lib/SimpleEventPlugin.js": 218,
222 | "./node_modules/react/lib/SyntheticAnimationEvent.js": 219,
223 | "./node_modules/react/lib/SyntheticClipboardEvent.js": 220,
224 | "./node_modules/react/lib/SyntheticCompositionEvent.js": 221,
225 | "./node_modules/react/lib/SyntheticDragEvent.js": 222,
226 | "./node_modules/react/lib/SyntheticFocusEvent.js": 223,
227 | "./node_modules/react/lib/SyntheticInputEvent.js": 224,
228 | "./node_modules/react/lib/SyntheticKeyboardEvent.js": 225,
229 | "./node_modules/react/lib/SyntheticTouchEvent.js": 226,
230 | "./node_modules/react/lib/SyntheticTransitionEvent.js": 227,
231 | "./node_modules/react/lib/SyntheticWheelEvent.js": 228,
232 | "./node_modules/react/lib/adler32.js": 229,
233 | "./node_modules/react/lib/checkReactTypeSpec.js": 230,
234 | "./node_modules/react/lib/dangerousStyleValue.js": 231,
235 | "./node_modules/react/lib/findDOMNode.js": 232,
236 | "./node_modules/react/lib/flattenChildren.js": 233,
237 | "./node_modules/react/lib/getEventKey.js": 234,
238 | "./node_modules/react/lib/getNodeForCharacterOffset.js": 235,
239 | "./node_modules/react/lib/getVendorPrefixedEventName.js": 236,
240 | "./node_modules/react/lib/onlyChild.js": 237,
241 | "./node_modules/react/lib/quoteAttributeValueForBrowser.js": 238,
242 | "./node_modules/react/lib/renderSubtreeIntoContainer.js": 239,
243 | "./node_modules/redux-immutablejs/lib/index.js": 240,
244 | "./node_modules/redux-immutablejs/lib/utils/combineReducers.js": 241,
245 | "./node_modules/redux-immutablejs/lib/utils/createReducer.js": 242,
246 | "./node_modules/redux-thunk/lib/index.js": 243,
247 | "./node_modules/redux/lib/applyMiddleware.js": 244,
248 | "./node_modules/redux/lib/bindActionCreators.js": 245,
249 | "./node_modules/redux/lib/combineReducers.js": 246,
250 | "./node_modules/strict-uri-encode/index.js": 247,
251 | "./node_modules/symbol-observable/index.js": 248,
252 | "./node_modules/symbol-observable/lib/index.js": 249,
253 | "./node_modules/symbol-observable/lib/ponyfill.js": 250,
254 | "./node_modules/webpack/buildin/module.js": 251
255 | }
256 | }
--------------------------------------------------------------------------------
/nodemon.json:
--------------------------------------------------------------------------------
1 | {
2 | "restartable": "rs",
3 | "ignore": [
4 | ".git",
5 | "node_modules/**/node_modules"
6 | ],
7 | "verbose": true,
8 | "watch": [
9 | "server",
10 | "common"
11 | ],
12 | "env": {
13 | "NODE_ENV": "development"
14 | },
15 | "ext": "js json jsx"
16 | }
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-ocean",
3 | "license": "ISC",
4 | "version": "0.13.1",
5 | "author": "LukeLin",
6 | "keywords": [
7 | "react",
8 | "redux",
9 | "webpack",
10 | "babel",
11 | "immutable",
12 | "isomophic react",
13 | "universal react"
14 | ],
15 | "main": "./dist/server.js",
16 | "babel": {
17 | "presets": [
18 | "react"
19 | ],
20 | "plugins": [
21 | "transform-es2015-modules-commonjs",
22 | "transform-async-to-generator",
23 | "transform-decorators-legacy",
24 | "transform-class-properties"
25 | ]
26 | },
27 | "dependencies": {
28 | "body-parser": "1.15.2",
29 | "classnames": "2.2.5",
30 | "compression": "1.6.2",
31 | "cookie-parser": "1.4.3",
32 | "csurf": "1.9.0",
33 | "ejs": "2.5.2",
34 | "express": "4.14.0",
35 | "express-session": "1.14.1",
36 | "fastclick": "1.0.6",
37 | "helmet": "2.3.0",
38 | "immutable": "3.8.1",
39 | "isomorphic-fetch": "2.2.1",
40 | "morgan": "1.7.0",
41 | "pm2": "2.0.18",
42 | "react": "15.3.2",
43 | "react-dom": "15.3.2",
44 | "react-immutable-proptypes": "2.1.0",
45 | "react-redux": "4.4.5",
46 | "react-router": "^3.0.0",
47 | "redux": "3.6.0",
48 | "redux-immutablejs": "0.0.8",
49 | "redux-thunk": "2.1.0",
50 | "secure-filters": "^1.0.5",
51 | "socket.io": "1.5.0",
52 | "source-map-support": "^0.4.5"
53 | },
54 | "description": "isomophic-react-redux-starter",
55 | "devDependencies": {
56 | "babel-core": "^6.18.0",
57 | "babel-loader": "^6.2.5",
58 | "babel-plugin-syntax-async-functions": "^6.13.0",
59 | "babel-plugin-transform-async-to-generator": "^6.16.0",
60 | "babel-plugin-transform-class-properties": "^6.19.0",
61 | "babel-plugin-transform-decorators-legacy": "^1.3.4",
62 | "babel-plugin-transform-es2015-modules-commonjs": "^6.18.0",
63 | "babel-plugin-transform-react-constant-elements": "^6.9.1",
64 | "babel-plugin-transform-react-inline-elements": "^6.8.0",
65 | "babel-plugin-transform-react-remove-prop-types": "^0.2.10",
66 | "babel-plugin-transform-regenerator": "^6.16.1",
67 | "babel-plugin-transform-runtime": "^6.15.0",
68 | "babel-preset-es2015": "^6.18.0",
69 | "babel-preset-react": "^6.16.0",
70 | "babel-preset-react-hmre": "^1.1.1",
71 | "babel-runtime": "^6.18.0",
72 | "browser-sync": "^2.17.5",
73 | "css-loader": "^0.23.1",
74 | "del": "^2.2.2",
75 | "extract-text-webpack-plugin": "^1.0.1",
76 | "file-loader": "^0.8.5",
77 | "gulp": ">=3.9.0",
78 | "happypack": "^2.2.1",
79 | "json-loader": "^0.5.4",
80 | "nodemon": "^1.11.0",
81 | "progress-bar-webpack-plugin": "^1.9.0",
82 | "react-addons-perf": "^15.3.2",
83 | "redux-logger": "^2.7.0",
84 | "style-loader": "^0.13.1",
85 | "url-loader": "^0.5.7",
86 | "webpack": "^1.13.2",
87 | "webpack-dev-middleware": "^1.8.4",
88 | "webpack-hot-middleware": "^2.13.0",
89 | "why-did-you-update": "0.0.8"
90 | },
91 | "scripts": {
92 | "start": "node starter.js",
93 | "kill": "pm2 delete react-ocean",
94 | "build:lib": "gulp build:lib:dev && gulp build:lib",
95 | "build:dev": "set NODE_ENV=development && gulp build:dev",
96 | "build": "npm run build:prod && npm run build:dev",
97 | "build:prod": "set NODE_ENV=production && gulp build",
98 | "build:server": "webpack --progress --config ./webpack.config-server.js",
99 | "local": "npm run build:server && nodemon index.js",
100 | "debug": "npm run build:server && node-debug index.js",
101 | "watch": "gulp watch"
102 | },
103 | "engines": {
104 | "node": ">=6.0.0"
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/public/css/main-min.css:
--------------------------------------------------------------------------------
1 | body{font-size:16px}
--------------------------------------------------------------------------------
/public/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-size: 16px;
3 | }
4 | /*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiIuL2Nzcy9tYWluLmNzcyIsInNvdXJjZVJvb3QiOiIifQ==*/
--------------------------------------------------------------------------------
/public/css/main.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"./css/main.css","sources":[],"mappings":";;","sourceRoot":""}
--------------------------------------------------------------------------------
/public/js/debug/Vote.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([0],{
2 |
3 | /***/ 109:
4 | /*!***********************************!*\
5 | !*** ./common/pages/App/Vote.jsx ***!
6 | \***********************************/
7 | /***/ function(module, exports, __webpack_require__) {
8 |
9 | 'use strict';
10 |
11 | exports.__esModule = true;
12 |
13 | var _classCallCheck2 = __webpack_require__(/*! babel-runtime/helpers/classCallCheck */ 11);
14 |
15 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
16 |
17 | var _possibleConstructorReturn2 = __webpack_require__(/*! babel-runtime/helpers/possibleConstructorReturn */ 13);
18 |
19 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
20 |
21 | var _inherits2 = __webpack_require__(/*! babel-runtime/helpers/inherits */ 12);
22 |
23 | var _inherits3 = _interopRequireDefault(_inherits2);
24 |
25 | var _dec, _dec2, _class, _class2, _temp;
26 |
27 | var _react = __webpack_require__(/*! react */ 3);
28 |
29 | var _react2 = _interopRequireDefault(_react);
30 |
31 | var _reactRedux = __webpack_require__(/*! react-redux */ 41);
32 |
33 | var _reactRouter = __webpack_require__(/*! react-router */ 99);
34 |
35 | var _connectDataFetchers = __webpack_require__(/*! ../../utils/connectDataFetchers */ 110);
36 |
37 | var _connectDataFetchers2 = _interopRequireDefault(_connectDataFetchers);
38 |
39 | var _vote = __webpack_require__(/*! ../../actions/vote */ 108);
40 |
41 | var ACTIONS = _interopRequireWildcard(_vote);
42 |
43 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
44 |
45 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
46 |
47 | var Vote = (_dec = (0, _reactRedux.connect)(function mapStateToProps(state) {
48 | return {
49 | message: state.vote.message
50 | };
51 | }), _dec2 = (0, _connectDataFetchers2.default)([ACTIONS.loadData]), _dec(_class = _dec2(_class = (_temp = _class2 = function (_Component) {
52 | (0, _inherits3.default)(Vote, _Component);
53 |
54 | function Vote() {
55 | (0, _classCallCheck3.default)(this, Vote);
56 | return (0, _possibleConstructorReturn3.default)(this, _Component.apply(this, arguments));
57 | }
58 |
59 | Vote.prototype.render = function render() {
60 | return _react2.default.createElement(
61 | 'div',
62 | { className: 'vote' },
63 | 'this is vote',
64 | _react2.default.createElement(
65 | _reactRouter.Link,
66 | { to: '/about?debug=test' },
67 | 'about'
68 | ),
69 | _react2.default.createElement(
70 | _reactRouter.Link,
71 | { to: '/test' },
72 | 'test'
73 | ),
74 | 'message: ',
75 | this.props.message
76 | );
77 | };
78 |
79 | return Vote;
80 | }(_react.Component), _class2.pageConfig = {
81 | pageId: 'Vote'
82 | }, _temp)) || _class) || _class);
83 | exports.default = Vote;
84 |
85 | /***/ }
86 |
87 | });
88 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9EOi93b3Jrc3BhY2UvamF2YXNjcmlwdC9pc29tb3JwaGljLXJlYWN0LXJlZHV4LXN0YXJ0ZXIvY29tbW9uL3BhZ2VzL0FwcC9Wb3RlLmpzeCJdLCJuYW1lcyI6WyJBQ1RJT05TIiwiVm90ZSIsIm1hcFN0YXRlVG9Qcm9wcyIsInN0YXRlIiwibWVzc2FnZSIsInZvdGUiLCJsb2FkRGF0YSIsInJlbmRlciIsInByb3BzIiwicGFnZUNvbmZpZyIsInBhZ2VJZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7OztBQUNBOztBQUNBOztBQUVBOzs7O0FBQ0E7O0tBQVlBLE87Ozs7OztLQVFOQyxJLFdBTkwseUJBQVEsU0FBU0MsZUFBVCxDQUF5QkMsS0FBekIsRUFBZ0M7QUFDckMsWUFBTztBQUNIQyxrQkFBU0QsTUFBTUUsSUFBTixDQUFXRDtBQURqQixNQUFQO0FBR0gsRUFKQSxDLFVBS0EsbUNBQW9CLENBQUNKLFFBQVFNLFFBQVQsQ0FBcEIsQzs7Ozs7Ozs7b0JBS0dDLE0scUJBQVM7QUFDTCxnQkFDSTtBQUFBO0FBQUEsZUFBSyxXQUFVLE1BQWY7QUFBQTtBQUVJO0FBQUE7QUFBQSxtQkFBTSxJQUFHLG1CQUFUO0FBQUE7QUFBQSxjQUZKO0FBR0k7QUFBQTtBQUFBLG1CQUFNLElBQUcsT0FBVDtBQUFBO0FBQUEsY0FISjtBQUFBO0FBSWUsa0JBQUtDLEtBQUwsQ0FBV0o7QUFKMUIsVUFESjtBQVFILE07Ozs4QkFaTUssVSxHQUFhO0FBQ2hCQyxhQUFRO0FBRFEsRTttQkFlVFQsSSIsImZpbGUiOiIvanMvZGVidWcvVm90ZS5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBSZWFjdCwgeyBDb21wb25lbnQsIFByb3BUeXBlcyB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBMaW5rIH0gZnJvbSAncmVhY3Qtcm91dGVyJztcblxuaW1wb3J0IGNvbm5lY3REYXRhRmV0Y2hlcnMgZnJvbSAnLi4vLi4vdXRpbHMvY29ubmVjdERhdGFGZXRjaGVycyc7XG5pbXBvcnQgKiBhcyBBQ1RJT05TIGZyb20gJy4uLy4uL2FjdGlvbnMvdm90ZSc7XG5cbkBjb25uZWN0KGZ1bmN0aW9uIG1hcFN0YXRlVG9Qcm9wcyhzdGF0ZSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIG1lc3NhZ2U6IHN0YXRlLnZvdGUubWVzc2FnZVxuICAgIH07XG59KVxuQGNvbm5lY3REYXRhRmV0Y2hlcnMoW0FDVElPTlMubG9hZERhdGFdKVxuY2xhc3MgVm90ZSBleHRlbmRzIENvbXBvbmVudCB7XG4gICAgc3RhdGljIHBhZ2VDb25maWcgPSB7XG4gICAgICAgIHBhZ2VJZDogJ1ZvdGUnXG4gICAgfTtcbiAgICByZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cInZvdGVcIj5cbiAgICAgICAgICAgICAgICB0aGlzIGlzIHZvdGVcbiAgICAgICAgICAgICAgICA8TGluayB0bz1cIi9hYm91dD9kZWJ1Zz10ZXN0XCI+YWJvdXQ8L0xpbms+XG4gICAgICAgICAgICAgICAgPExpbmsgdG89XCIvdGVzdFwiPnRlc3Q8L0xpbms+XG4gICAgICAgICAgICAgICAgbWVzc2FnZTogeyB0aGlzLnByb3BzLm1lc3NhZ2UgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBWb3RlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vRDovd29ya3NwYWNlL2phdmFzY3JpcHQvaXNvbW9ycGhpYy1yZWFjdC1yZWR1eC1zdGFydGVyL2NvbW1vbi9wYWdlcy9BcHAvVm90ZS5qc3giXSwic291cmNlUm9vdCI6IiJ9
--------------------------------------------------------------------------------
/public/js/min/Vote-85c4768b46fe43df6032.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([0],{103:function(e,t,n){"use strict";function a(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}function u(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var o,r,s,l,f,i=n(11),d=u(i),c=n(13),p=u(c),m=n(12),g=u(m),v=n(2),h=u(v),_=n(40),b=n(96),y=n(104),k=u(y),E=n(102),M=a(E),w=(o=(0,_.connect)(function(e){return{message:e.vote.message}}),r=(0,k.default)([M.loadData]),o(s=r((f=l=function(e){function t(){return(0,d.default)(this,t),(0,p.default)(this,e.apply(this,arguments))}return(0,g.default)(t,e),t.prototype.render=function(){return h.default.createElement("div",{className:"vote"},"this is vote",h.default.createElement(b.Link,{to:"/about?debug=test"},"about"),h.default.createElement(b.Link,{to:"/test"},"test"),"message: ",this.props.message)},t}(v.Component),l.pageConfig={pageId:"Vote"},s=f))||s)||s);t.default=w}});
--------------------------------------------------------------------------------
/public/js/min/app-5f3b653ecdc8e6fe9b59.js:
--------------------------------------------------------------------------------
1 | !function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var n=window.webpackJsonp;window.webpackJsonp=function(r,i){for(var u,s,f=0,c=[];f=e.length)break;i=e[r++]}else{if(r=e.next(),r.done)break;i=r.value}var u=i;this[u].funcBinded||(this[u]=this[u].bind(this),this[u].funcBinded=!0)}},e.prototype.on=function(t,e){if("function"!=typeof e)throw new Error("fn should be a function");return this.__eventNames[t]?this.__eventNames[t].push(e):this.__eventNames[t]=[e],this.context.$eventBus.addListener(t,e)},e.prototype.emit=function(t){for(var e,n=arguments.length,r=Array(n>1?n-1:0),o=1;o=0?(this.context.$eventBus.removeListener(t,e),n.splice(r,1),n.length||delete this.__eventNames[t]):console.warn("event: "+t+" is not registered in "+this._reactInternalInstance.getName()+" Component"),!0}return console.warn("event: "+t+" is not registered in "+this.constructor.name+" Component"),!1},e.prototype.shouldComponentUpdate=function(t,e){var n=!(0,d.default)(this.props,t)||!(0,d.default)(this.state,e);return n},e.prototype.componentWillUnmount=function(){for(var t in this.__eventNames)if(this.__eventNames.hasOwnProperty(t))for(var e=this.__eventNames[t],n=Array.isArray(e),r=0,e=n?e:e[Symbol.iterator]();;){var o;if(n){if(r>=e.length)break;o=e[r++]}else{if(r=e.next(),r.done)break;o=r.value}var i=o;this.off(t,i)}},e}(l.Component);e.default=_,_.contextTypes={$eventBus:l.PropTypes.instanceOf(v.default)}},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0;var o=n(61),i=r(o),u=n(60),s=r(u),f="function"==typeof s.default&&"symbol"==typeof i.default?function(t){return typeof t}:function(t){return t&&"function"==typeof s.default&&t.constructor===s.default&&t!==s.default.prototype?"symbol":typeof t};e.default="function"==typeof s.default&&"symbol"===f(i.default)?function(t){return"undefined"==typeof t?"undefined":f(t)}:function(t){return t&&"function"==typeof s.default&&t.constructor===s.default&&t!==s.default.prototype?"symbol":"undefined"==typeof t?"undefined":f(t)}},function(t,e){t.exports=!0},function(t,e){e.f={}.propertyIsEnumerable},function(t,e,n){var r=n(10).f,o=n(5),i=n(4)("toStringTag");t.exports=function(t,e,n){t&&!o(t=n?t:t.prototype,i)&&r(t,i,{configurable:!0,value:e})}},function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e,n){var r=n(14),o=n(74),i=n(28),u=n(30)("IE_PROTO"),s=function(){},f="prototype",c=function(){var t,e=n(38)("iframe"),r=i.length,o="<",u=">";for(e.style.display="none",n(51).appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(o+"script"+u+"document.F=Object"+o+"/script"+u),t.close(),c=t.F;r--;)delete c[f][i[r]];return c()};t.exports=Object.create||function(t,e){var n;return null!==t?(s[f]=r(t),n=new s,s[f]=null,n[u]=t):n=c(),void 0===e?n:o(n,e)}},function(t,e,n){var r=n(31)("keys"),o=n(20);t.exports=function(t){return r[t]||(r[t]=o(t))}},function(t,e,n){var r=n(1),o="__core-js_shared__",i=r[o]||(r[o]={});t.exports=function(t){return i[t]||(i[t]={})}},function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},function(t,e,n){var r=n(15);t.exports=function(t,e){if(!r(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!r(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},function(t,e,n){var r=n(1),o=n(7),i=n(24),u=n(35),s=n(10).f;t.exports=function(t){var e=o.Symbol||(o.Symbol=i?{}:r.Symbol||{});"_"==t.charAt(0)||t in e||s(e,t,{value:u.f(t)})}},function(t,e,n){e.f=n(4)},function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e,n){var r=n(49);t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,o){return t.call(e,n,r,o)}}return function(){return t.apply(e,arguments)}}},function(t,e,n){var r=n(15),o=n(1).document,i=r(o)&&r(o.createElement);t.exports=function(t){return i?o.createElement(t):{}}},function(t,e){e.f=Object.getOwnPropertySymbols},function(t,e,n){t.exports=n(3)(153)},function(t,e,n){t.exports=!n(8)&&!n(17)(function(){return 7!=Object.defineProperty(n(38)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){"use strict";var r=n(24),o=n(16),i=n(46),u=n(9),s=n(5),f=n(21),c=n(70),a=n(26),l=n(76),p=n(4)("iterator"),d=!([].keys&&"next"in[].keys()),h="@@iterator",v="keys",y="values",_=function(){return this};t.exports=function(t,e,n,m,g,b,x){c(n,e,m);var O,w,E,S=function(t){if(!d&&t in M)return M[t];switch(t){case v:return function(){return new n(this,t)};case y:return function(){return new n(this,t)}}return function(){return new n(this,t)}},j=e+" Iterator",C=g==y,P=!1,M=t.prototype,T=M[p]||M[h]||g&&M[g],L=T||S(g),A=g?C?S("entries"):L:void 0,k="Array"==e?M.entries||T:T;if(k&&(E=l(k.call(new t)),E!==Object.prototype&&(a(E,j,!0),r||s(E,p)||u(E,p,_))),C&&T&&T.name!==y&&(P=!0,L=function(){return T.call(this)}),r&&!x||!d&&!P&&M[p]||u(M,p,L),f[e]=L,f[j]=_,g)if(O={values:C?L:S(y),keys:b?L:S(v),entries:A},x)for(w in O)w in M||i(M,w,O[w]);else o(o.P+o.F*(d||P),e,O);return O}},function(t,e,n){var r=n(25),o=n(19),i=n(6),u=n(33),s=n(5),f=n(41),c=Object.getOwnPropertyDescriptor;e.f=n(8)?c:function(t,e){if(t=i(t),e=u(e,!0),f)try{return c(t,e)}catch(t){}if(s(t,e))return o(!r.f.call(t,e),t[e])}},function(t,e,n){var r=n(45),o=n(28).concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return r(t,o)}},function(t,e,n){var r=n(5),o=n(6),i=n(67)(!1),u=n(30)("IE_PROTO");t.exports=function(t,e){var n,s=o(t),f=0,c=[];for(n in s)n!=u&&r(s,n)&&c.push(n);for(;e.length>f;)r(s,n=e[f++])&&(~i(c,n)||c.push(n));return c}},function(t,e,n){t.exports=n(9)},function(t,e){function n(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(t){return"function"==typeof t}function o(t){return"number"==typeof t}function i(t){return"object"==typeof t&&null!==t}function u(t){return void 0===t}t.exports=n,n.EventEmitter=n,n.prototype._events=void 0,n.prototype._maxListeners=void 0,n.defaultMaxListeners=10,n.prototype.setMaxListeners=function(t){if(!o(t)||t<0||isNaN(t))throw TypeError("n must be a positive number");return this._maxListeners=t,this},n.prototype.emit=function(t){var e,n,o,s,f,c;if(this._events||(this._events={}),"error"===t&&(!this._events.error||i(this._events.error)&&!this._events.error.length)){if(e=arguments[1],e instanceof Error)throw e;var a=new Error('Uncaught, unspecified "error" event. ('+e+")");throw a.context=e,a}if(n=this._events[t],u(n))return!1;if(r(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:s=Array.prototype.slice.call(arguments,1),n.apply(this,s)}else if(i(n))for(s=Array.prototype.slice.call(arguments,1),c=n.slice(),o=c.length,f=0;f0&&this._events[t].length>o&&(this._events[t].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[t].length),"function"==typeof console.trace&&console.trace())),this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(t,e){function n(){this.removeListener(t,n),o||(o=!0,e.apply(this,arguments))}if(!r(e))throw TypeError("listener must be a function");var o=!1;return n.listener=e,this.on(t,n),this},n.prototype.removeListener=function(t,e){var n,o,u,s;if(!r(e))throw TypeError("listener must be a function");if(!this._events||!this._events[t])return this;if(n=this._events[t],u=n.length,o=-1,n===e||r(n.listener)&&n.listener===e)delete this._events[t],this._events.removeListener&&this.emit("removeListener",t,e);else if(i(n)){for(s=u;s-- >0;)if(n[s]===e||n[s].listener&&n[s].listener===e){o=s;break}if(o<0)return this;1===n.length?(n.length=0,delete this._events[t]):n.splice(o,1),this._events.removeListener&&this.emit("removeListener",t,e)}return this},n.prototype.removeAllListeners=function(t){var e,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[t]&&delete this._events[t],this;if(0===arguments.length){for(e in this._events)"removeListener"!==e&&this.removeAllListeners(e);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[t],r(n))this.removeListener(t,n);else if(n)for(;n.length;)this.removeListener(t,n[n.length-1]);return delete this._events[t],this},n.prototype.listeners=function(t){var e;return e=this._events&&this._events[t]?r(this._events[t])?[this._events[t]]:this._events[t].slice():[]},n.prototype.listenerCount=function(t){if(this._events){var e=this._events[t];if(r(e))return 1;if(e)return e.length}return 0},n.listenerCount=function(t,e){return t.listenerCount(e)}},,function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,e,n){t.exports=n(3)(124)},function(t,e,n){t.exports=n(1).document&&document.documentElement},function(t,e,n){var r=n(36);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},function(t,e,n){var r=n(32),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},function(t,e,n){var r=n(27);t.exports=function(t){return Object(r(t))}},function(t,e){},function(t,e,n){"use strict";var r=n(78)(!0);n(42)(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,e=this._t,n=this._i;return n>=e.length?{value:void 0,done:!0}:(t=r(e,n),this._i+=t.length,{value:t,done:!1})})},function(t,e,n){n(80);for(var r=n(1),o=n(9),i=n(21),u=n(4)("toStringTag"),s=["NodeList","DOMTokenList","MediaList","StyleSheetList","CSSRuleList"],f=0;f<5;f++){var c=s[f],a=r[c],l=a&&a.prototype;l&&!l[u]&&o(l,u,c),i[c]=i.Array}},function(t,e,n){t.exports={default:n(62),__esModule:!0}},function(t,e,n){t.exports={default:n(63),__esModule:!0}},function(t,e,n){t.exports={default:n(64),__esModule:!0}},function(t,e,n){t.exports={default:n(65),__esModule:!0}},function(t,e,n){n(81);var r=n(7).Object;t.exports=function(t,e){return r.create(t,e)}},function(t,e,n){n(82),t.exports=n(7).Object.setPrototypeOf},function(t,e,n){n(83),n(55),n(84),n(85),t.exports=n(7).Symbol},function(t,e,n){n(56),n(57),t.exports=n(35).f("iterator")},function(t,e){t.exports=function(){}},function(t,e,n){var r=n(6),o=n(53),i=n(79);t.exports=function(t){return function(e,n,u){var s,f=r(e),c=o(f.length),a=i(u,c);if(t&&n!=n){for(;c>a;)if(s=f[a++],s!=s)return!0}else for(;c>a;a++)if((t||a in f)&&f[a]===n)return t||a||0;return!t&&-1}}},function(t,e,n){var r=n(18),o=n(39),i=n(25);t.exports=function(t){var e=r(t),n=o.f;if(n)for(var u,s=n(t),f=i.f,c=0;s.length>c;)f.call(t,u=s[c++])&&e.push(u);return e}},function(t,e,n){var r=n(36);t.exports=Array.isArray||function(t){return"Array"==r(t)}},function(t,e,n){"use strict";var r=n(29),o=n(19),i=n(26),u={};n(9)(u,n(4)("iterator"),function(){return this}),t.exports=function(t,e,n){t.prototype=r(u,{next:o(1,n)}),i(t,e+" Iterator")}},function(t,e){t.exports=function(t,e){return{value:e,done:!!t}}},function(t,e,n){var r=n(18),o=n(6);t.exports=function(t,e){for(var n,i=o(t),u=r(i),s=u.length,f=0;s>f;)if(i[n=u[f++]]===e)return n}},function(t,e,n){var r=n(20)("meta"),o=n(15),i=n(5),u=n(10).f,s=0,f=Object.isExtensible||function(){return!0},c=!n(17)(function(){return f(Object.preventExtensions({}))}),a=function(t){u(t,r,{value:{i:"O"+ ++s,w:{}}})},l=function(t,e){if(!o(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!i(t,r)){if(!f(t))return"F";if(!e)return"E";a(t)}return t[r].i},p=function(t,e){if(!i(t,r)){if(!f(t))return!0;if(!e)return!1;a(t)}return t[r].w},d=function(t){return c&&h.NEED&&f(t)&&!i(t,r)&&a(t),t},h=t.exports={KEY:r,NEED:!1,fastKey:l,getWeak:p,onFreeze:d}},function(t,e,n){var r=n(10),o=n(14),i=n(18);t.exports=n(8)?Object.defineProperties:function(t,e){o(t);for(var n,u=i(e),s=u.length,f=0;s>f;)r.f(t,n=u[f++],e[n]);return t}},function(t,e,n){var r=n(6),o=n(44).f,i={}.toString,u="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(t){try{return o(t)}catch(t){return u.slice()}};t.exports.f=function(t){return u&&"[object Window]"==i.call(t)?s(t):o(r(t))}},function(t,e,n){var r=n(5),o=n(54),i=n(30)("IE_PROTO"),u=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=o(t),r(t,i)?t[i]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?u:null}},function(t,e,n){var r=n(15),o=n(14),i=function(t,e){if(o(t),!r(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,e,r){try{r=n(37)(Function.call,n(43).f(Object.prototype,"__proto__").set,2),r(t,[]),e=!(t instanceof Array)}catch(t){e=!0}return function(t,n){return i(t,n),e?t.__proto__=n:r(t,n),t}}({},!1):void 0),check:i}},function(t,e,n){var r=n(32),o=n(27);t.exports=function(t){return function(e,n){var i,u,s=String(o(e)),f=r(n),c=s.length;return f<0||f>=c?t?"":void 0:(i=s.charCodeAt(f),i<55296||i>56319||f+1===c||(u=s.charCodeAt(f+1))<56320||u>57343?t?s.charAt(f):i:t?s.slice(f,f+2):(i-55296<<10)+(u-56320)+65536)}}},function(t,e,n){var r=n(32),o=Math.max,i=Math.min;t.exports=function(t,e){return t=r(t),t<0?o(t+e,0):i(t,e)}},function(t,e,n){"use strict";var r=n(66),o=n(71),i=n(21),u=n(6);t.exports=n(42)(Array,"Array",function(t,e){this._t=u(t),this._i=0,this._k=e},function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,o(1)):"keys"==e?o(0,n):"values"==e?o(0,t[n]):o(0,[n,t[n]])},"values"),i.Arguments=i.Array,r("keys"),r("values"),r("entries")},function(t,e,n){var r=n(16);r(r.S,"Object",{create:n(29)})},function(t,e,n){var r=n(16);r(r.S,"Object",{setPrototypeOf:n(77).set})},function(t,e,n){"use strict";var r=n(1),o=n(5),i=n(8),u=n(16),s=n(46),f=n(73).KEY,c=n(17),a=n(31),l=n(26),p=n(20),d=n(4),h=n(35),v=n(34),y=n(72),_=n(68),m=n(69),g=n(14),b=n(6),x=n(33),O=n(19),w=n(29),E=n(75),S=n(43),j=n(10),C=n(18),P=S.f,M=j.f,T=E.f,L=r.Symbol,A=r.JSON,k=A&&A.stringify,D="prototype",I=d("_hidden"),N=d("toPrimitive"),F={}.propertyIsEnumerable,R=a("symbol-registry"),U=a("symbols"),B=a("op-symbols"),V=Object[D],$="function"==typeof L,W=r.QObject,q=!W||!W[D]||!W[D].findChild,G=i&&c(function(){return 7!=w(M({},"a",{get:function(){return M(this,"a",{value:7}).a}})).a})?function(t,e,n){var r=P(V,e);r&&delete V[e],M(t,e,n),r&&t!==V&&M(V,e,r)}:M,J=function(t){var e=U[t]=w(L[D]);return e._k=t,e},H=$&&"symbol"==typeof L.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof L},K=function(t,e,n){return t===V&&K(B,e,n),g(t),e=x(e,!0),g(n),o(U,e)?(n.enumerable?(o(t,I)&&t[I][e]&&(t[I][e]=!1),n=w(n,{enumerable:O(0,!1)})):(o(t,I)||M(t,I,O(1,{})),t[I][e]=!0),G(t,e,n)):M(t,e,n)},z=function(t,e){g(t);for(var n,r=_(e=b(e)),o=0,i=r.length;i>o;)K(t,n=r[o++],e[n]);return t},Y=function(t,e){return void 0===e?w(t):z(w(t),e)},Q=function(t){var e=F.call(this,t=x(t,!0));return!(this===V&&o(U,t)&&!o(B,t))&&(!(e||!o(this,t)||!o(U,t)||o(this,I)&&this[I][t])||e)},Z=function(t,e){if(t=b(t),e=x(e,!0),t!==V||!o(U,e)||o(B,e)){var n=P(t,e);return!n||!o(U,e)||o(t,I)&&t[I][e]||(n.enumerable=!0),n}},X=function(t){for(var e,n=T(b(t)),r=[],i=0;n.length>i;)o(U,e=n[i++])||e==I||e==f||r.push(e);return r},tt=function(t){for(var e,n=t===V,r=T(n?B:b(t)),i=[],u=0;r.length>u;)!o(U,e=r[u++])||n&&!o(V,e)||i.push(U[e]);return i};$||(L=function(){if(this instanceof L)throw TypeError("Symbol is not a constructor!");var t=p(arguments.length>0?arguments[0]:void 0),e=function(n){this===V&&e.call(B,n),o(this,I)&&o(this[I],t)&&(this[I][t]=!1),G(this,t,O(1,n))};return i&&q&&G(V,t,{configurable:!0,set:e}),J(t)},s(L[D],"toString",function(){return this._k}),S.f=Z,j.f=K,n(44).f=E.f=X,n(25).f=Q,n(39).f=tt,i&&!n(24)&&s(V,"propertyIsEnumerable",Q,!0),h.f=function(t){return J(d(t))}),u(u.G+u.W+u.F*!$,{Symbol:L});for(var et="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),nt=0;et.length>nt;)d(et[nt++]);for(var et=C(d.store),nt=0;et.length>nt;)v(et[nt++]);u(u.S+u.F*!$,"Symbol",{for:function(t){return o(R,t+="")?R[t]:R[t]=L(t)},keyFor:function(t){if(H(t))return y(R,t);throw TypeError(t+" is not a symbol!")},useSetter:function(){q=!0},useSimple:function(){q=!1}}),u(u.S+u.F*!$,"Object",{create:Y,defineProperty:K,defineProperties:z,getOwnPropertyDescriptor:Z,getOwnPropertyNames:X,getOwnPropertySymbols:tt}),A&&u(u.S+u.F*(!$||c(function(){var t=L();return"[null]"!=k([t])||"{}"!=k({a:t})||"{}"!=k(Object(t))})),"JSON",{stringify:function(t){if(void 0!==t&&!H(t)){for(var e,n,r=[t],o=1;arguments.length>o;)r.push(arguments[o++]);return e=r[1],"function"==typeof e&&(n=e),!n&&m(e)||(e=function(t,e){if(n&&(e=n.call(this,t,e)),!H(e))return e}),r[1]=e,k.apply(A,r)}}}),L[D][N]||n(9)(L[D],N,L[D].valueOf),l(L,"Symbol"),l(Math,"Math",!0),l(r.JSON,"JSON",!0)},function(t,e,n){n(34)("asyncIterator")},function(t,e,n){n(34)("observable")},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0;var o=n(11),i=r(o),u=n(13),s=r(u),f=n(12),c=r(f),a=n(2),l=r(a),p=n(47),d=r(p),h=new d.default,v=function(t){function e(n,r){return(0,i.default)(this,e),(0,s.default)(this,t.call(this,n,r))}return(0,c.default)(e,t),e.prototype.getChildContext=function(){return{$eventBus:h,$appConfig:this.props.appConfig}},e.prototype.componentDidMount=function(){},e.prototype.componentDidUpdate=function(){},e.prototype.componentWillUnmount=function(){},e.prototype.render=function(){return l.default.Children.only(this.props.children)},e}(a.Component);v.defaultProps={appConfig:null},v.propTypes={appConfig:a.PropTypes.object},v.childContextTypes={$eventBus:a.PropTypes.instanceOf(d.default),$appConfig:a.PropTypes.object},e.default=v},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}function o(t,e){return t===e||"function"==typeof t&&"function"==typeof e&&t.toString()===e.toString()}function i(t,e){if(o(t,e))return!0;if("object"!==("undefined"==typeof t?"undefined":(0,s.default)(t))||null===t||"object"!==("undefined"==typeof e?"undefined":(0,s.default)(e))||null===e)return!1;var n=Object.keys(t),r=Object.keys(e);if(n.length!==r.length)return!1;for(var i=0;ic;)for(var p,d=s(arguments[c++]),h=a?r(d).concat(a(d)):r(d),v=h.length,y=0;v>y;)l.call(d,p=h[y++])&&(n[p]=d[p]);return n}:f},,,,,function(t,e,n){var r=n(16);r(r.S+r.F,"Object",{assign:n(118)})},,,,,,,,,,,,,,,,,function(t,e){"use strict";e.__esModule=!0,e.default={getVote:function(t){return new Promise(function(t,e){setTimeout(function(){t({data:{message:123}})},500)})}}},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}function o(t){return{text:t.about}}e.__esModule=!0;var i,u,s,f,c=n(11),a=r(c),l=n(13),p=r(l),d=n(12),h=r(d),v=n(2),y=r(v),_=n(96),m=n(40),g=(i=(0,m.connect)(o),i((f=s=function(t){function e(){return(0,a.default)(this,e),(0,p.default)(this,t.apply(this,arguments))}return(0,h.default)(e,t),e.prototype.render=function(){return y.default.createElement("div",{className:"about"},"this is about page",y.default.createElement(_.Link,{to:"/vote?debug=test"},"vote"),"text: ",this.props.text)},e}(v.Component),s.pageConfig={pageId:"About"},u=f))||u);e.default=g},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0;var o=n(2),i=r(o),u=function(t){var e=t.children;return i.default.Children.only(e)};u.propTypes={children:o.PropTypes.object},e.default=u},,,,function(t,e,n){"use strict";function r(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"test";return t}e.__esModule=!0,e.default=r;n(50)},,function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0;var o=n(50),i=n(146),u=r(i),s=n(150),f=r(s),c=(0,o.combineReducers)({about:u.default,vote:f.default});e.default=c},,function(t,e,n){"use strict";function r(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e.default=t,e}function o(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};switch(e.type){case u.LOAD_VOTE_SUCCESS:return e.payload;default:return t}}e.__esModule=!0,e.default=o;var i=n(102),u=r(i)},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}function o(t,e,n,r){var o=e.routes[e.routes.length-1];if(o.component){var i=o.component.WrappedComponent,u=e.location,s=i.OriginalPage?i.OriginalPage:i;Object.assign(window.__APP_CONFIG__,{pageId:u.query.pageId||s.pageConfig&&s.pageConfig.pageId})}r()}e.__esModule=!0;var i=n(2),u=r(i),s=n(96),f=n(104),c=(r(f),n(142)),a=r(c),l=n(141),p=r(l);e.default=function(t){return u.default.createElement(s.Route,{path:"/",component:a.default,onChange:o},u.default.createElement(s.IndexRoute,{getComponent:function(t,e){n.e(0,function(t){e(null,n(103).default)})}}),u.default.createElement(s.Route,{path:"vote",getComponent:function(t,e){n.e(0,function(t){e(null,n(103).default)})}}),u.default.createElement(s.Route,{path:"about",component:p.default}))}},function(t,e,n){(function(t){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}function o(e,n){var r=[s.default],o=void 0;return o=t.browser?(0,i.createStore)(c.default,e,(0,i.compose)(i.applyMiddleware.apply(void 0,r))):(0,i.createStore)(c.default,e,(0,i.compose)(i.applyMiddleware.apply(void 0,r),function(t){return t}))}e.__esModule=!0,e.default=o;var i=n(50),u=n(89),s=r(u),f=n(148),c=r(f)}).call(e,n(90))}]);
--------------------------------------------------------------------------------
/public/js/min/chat-9ed37d333f9142979733.js:
--------------------------------------------------------------------------------
1 | !function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var n={};return e.m=t,e.c=n,e.p="/static",e(0)}([function(t,e,n){t.exports=n(128)},function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(t,e,n){t.exports=n(3)(6)},function(t,e){t.exports=libs_lib},function(t,e,n){var r=n(31)("wks"),o=n(20),i=n(1).Symbol,s="function"==typeof i,u=t.exports=function(t){return r[t]||(r[t]=s&&i[t]||(s?i:o)("Symbol."+t))};u.store=r},function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},function(t,e,n){var r=n(52),o=n(27);t.exports=function(t){return r(o(t))}},function(t,e){var n=t.exports={version:"2.4.0"};"number"==typeof __e&&(__e=n)},function(t,e,n){t.exports=!n(17)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e,n){var r=n(10),o=n(19);t.exports=n(8)?function(t,e,n){return r.f(t,e,o(1,n))}:function(t,e,n){return t[e]=n,t}},function(t,e,n){var r=n(14),o=n(41),i=n(33),s=Object.defineProperty;e.f=n(8)?Object.defineProperty:function(t,e,n){if(r(t),e=i(e,!0),r(n),o)try{return s(t,e,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},function(t,e){"use strict";e.__esModule=!0,e.default=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0;var o=n(59),i=r(o),s=n(58),u=r(s),a=n(23),f=r(a);e.default=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+("undefined"==typeof e?"undefined":(0,f.default)(e)));t.prototype=(0,u.default)(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(i.default?(0,i.default)(t,e):t.__proto__=e)}},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0;var o=n(23),i=r(o);e.default=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!==("undefined"==typeof e?"undefined":(0,i.default)(e))&&"function"!=typeof e?t:e}},function(t,e,n){var r=n(15);t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},function(t,e){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,e,n){var r=n(1),o=n(7),i=n(37),s=n(9),u="prototype",a=function(t,e,n){var f,c,l,p=t&a.F,d=t&a.G,h=t&a.S,v=t&a.P,y=t&a.B,m=t&a.W,_=d?o:o[e]||(o[e]={}),g=_[u],b=d?r:h?r[e]:(r[e]||{})[u];d&&(n=e);for(f in n)c=!p&&b&&void 0!==b[f],c&&f in _||(l=c?b[f]:n[f],_[f]=d&&"function"!=typeof b[f]?n[f]:y&&c?i(l,r):m&&b[f]==l?function(t){var e=function(e,n,r){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(e);case 2:return new t(e,n)}return new t(e,n,r)}return t.apply(this,arguments)};return e[u]=t[u],e}(l):v&&"function"==typeof l?i(Function.call,l):l,v&&((_.virtual||(_.virtual={}))[f]=l,t&a.R&&g&&!g[f]&&s(g,f,l)))};a.F=1,a.G=2,a.S=4,a.P=8,a.B=16,a.W=32,a.U=64,a.R=128,t.exports=a},function(t,e){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,e,n){var r=n(45),o=n(28);t.exports=Object.keys||function(t){return r(t,o)}},function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},function(t,e){t.exports={}},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}function o(t){var e=Object.getOwnPropertyNames(t).filter(function(e){return y.test(e)&&"function"==typeof t[e]}),n=Object.getPrototypeOf(t);return n!==Object.prototype&&(e=e.concat(o(n))),e}e.__esModule=!0,e.default=void 0;var i=n(11),s=r(i),u=n(13),a=r(u),f=n(12),c=r(f),l=n(2),p=(r(l),n(87)),d=r(p),h=n(47),v=r(h),y=/^on[A-Z]/,m=function(t){function e(n,r){(0,s.default)(this,e);var o=(0,a.default)(this,t.call(this,n,r));return o.__eventNames={},o.__bindFunctions(),o}return(0,c.default)(e,t),e.prototype.__bindFunctions=function(){for(var t=o(this),e=t,n=Array.isArray(e),r=0,e=n?e:e[Symbol.iterator]();;){var i;if(n){if(r>=e.length)break;i=e[r++]}else{if(r=e.next(),r.done)break;i=r.value}var s=i;this[s].funcBinded||(this[s]=this[s].bind(this),this[s].funcBinded=!0)}},e.prototype.on=function(t,e){if("function"!=typeof e)throw new Error("fn should be a function");return this.__eventNames[t]?this.__eventNames[t].push(e):this.__eventNames[t]=[e],this.context.$eventBus.addListener(t,e)},e.prototype.emit=function(t){for(var e,n=arguments.length,r=Array(n>1?n-1:0),o=1;o=0?(this.context.$eventBus.removeListener(t,e),n.splice(r,1),n.length||delete this.__eventNames[t]):console.warn("event: "+t+" is not registered in "+this._reactInternalInstance.getName()+" Component"),!0}return console.warn("event: "+t+" is not registered in "+this.constructor.name+" Component"),!1},e.prototype.shouldComponentUpdate=function(t,e){var n=!(0,d.default)(this.props,t)||!(0,d.default)(this.state,e);return n},e.prototype.componentWillUnmount=function(){for(var t in this.__eventNames)if(this.__eventNames.hasOwnProperty(t))for(var e=this.__eventNames[t],n=Array.isArray(e),r=0,e=n?e:e[Symbol.iterator]();;){var o;if(n){if(r>=e.length)break;o=e[r++]}else{if(r=e.next(),r.done)break;o=r.value}var i=o;this.off(t,i)}},e}(l.Component);e.default=m,m.contextTypes={$eventBus:l.PropTypes.instanceOf(v.default)}},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0;var o=n(61),i=r(o),s=n(60),u=r(s),a="function"==typeof u.default&&"symbol"==typeof i.default?function(t){return typeof t}:function(t){return t&&"function"==typeof u.default&&t.constructor===u.default&&t!==u.default.prototype?"symbol":typeof t};e.default="function"==typeof u.default&&"symbol"===a(i.default)?function(t){return"undefined"==typeof t?"undefined":a(t)}:function(t){return t&&"function"==typeof u.default&&t.constructor===u.default&&t!==u.default.prototype?"symbol":"undefined"==typeof t?"undefined":a(t)}},function(t,e){t.exports=!0},function(t,e){e.f={}.propertyIsEnumerable},function(t,e,n){var r=n(10).f,o=n(5),i=n(4)("toStringTag");t.exports=function(t,e,n){t&&!o(t=n?t:t.prototype,i)&&r(t,i,{configurable:!0,value:e})}},function(t,e){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e,n){var r=n(14),o=n(74),i=n(28),s=n(30)("IE_PROTO"),u=function(){},a="prototype",f=function(){var t,e=n(38)("iframe"),r=i.length,o="<",s=">";for(e.style.display="none",n(51).appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(o+"script"+s+"document.F=Object"+o+"/script"+s),t.close(),f=t.F;r--;)delete f[a][i[r]];return f()};t.exports=Object.create||function(t,e){var n;return null!==t?(u[a]=r(t),n=new u,u[a]=null,n[s]=t):n=f(),void 0===e?n:o(n,e)}},function(t,e,n){var r=n(31)("keys"),o=n(20);t.exports=function(t){return r[t]||(r[t]=o(t))}},function(t,e,n){var r=n(1),o="__core-js_shared__",i=r[o]||(r[o]={});t.exports=function(t){return i[t]||(i[t]={})}},function(t,e){var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},function(t,e,n){var r=n(15);t.exports=function(t,e){if(!r(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!r(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},function(t,e,n){var r=n(1),o=n(7),i=n(24),s=n(35),u=n(10).f;t.exports=function(t){var e=o.Symbol||(o.Symbol=i?{}:r.Symbol||{});"_"==t.charAt(0)||t in e||u(e,t,{value:s.f(t)})}},function(t,e,n){e.f=n(4)},function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e,n){var r=n(49);t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,o){return t.call(e,n,r,o)}}return function(){return t.apply(e,arguments)}}},function(t,e,n){var r=n(15),o=n(1).document,i=r(o)&&r(o.createElement);t.exports=function(t){return i?o.createElement(t):{}}},function(t,e){e.f=Object.getOwnPropertySymbols},function(t,e,n){t.exports=n(3)(153)},function(t,e,n){t.exports=!n(8)&&!n(17)(function(){return 7!=Object.defineProperty(n(38)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){"use strict";var r=n(24),o=n(16),i=n(46),s=n(9),u=n(5),a=n(21),f=n(70),c=n(26),l=n(76),p=n(4)("iterator"),d=!([].keys&&"next"in[].keys()),h="@@iterator",v="keys",y="values",m=function(){return this};t.exports=function(t,e,n,_,g,b,x){f(n,e,_);var w,O,S,E=function(t){if(!d&&t in P)return P[t];switch(t){case v:return function(){return new n(this,t)};case y:return function(){return new n(this,t)}}return function(){return new n(this,t)}},M=e+" Iterator",j=g==y,N=!1,P=t.prototype,L=P[p]||P[h]||g&&P[g],C=L||E(g),T=g?j?E("entries"):C:void 0,A="Array"==e?P.entries||L:L;if(A&&(S=l(A.call(new t)),S!==Object.prototype&&(c(S,M,!0),r||u(S,p)||s(S,p,m))),j&&L&&L.name!==y&&(N=!0,C=function(){return L.call(this)}),r&&!x||!d&&!N&&P[p]||s(P,p,C),a[e]=C,a[M]=m,g)if(w={values:j?C:E(y),keys:b?C:E(v),entries:T},x)for(O in w)O in P||i(P,O,w[O]);else o(o.P+o.F*(d||N),e,w);return w}},function(t,e,n){var r=n(25),o=n(19),i=n(6),s=n(33),u=n(5),a=n(41),f=Object.getOwnPropertyDescriptor;e.f=n(8)?f:function(t,e){if(t=i(t),e=s(e,!0),a)try{return f(t,e)}catch(t){}if(u(t,e))return o(!r.f.call(t,e),t[e])}},function(t,e,n){var r=n(45),o=n(28).concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return r(t,o)}},function(t,e,n){var r=n(5),o=n(6),i=n(67)(!1),s=n(30)("IE_PROTO");t.exports=function(t,e){var n,u=o(t),a=0,f=[];for(n in u)n!=s&&r(u,n)&&f.push(n);for(;e.length>a;)r(u,n=e[a++])&&(~i(f,n)||f.push(n));return f}},function(t,e,n){t.exports=n(9)},function(t,e){function n(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(t){return"function"==typeof t}function o(t){return"number"==typeof t}function i(t){return"object"==typeof t&&null!==t}function s(t){return void 0===t}t.exports=n,n.EventEmitter=n,n.prototype._events=void 0,n.prototype._maxListeners=void 0,n.defaultMaxListeners=10,n.prototype.setMaxListeners=function(t){if(!o(t)||t<0||isNaN(t))throw TypeError("n must be a positive number");return this._maxListeners=t,this},n.prototype.emit=function(t){var e,n,o,u,a,f;if(this._events||(this._events={}),"error"===t&&(!this._events.error||i(this._events.error)&&!this._events.error.length)){if(e=arguments[1],e instanceof Error)throw e;var c=new Error('Uncaught, unspecified "error" event. ('+e+")");throw c.context=e,c}if(n=this._events[t],s(n))return!1;if(r(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:u=Array.prototype.slice.call(arguments,1),n.apply(this,u)}else if(i(n))for(u=Array.prototype.slice.call(arguments,1),f=n.slice(),o=f.length,a=0;a0&&this._events[t].length>o&&(this._events[t].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[t].length),"function"==typeof console.trace&&console.trace())),this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(t,e){function n(){this.removeListener(t,n),o||(o=!0,e.apply(this,arguments))}if(!r(e))throw TypeError("listener must be a function");var o=!1;return n.listener=e,this.on(t,n),this},n.prototype.removeListener=function(t,e){var n,o,s,u;if(!r(e))throw TypeError("listener must be a function");if(!this._events||!this._events[t])return this;if(n=this._events[t],s=n.length,o=-1,n===e||r(n.listener)&&n.listener===e)delete this._events[t],this._events.removeListener&&this.emit("removeListener",t,e);else if(i(n)){for(u=s;u-- >0;)if(n[u]===e||n[u].listener&&n[u].listener===e){o=u;break}if(o<0)return this;1===n.length?(n.length=0,delete this._events[t]):n.splice(o,1),this._events.removeListener&&this.emit("removeListener",t,e)}return this},n.prototype.removeAllListeners=function(t){var e,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[t]&&delete this._events[t],this;if(0===arguments.length){for(e in this._events)"removeListener"!==e&&this.removeAllListeners(e);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[t],r(n))this.removeListener(t,n);else if(n)for(;n.length;)this.removeListener(t,n[n.length-1]);return delete this._events[t],this},n.prototype.listeners=function(t){var e;return e=this._events&&this._events[t]?r(this._events[t])?[this._events[t]]:this._events[t].slice():[]},n.prototype.listenerCount=function(t){if(this._events){var e=this._events[t];if(r(e))return 1;if(e)return e.length}return 0},n.listenerCount=function(t,e){return t.listenerCount(e)}},,function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,e,n){t.exports=n(3)(124)},function(t,e,n){t.exports=n(1).document&&document.documentElement},function(t,e,n){var r=n(36);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},function(t,e,n){var r=n(32),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},function(t,e,n){var r=n(27);t.exports=function(t){return Object(r(t))}},function(t,e){},function(t,e,n){"use strict";var r=n(78)(!0);n(42)(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,e=this._t,n=this._i;return n>=e.length?{value:void 0,done:!0}:(t=r(e,n),this._i+=t.length,{value:t,done:!1})})},function(t,e,n){n(80);for(var r=n(1),o=n(9),i=n(21),s=n(4)("toStringTag"),u=["NodeList","DOMTokenList","MediaList","StyleSheetList","CSSRuleList"],a=0;a<5;a++){var f=u[a],c=r[f],l=c&&c.prototype;l&&!l[s]&&o(l,s,f),i[f]=i.Array}},function(t,e,n){t.exports={default:n(62),__esModule:!0}},function(t,e,n){t.exports={default:n(63),__esModule:!0}},function(t,e,n){t.exports={default:n(64),__esModule:!0}},function(t,e,n){t.exports={default:n(65),__esModule:!0}},function(t,e,n){n(81);var r=n(7).Object;t.exports=function(t,e){return r.create(t,e)}},function(t,e,n){n(82),t.exports=n(7).Object.setPrototypeOf},function(t,e,n){n(83),n(55),n(84),n(85),t.exports=n(7).Symbol},function(t,e,n){n(56),n(57),t.exports=n(35).f("iterator")},function(t,e){t.exports=function(){}},function(t,e,n){var r=n(6),o=n(53),i=n(79);t.exports=function(t){return function(e,n,s){var u,a=r(e),f=o(a.length),c=i(s,f);if(t&&n!=n){for(;f>c;)if(u=a[c++],u!=u)return!0}else for(;f>c;c++)if((t||c in a)&&a[c]===n)return t||c||0;return!t&&-1}}},function(t,e,n){var r=n(18),o=n(39),i=n(25);t.exports=function(t){var e=r(t),n=o.f;if(n)for(var s,u=n(t),a=i.f,f=0;u.length>f;)a.call(t,s=u[f++])&&e.push(s);return e}},function(t,e,n){var r=n(36);t.exports=Array.isArray||function(t){return"Array"==r(t)}},function(t,e,n){"use strict";var r=n(29),o=n(19),i=n(26),s={};n(9)(s,n(4)("iterator"),function(){return this}),t.exports=function(t,e,n){t.prototype=r(s,{next:o(1,n)}),i(t,e+" Iterator")}},function(t,e){t.exports=function(t,e){return{value:e,done:!!t}}},function(t,e,n){var r=n(18),o=n(6);t.exports=function(t,e){for(var n,i=o(t),s=r(i),u=s.length,a=0;u>a;)if(i[n=s[a++]]===e)return n}},function(t,e,n){var r=n(20)("meta"),o=n(15),i=n(5),s=n(10).f,u=0,a=Object.isExtensible||function(){return!0},f=!n(17)(function(){return a(Object.preventExtensions({}))}),c=function(t){s(t,r,{value:{i:"O"+ ++u,w:{}}})},l=function(t,e){if(!o(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!i(t,r)){if(!a(t))return"F";if(!e)return"E";c(t)}return t[r].i},p=function(t,e){if(!i(t,r)){if(!a(t))return!0;if(!e)return!1;c(t)}return t[r].w},d=function(t){return f&&h.NEED&&a(t)&&!i(t,r)&&c(t),t},h=t.exports={KEY:r,NEED:!1,fastKey:l,getWeak:p,onFreeze:d}},function(t,e,n){var r=n(10),o=n(14),i=n(18);t.exports=n(8)?Object.defineProperties:function(t,e){o(t);for(var n,s=i(e),u=s.length,a=0;u>a;)r.f(t,n=s[a++],e[n]);return t}},function(t,e,n){var r=n(6),o=n(44).f,i={}.toString,s="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],u=function(t){try{return o(t)}catch(t){return s.slice()}};t.exports.f=function(t){return s&&"[object Window]"==i.call(t)?u(t):o(r(t))}},function(t,e,n){var r=n(5),o=n(54),i=n(30)("IE_PROTO"),s=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=o(t),r(t,i)?t[i]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?s:null}},function(t,e,n){var r=n(15),o=n(14),i=function(t,e){if(o(t),!r(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,e,r){try{r=n(37)(Function.call,n(43).f(Object.prototype,"__proto__").set,2),r(t,[]),e=!(t instanceof Array)}catch(t){e=!0}return function(t,n){return i(t,n),e?t.__proto__=n:r(t,n),t}}({},!1):void 0),check:i}},function(t,e,n){var r=n(32),o=n(27);t.exports=function(t){return function(e,n){var i,s,u=String(o(e)),a=r(n),f=u.length;return a<0||a>=f?t?"":void 0:(i=u.charCodeAt(a),i<55296||i>56319||a+1===f||(s=u.charCodeAt(a+1))<56320||s>57343?t?u.charAt(a):i:t?u.slice(a,a+2):(i-55296<<10)+(s-56320)+65536)}}},function(t,e,n){var r=n(32),o=Math.max,i=Math.min;t.exports=function(t,e){return t=r(t),t<0?o(t+e,0):i(t,e)}},function(t,e,n){"use strict";var r=n(66),o=n(71),i=n(21),s=n(6);t.exports=n(42)(Array,"Array",function(t,e){this._t=s(t),this._i=0,this._k=e},function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,o(1)):"keys"==e?o(0,n):"values"==e?o(0,t[n]):o(0,[n,t[n]])},"values"),i.Arguments=i.Array,r("keys"),r("values"),r("entries")},function(t,e,n){var r=n(16);r(r.S,"Object",{create:n(29)})},function(t,e,n){var r=n(16);r(r.S,"Object",{setPrototypeOf:n(77).set})},function(t,e,n){"use strict";var r=n(1),o=n(5),i=n(8),s=n(16),u=n(46),a=n(73).KEY,f=n(17),c=n(31),l=n(26),p=n(20),d=n(4),h=n(35),v=n(34),y=n(72),m=n(68),_=n(69),g=n(14),b=n(6),x=n(33),w=n(19),O=n(29),S=n(75),E=n(43),M=n(10),j=n(18),N=E.f,P=M.f,L=S.f,C=r.Symbol,T=r.JSON,A=T&&T.stringify,k="prototype",I=d("_hidden"),F=d("toPrimitive"),B={}.propertyIsEnumerable,R=c("symbol-registry"),D=c("symbols"),W=c("op-symbols"),U=Object[k],$="function"==typeof C,J=r.QObject,K=!J||!J[k]||!J[k].findChild,z=i&&f(function(){return 7!=O(P({},"a",{get:function(){return P(this,"a",{value:7}).a}})).a})?function(t,e,n){var r=N(U,e);r&&delete U[e],P(t,e,n),r&&t!==U&&P(U,e,r)}:P,G=function(t){var e=D[t]=O(C[k]);return e._k=t,e},q=$&&"symbol"==typeof C.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof C},Y=function(t,e,n){return t===U&&Y(W,e,n),g(t),e=x(e,!0),g(n),o(D,e)?(n.enumerable?(o(t,I)&&t[I][e]&&(t[I][e]=!1),n=O(n,{enumerable:w(0,!1)})):(o(t,I)||P(t,I,w(1,{})),t[I][e]=!0),z(t,e,n)):P(t,e,n)},Q=function(t,e){g(t);for(var n,r=m(e=b(e)),o=0,i=r.length;i>o;)Y(t,n=r[o++],e[n]);return t},Z=function(t,e){return void 0===e?O(t):Q(O(t),e)},H=function(t){var e=B.call(this,t=x(t,!0));return!(this===U&&o(D,t)&&!o(W,t))&&(!(e||!o(this,t)||!o(D,t)||o(this,I)&&this[I][t])||e)},V=function(t,e){if(t=b(t),e=x(e,!0),t!==U||!o(D,e)||o(W,e)){var n=N(t,e);return!n||!o(D,e)||o(t,I)&&t[I][e]||(n.enumerable=!0),n}},X=function(t){for(var e,n=L(b(t)),r=[],i=0;n.length>i;)o(D,e=n[i++])||e==I||e==a||r.push(e);return r},tt=function(t){for(var e,n=t===U,r=L(n?W:b(t)),i=[],s=0;r.length>s;)!o(D,e=r[s++])||n&&!o(U,e)||i.push(D[e]);return i};$||(C=function(){if(this instanceof C)throw TypeError("Symbol is not a constructor!");var t=p(arguments.length>0?arguments[0]:void 0),e=function(n){this===U&&e.call(W,n),o(this,I)&&o(this[I],t)&&(this[I][t]=!1),z(this,t,w(1,n))};return i&&K&&z(U,t,{configurable:!0,set:e}),G(t)},u(C[k],"toString",function(){return this._k}),E.f=V,M.f=Y,n(44).f=S.f=X,n(25).f=H,n(39).f=tt,i&&!n(24)&&u(U,"propertyIsEnumerable",H,!0),h.f=function(t){return G(d(t))}),s(s.G+s.W+s.F*!$,{Symbol:C});for(var et="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),nt=0;et.length>nt;)d(et[nt++]);for(var et=j(d.store),nt=0;et.length>nt;)v(et[nt++]);s(s.S+s.F*!$,"Symbol",{for:function(t){return o(R,t+="")?R[t]:R[t]=C(t)},keyFor:function(t){if(q(t))return y(R,t);throw TypeError(t+" is not a symbol!")},useSetter:function(){K=!0},useSimple:function(){K=!1}}),s(s.S+s.F*!$,"Object",{create:Z,defineProperty:Y,defineProperties:Q,getOwnPropertyDescriptor:V,getOwnPropertyNames:X,getOwnPropertySymbols:tt}),T&&s(s.S+s.F*(!$||f(function(){var t=C();return"[null]"!=A([t])||"{}"!=A({a:t})||"{}"!=A(Object(t))})),"JSON",{stringify:function(t){if(void 0!==t&&!q(t)){for(var e,n,r=[t],o=1;arguments.length>o;)r.push(arguments[o++]);return e=r[1],"function"==typeof e&&(n=e),!n&&_(e)||(e=function(t,e){if(n&&(e=n.call(this,t,e)),!q(e))return e}),r[1]=e,A.apply(T,r)}}}),C[k][F]||n(9)(C[k],F,C[k].valueOf),l(C,"Symbol"),l(Math,"Math",!0),l(r.JSON,"JSON",!0)},function(t,e,n){n(34)("asyncIterator")},function(t,e,n){n(34)("observable")},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0;var o=n(11),i=r(o),s=n(13),u=r(s),a=n(12),f=r(a),c=n(2),l=r(c),p=n(47),d=r(p),h=new d.default,v=function(t){function e(n,r){return(0,i.default)(this,e),(0,u.default)(this,t.call(this,n,r))}return(0,f.default)(e,t),e.prototype.getChildContext=function(){return{$eventBus:h,$appConfig:this.props.appConfig}},e.prototype.componentDidMount=function(){},e.prototype.componentDidUpdate=function(){},e.prototype.componentWillUnmount=function(){},e.prototype.render=function(){return l.default.Children.only(this.props.children)},e}(c.Component);v.defaultProps={appConfig:null},v.propTypes={appConfig:c.PropTypes.object},v.childContextTypes={$eventBus:c.PropTypes.instanceOf(d.default),$appConfig:c.PropTypes.object},e.default=v},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}function o(t,e){return t===e||"function"==typeof t&&"function"==typeof e&&t.toString()===e.toString()}function i(t,e){if(o(t,e))return!0;if("object"!==("undefined"==typeof t?"undefined":(0,u.default)(t))||null===t||"object"!==("undefined"==typeof e?"undefined":(0,u.default)(e))||null===e)return!1;var n=Object.keys(t),r=Object.keys(e);if(n.length!==r.length)return!1;for(var i=0;i0&&void 0!==arguments[0]?arguments[0]:{},e=null,n=document.getElementById("page"),r="function"==typeof t.onRenderCompleted&&t.onRenderCompleted;return function(o){var i=o.rootReducer,f=void 0===i?function(){}:i,c=o.component,l=void 0===c?null:c,d="function"==typeof t.transformer?t.transformer(window.__INITIAL_STATE__):window.__INITIAL_STATE__;return e||(e=(0,h.default)(d,f)),(0,u.render)(s.default.createElement(a.Provider,{store:e},s.default.createElement(p.default,{appConfig:window.__APP_CONFIG__},l)),n,r),Promise.resolve(e)}}e.__esModule=!0,e.default=o;var i=n(2),s=r(i),u=n(88),a=n(40),f=n(94),c=r(f),l=n(86),p=r(l),d=n(93),h=r(d);c.default.attach(document.body)},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}function o(t,e){var n=f(e,t);return n}e.__esModule=!0,e.default=o;var i=n(50),s=n(89),u=r(s),a=function(){var t=(0,i.applyMiddleware)(u.default),e=[t];return e},f=i.compose.apply(void 0,a())(i.createStore)},function(t,e,n){t.exports=n(3)(126)},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}var o=n(2),i=r(o),s=n(92),u=r(s),a=n(144),f=r(a);n(91);var c=(0,u.default)();c({component:i.default.createElement(f.default,null)})},,,,function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0,e.default=void 0;var o=n(11),i=r(o),s=n(13),u=r(s),a=n(12),f=r(a),c=n(2),l=r(c),p=n(22),d=r(p),h=function(t){function e(n,r){(0,i.default)(this,e);var o=(0,u.default)(this,t.call(this,n,r));return o.state={newName:""},o}return(0,f.default)(e,t),e.prototype.onKey=function(t){this.setState({newName:t.target.value})},e.prototype.onSubmit=function(t){t.preventDefault();var e=this.state.newName;this.props.onChangeName(e),this.setState({newName:""})},e.prototype.render=function(){return l.default.createElement("div",{className:"change_name_form"},l.default.createElement("h3",null," Change Name "),l.default.createElement("form",{onSubmit:this.onSubmit},l.default.createElement("input",{onChange:this.onKey,value:this.state.newName})))},e}(d.default);e.default=h},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0,e.MessageForm=e.MessageList=e.Message=void 0;var o=n(11),i=r(o),s=n(13),u=r(s),a=n(12),f=r(a),c=n(2),l=r(c),p=n(22),d=r(p),h=e.Message=function(t){function e(n,r){return(0,i.default)(this,e),(0,u.default)(this,t.call(this,n,r))}return(0,f.default)(e,t),e.prototype.render=function(){return l.default.createElement("div",{className:"message"},l.default.createElement("strong",null,this.props.user," :"),l.default.createElement("span",null,this.props.text))},e}(d.default);h.defaultProps={user:"",text:""},h.propTypes={user:c.PropTypes.string.isRequired,text:c.PropTypes.string.isRequired};e.MessageList=function(t){function e(n,r){return(0,i.default)(this,e),(0,u.default)(this,t.call(this,n,r))}return(0,f.default)(e,t),e.prototype.render=function(){return l.default.createElement("div",{className:"messages"},l.default.createElement("h2",null," Conversation: "),this.props.messages.map(function(t,e){return l.default.createElement(h,{key:e,user:t.user,text:t.text})}))},e}(d.default),e.MessageForm=function(t){function e(n,r){(0,i.default)(this,e);var o=(0,u.default)(this,t.call(this,n,r));return o.state={text:""},o}return(0,f.default)(e,t),e.prototype.onSubmit=function(t){if(t.preventDefault(),this.state.text){var e={user:this.props.user,text:this.state.text};this.props.onMessageSubmit(e),this.setState({text:""})}},e.prototype.onChange=function(t){this.setState({text:t.target.value})},e.prototype.render=function(){return l.default.createElement("div",{className:"message_form"},l.default.createElement("h3",null,"Write New Message"),l.default.createElement("form",{onSubmit:this.onSubmit},l.default.createElement("input",{onChange:this.onChange,value:this.state.text})))},e}(d.default)},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0,e.default=void 0;var o=n(11),i=r(o),s=n(13),u=r(s),a=n(12),f=r(a),c=n(2),l=r(c),p=n(22),d=r(p),h=function(t){function e(n,r){return(0,i.default)(this,e),(0,u.default)(this,t.call(this,n,r))}return(0,f.default)(e,t),e.prototype.render=function(){return l.default.createElement("div",{className:"users"},l.default.createElement("h3",null," Online Users "),l.default.createElement("ul",null,this.props.users.map(function(t,e){return l.default.createElement("li",{key:e},t)})))},e}(d.default);e.default=h},,,,,,,,,,function(t,e,n){(function(t){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}e.__esModule=!0;var o=n(11),i=r(o),s=n(13),u=r(s),a=n(12),f=r(a),c=n(2),l=r(c),p=(n(40),n(22)),d=r(p),h=n(134),v=r(h),y=n(133),m=n(132),_=r(m);if(t.browser)var g=io.connect();var b=function(t){function e(n,r){(0,i.default)(this,e);var o=(0,u.default)(this,t.call(this,n,r));return o.state={users:[],messages:[],text:""},o}return(0,f.default)(e,t),e.prototype.componentDidMount=function(){g.on("init",this.initialize.bind(this)),g.on("send:message",this.messageRecieve.bind(this)),g.on("user:join",this.userJoined.bind(this)),g.on("user:left",this.userLeft.bind(this)),g.on("change:name",this.userChangedName.bind(this))},e.prototype.initialize=function(t){var e=t.users,n=t.name;this.setState({users:e,user:n})},e.prototype.messageRecieve=function(t){var e=this.state.messages;this.setState({messages:[].concat(e,[t])})},e.prototype.userJoined=function(t){var e=this.state,n=e.users,r=e.messages,o=t.name;this.setState({users:[n,o],messages:[].concat(r,[{user:"APPLICATION BOT",text:o+" Joined"}])})},e.prototype.userLeft=function(t){var e=this.state,n=e.users,r=e.messages,o=t.name,i=n.indexOf(o);n.splice(i,1),this.setState({users:[].concat(n),messages:[].concat(r,[{user:"APPLICATION BOT",text:o+" Left"}])})},e.prototype.userChangedName=function(t){var e=t.oldName,n=t.newName,r=this.state,o=r.users,i=r.messages,s=o.indexOf(e);o.splice(s,1,n),this.setState({users:[].concat(o),messages:[].concat(i,[{user:"APPLICATION BOT",text:"Change Name : "+e+" ==> "+n}])})},e.prototype.onMessageSubmit=function(t){var e=this.state.messages;this.setState({messages:[].concat(e,[t])}),g.emit("send:message",t)},e.prototype.onChangeName=function(t){var e=this,n=this.state.user,r=this.state.messages;g.emit("change:name",{name:t},function(o){if(!o)return alert("There was an error changing your name");var i=e.state.users,s=i.indexOf(n);i.splice(s,1,t),r=r.map(function(e){return e.user===n?Object.assign({},e,{user:t}):e}),e.setState({users:[].concat(i),user:t,messages:r})})},e.prototype.render=function(){return l.default.createElement("div",null,l.default.createElement(v.default,{users:this.state.users}),l.default.createElement(y.MessageList,{messages:this.state.messages}),l.default.createElement(y.MessageForm,{onMessageSubmit:this.onMessageSubmit,user:this.state.user}),l.default.createElement(_.default,{onChangeName:this.onChangeName}))},e}(d.default);e.default=b}).call(e,n(90))}]);
--------------------------------------------------------------------------------
/server/apis/index.js:
--------------------------------------------------------------------------------
1 | import { Router } from 'express';
2 |
3 | let router = new Router();
4 |
5 | router.post('/ajax', function(req, res, next){
6 | if(error) {
7 | next();
8 | } else {
9 | res.send('test')
10 | }
11 | });
12 |
13 | export default router;
14 |
15 |
16 |
--------------------------------------------------------------------------------
/server/app.js:
--------------------------------------------------------------------------------
1 | import http from 'http';
2 | import express from 'express';
3 | import compress from 'compression';
4 | import logger from 'morgan';
5 | import cookieParser from 'cookie-parser';
6 | import bodyParser from 'body-parser';
7 | import session from 'express-session';
8 | import csurf from 'csurf';
9 | import config from './config/config.json';
10 | import routes from './routes/index';
11 | import apis from './apis/index';
12 | import allowCrossDomain from './middlewares/allowCrossDomain'
13 | import reactRender from './middlewares/renderReactMiddleware';
14 | import Immutable from 'immutable';
15 | import helmet from 'helmet';
16 | import socket from './sockets/socket';
17 | import spaRenderMatch from './middlewares/spaRenderMatch';
18 |
19 | let app = express();
20 |
21 | app.set('host', process.env.IP || '127.0.0.1');
22 | app.set('port', process.env.PORT || 3000);
23 | app.disable('x-powered-by');
24 |
25 | app.use(helmet.contentSecurityPolicy());
26 | app.use(helmet.frameguard());
27 | app.use(helmet.noSniff());
28 | app.use(helmet.xssFilter());
29 | app.use(helmet.hsts());
30 | app.use(compress());
31 | app.use(logger('dev'));
32 | app.use(bodyParser.json());
33 | app.use(bodyParser.urlencoded({ extended: true }));
34 | app.use(cookieParser());
35 | app.use(session({
36 | resave: true,
37 | secret: 'mySecretCookieSalt',
38 | key: 'myCookieSessionId',
39 | saveUninitialized: true,
40 | cookie: {
41 | httpOnly: true,
42 | }
43 | }));
44 |
45 | // app.use(favicon(__dirname + '/../public/favicon.ico'));
46 | app.use('/static', express.static(__dirname + '/../public', {
47 | maxAge: 86400000
48 | }));
49 |
50 | // if(process.env.NODE_ENV !== 'production'){
51 | // let webpack = require('webpack');
52 | // let config = require('../create-webpack.config')(true);
53 | // let webpackDevMiddleware = require('webpack-dev-middleware');
54 | // let webpackHotMiddleware = require('webpack-hot-middleware');
55 | // let compiler = webpack(config);
56 | // app.use(webpackDevMiddleware(compiler, { noInfo: true, publicPath: config.output.publicPath }));
57 | // app.use(webpackHotMiddleware(compiler));
58 | // }
59 |
60 | app.use(allowCrossDomain);
61 |
62 | app.use(csurf());
63 | app.use(function (req, res, next) {
64 | res.locals.csrftoken = req.csrfToken();
65 | next();
66 | });
67 | app.use(reactRender({
68 | transformer: function(data){
69 | return Immutable.fromJS(data);
70 | }
71 | }));
72 |
73 | app.use('/api', apis);
74 | app.use('/', routes);
75 | app.use('*', spaRenderMatch);
76 |
77 | // error handlers
78 | // no stacktraces leaked to user
79 | app.use(function(err, req, res, next) {
80 | console.dir(err);
81 | res.status(err.status || 500);
82 | if(err.status === 500) {
83 | console.error(err.stack);
84 | res.json({error: 'Internal Server Error'});
85 | }
86 | else if(err.status === 404) {
87 | res.render('error'); //render error page
88 | } else {
89 | res.json({error: err.message})
90 | }
91 | });
92 |
93 |
94 | process.on('uncaughtException', err => {
95 | console.error(err.message + '\n' + err.stack);
96 | });
97 | process.on('unhandledRejection', (reason, p) => {
98 | console.error("Unhandled Rejection at: Promise ", p, " reason: ", reason);
99 | });
100 | process.on('rejectionHandled', (reason, p) => {
101 | console.warn("rejectionHandled at: Promise ", p, " reason: ", reason);
102 | });
103 |
104 | let server = http.createServer(app);
105 |
106 | /* Socket.io Communication */
107 | let io = require('socket.io').listen(server);
108 | io.sockets.on('connection', socket);
109 |
110 | server.listen(app.get('port'), app.get('host'), function() {
111 | let { address, port } = server.address();
112 | console.log(`${ config.serverName } server listening at http://%s:%s`, address, port);
113 | });
114 |
115 |
--------------------------------------------------------------------------------
/server/config/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "application": {
3 | "version": {
4 | "css": "",
5 | "js": ""
6 | },
7 | "debugName": "test"
8 | },
9 | "serverName": "isomophic-react-redux-starter"
10 | }
--------------------------------------------------------------------------------
/server/controllers/async.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import fetch from 'isomorphic-fetch';
3 | import rootReducer from '../../common/reducers/async';
4 | import Page from '../../common/pages/async/Page.jsx';
5 |
6 | module.exports = async function (req, res, next) {
7 | let state = {
8 | postsByReddit: {},
9 | selectedReddit: 'reactjs'
10 | };
11 |
12 | try {
13 | let response = await fetch(`https://www.reddit.com/r/${state.selectedReddit}.json`, {
14 | method: 'GET',
15 | timeout: 5000
16 | }).then(response => response.json());
17 |
18 | state.postsByReddit[state.selectedReddit] = {
19 | didInvalidate: false,
20 | isFetching: false,
21 | lastUpdated: Date.now(),
22 | items: response.data.children.map(child => child.data)
23 | };
24 |
25 | } catch(ex){
26 | console.error(ex);
27 | }
28 |
29 | res.renderReactHTML({
30 | component: ,
31 | locals: {
32 | appName: 'async',
33 | title: 'async page'
34 | },
35 | data: state,
36 | rootReducer
37 | });
38 |
39 | };
40 |
--------------------------------------------------------------------------------
/server/controllers/chat.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Page from '../../common/pages/chat/Page';
3 | import fs from 'fs';
4 |
5 | let template = fs.readFileSync(__dirname + '/../views/chat.html', 'utf8');
6 | let fakeData = {
7 |
8 | };
9 |
10 | module.exports = function (req, res, next) {
11 | res.renderReactHTML({
12 | template,
13 | component: ,
14 | locals: {
15 | appName: 'chat',
16 | title: 'chat page'
17 | },
18 | data: fakeData,
19 | needTransform: false
20 | });
21 | };
22 |
--------------------------------------------------------------------------------
/server/controllers/todo.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import rootReducer from '../../common/reducers/todo';
3 | import Page from '../../common/pages/todo/Todo';
4 |
5 | let fakeData = {
6 | visibilityFilter: 'SHOW_ALL',
7 | todos: [
8 | {
9 | text: 'one',
10 | completed: false
11 | },
12 | {
13 | text: 'two',
14 | completed: true
15 | }
16 | ]
17 | };
18 |
19 | module.exports = function (req, res, next) {
20 | res.renderReactHTML({
21 | component: ,
22 | locals: {
23 | appName: 'todo',
24 | title: 'todo page'
25 | },
26 | data: fakeData,
27 | rootReducer,
28 | pageConfig: {
29 | user: 'test'
30 | }
31 | });
32 | };
33 |
--------------------------------------------------------------------------------
/server/middlewares/allowCrossDomain.js:
--------------------------------------------------------------------------------
1 |
2 | export default function allowCrossDomain(req, res, next) {
3 | let allowedOrigins = [
4 | 'http://www.test.com'
5 | ];
6 | let origin = req.headers.origin;
7 | if(allowedOrigins.indexOf(origin) > -1){
8 | res.header('Access-Control-Allow-Origin', origin);
9 | }
10 | next();
11 | }
12 |
--------------------------------------------------------------------------------
/server/middlewares/renderReactMiddleware.jsx:
--------------------------------------------------------------------------------
1 | import ejs from 'ejs';
2 | import React from 'react';
3 | import {renderToString} from 'react-dom/server';
4 | import {Provider} from 'react-redux';
5 | import fs from 'fs';
6 | import { jsObj as safeJSON } from 'secure-filters';
7 |
8 | import configureStore from '../../common/store/index';
9 | import App from '../../common/App.jsx';
10 | import config from '../config/config.json';
11 |
12 | const defaultTemplate = fs.readFileSync(__dirname + '/../views/index.html', 'utf8');
13 |
14 | export function getDefaultJSVersion(name) {
15 | let webpackAssets = fs.readFileSync(__dirname + '/../../webpack-assets.json', 'utf8');
16 |
17 | try {
18 | webpackAssets = JSON.parse(webpackAssets);
19 | } catch (ex) {
20 | console.log('webpack-assets.json parsed error');
21 | webpackAssets = {};
22 | }
23 | return webpackAssets[name];
24 | }
25 |
26 | export default function reactRender(middlewareConfig = {}) {
27 | return function (req, res, next) {
28 | res.renderReactHTML = function (opts = {}) {
29 | let {
30 | template = '',
31 | component = '',
32 | data = {},
33 | rootReducer = (() => {
34 | }),
35 | locals = {},
36 | pageConfig = {},
37 | needTransform = true
38 | } = opts;
39 | let transformedData = (typeof middlewareConfig.transformer === 'function' && needTransform)
40 | ? middlewareConfig.transformer(data) : data;
41 | let store = configureStore(transformedData, rootReducer);
42 | let html = '';
43 | pageConfig = Object.assign(typeof middlewareConfig.appConfig === 'object'
44 | ? middlewareConfig.appConfig : {}, pageConfig);
45 |
46 | try {
47 | html = renderToString((
48 |
49 |
50 | { component }
51 |
52 |
53 | ));
54 | } catch (ex) {
55 | html = 'internal server error: \n' + ex.message;
56 | console.error(ex.message);
57 | }
58 |
59 | let debug = req.query.debug && (req.query.debug === config.application.debugName);
60 | let version = config.application.version;
61 | let jsVersion = '';
62 | // prefer config version, useful when using CDN config
63 | if (process.env.NODE_ENV === 'production') {
64 | jsVersion = version && version.js;
65 | } else {
66 | jsVersion = getDefaultJSVersion(locals.appName || 'index');
67 | }
68 | template = template || middlewareConfig.defaultTemplate || defaultTemplate;
69 |
70 | let finalLocals = Object.assign({
71 | html,
72 | state: safeJSON(data),
73 | appName: 'index',
74 | title: '',
75 | test: process.env.NODE_ENV !== 'production',
76 | debug,
77 | appConfig: safeJSON(pageConfig),
78 | version: {
79 | js: jsVersion,
80 | css: version && version.css
81 | }
82 | }, res.locals, locals);
83 |
84 | let pageStr = ejs.render(template, finalLocals, {
85 | compileDebug: false
86 | });
87 |
88 | res.status(200).send(pageStr);
89 | };
90 |
91 | next();
92 | };
93 | }
94 |
--------------------------------------------------------------------------------
/server/middlewares/spaRenderMatch.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {renderToString} from 'react-dom/server';
3 | import {createMemoryHistory, match, RouterContext} from 'react-router';
4 | import {Provider} from 'react-redux';
5 | import createRoutes from '../../common/routes';
6 | import configureStore from '../../common/store/spaStore';
7 | import preRenderMiddleware from '../utils/preRender';
8 | import ejs from 'ejs';
9 | import config from '../config/config.json';
10 | import { getDefaultJSVersion } from './renderReactMiddleware';
11 | import App from '../../common/App.jsx';
12 | import { jsObj as safeJSON } from 'secure-filters';
13 | import fs from 'fs';
14 |
15 | const defaultTemplate = fs.readFileSync(__dirname + '/../views/index.html', 'utf8');
16 |
17 |
18 | export default function renderMatch(req, res) {
19 | const history = createMemoryHistory();
20 | const store = configureStore({
21 | user: {}
22 | }, history);
23 | let appConfig = {
24 | time: Date.now()
25 | };
26 | const routes = createRoutes(store, appConfig);
27 |
28 | match({routes, location: req.originalUrl}, async function (err, redirect, props){
29 | if (err) {
30 | res.status(500).json(err);
31 | } else if (redirect) {
32 | res.redirect(302, redirect.pathname + redirect.search);
33 | } else if (props) {
34 | let debug = req.query.debug && (req.query.debug === config.application.debugName);
35 | let version = config.application.version;
36 | let jsVersion = '';
37 | // prefer config version, useful when using CDN config
38 | if (process.env.NODE_ENV === 'production') {
39 | jsVersion = version && version.js;
40 | } else {
41 | jsVersion = getDefaultJSVersion('app');
42 | }
43 | let initialState = {};
44 | let componentHTML = '';
45 | let errorMsg = '';
46 |
47 | try {
48 | await preRenderMiddleware(store.dispatch, props, appConfig, req);
49 |
50 | componentHTML = renderToString(
51 |
52 |
53 |
54 |
55 |
56 | );
57 |
58 | initialState = store.getState();
59 |
60 | } catch(ex){
61 | errorMsg = ex.stack;
62 | console.log(ex.stack)
63 | }
64 |
65 | let pageStr = ejs.render(defaultTemplate, Object.assign({
66 | errorMsg,
67 | html: componentHTML,
68 | state: safeJSON(initialState),
69 | appName: 'app',
70 | title: '',
71 | test: process.env.NODE_ENV !== 'production',
72 | debug: debug,
73 | appConfig: safeJSON(appConfig),
74 | version: {
75 | js: jsVersion,
76 | css: version && version.css
77 | }
78 | }, {}), {
79 | compileDebug: false
80 | });
81 |
82 | res.status(200).send(pageStr);
83 |
84 | } else {
85 | res.redirect('/');
86 | }
87 | });
88 | }
89 |
--------------------------------------------------------------------------------
/server/routes/index.js:
--------------------------------------------------------------------------------
1 | import { Router } from 'express';
2 | import fs from 'fs';
3 |
4 | let router = new Router();
5 |
6 | import IndexPage from '../controllers/todo';
7 | import AsyncPage from '../controllers/async';
8 | import ChatPage from '../controllers/chat';
9 |
10 |
11 | /**
12 | * 首页请求
13 | */
14 | router.get('/', IndexPage);
15 | router.get('/async', AsyncPage);
16 | router.get('/chat', ChatPage);
17 |
18 |
19 | /**
20 | * 静态资源
21 | */
22 | let content = fs.readFileSync(__dirname + '/../../client/js/utils/sw.js', 'utf8');
23 |
24 | router.get('/sw.js', async function(req, res){
25 | res.set('Content-Type', 'application/javascript');
26 | res.send(content);
27 | });
28 |
29 | export default router;
30 |
--------------------------------------------------------------------------------
/server/sockets/socket.js:
--------------------------------------------------------------------------------
1 | // Keep track of which names are used so that there are no duplicates
2 | let userNames = (function () {
3 | let names = {};
4 |
5 | let claim = function (name) {
6 | if (!name || names[name]) {
7 | return false;
8 | } else {
9 | names[name] = true;
10 | return true;
11 | }
12 | };
13 |
14 | // find the lowest unused "guest" name and claim it
15 | let getGuestName = function () {
16 | let name,
17 | nextUserId = 1;
18 |
19 | do {
20 | name = 'Guest ' + nextUserId;
21 | nextUserId += 1;
22 | } while (!claim(name));
23 |
24 | return name;
25 | };
26 |
27 | // serialize claimed names as an array
28 | let get = function () {
29 | let res = [];
30 | for (let user in names) {
31 | res.push(user);
32 | }
33 |
34 | return res;
35 | };
36 |
37 | let free = function (name) {
38 | if (names[name]) {
39 | delete names[name];
40 | }
41 | };
42 |
43 | return {
44 | claim: claim,
45 | free: free,
46 | get: get,
47 | getGuestName: getGuestName
48 | };
49 | }());
50 |
51 | // export function for listening to the socket
52 | export default function (socket) {
53 | let name = userNames.getGuestName();
54 |
55 | // send the new user their name and a list of users
56 | socket.emit('init', {
57 | name: name,
58 | users: userNames.get()
59 | });
60 |
61 | // notify other clients that a new user has joined
62 | socket.broadcast.emit('user:join', {
63 | name: name
64 | });
65 |
66 | // broadcast a user's message to other users
67 | socket.on('send:message', function (data) {
68 | socket.broadcast.emit('send:message', {
69 | user: name,
70 | text: data.text
71 | });
72 | });
73 |
74 | // validate a user's name change, and broadcast it on success
75 | socket.on('change:name', function (data, fn) {
76 | if (userNames.claim(data.name)) {
77 | let oldName = name;
78 | userNames.free(oldName);
79 |
80 | name = data.name;
81 |
82 | socket.broadcast.emit('change:name', {
83 | oldName: oldName,
84 | newName: name
85 | });
86 |
87 | fn(true);
88 | } else {
89 | fn(false);
90 | }
91 | });
92 |
93 | // clean up when a user leaves, and broadcast it to other users
94 | socket.on('disconnect', function () {
95 | socket.broadcast.emit('user:left', {
96 | name: name
97 | });
98 | userNames.free(name);
99 | });
100 | };
101 |
--------------------------------------------------------------------------------
/server/utils/preRender.js:
--------------------------------------------------------------------------------
1 | function preRenderMiddleware(dispatch, { components, location, params }, appConfig = {}, req) {
2 | const promises = components.map((current) => {
3 | if(!current) return null;
4 |
5 | const component = current.WrappedComponent ? current.WrappedComponent : current;
6 | const pageConfig = component.OriginalPage && component.OriginalPage.pageConfig;
7 |
8 | return component.fetchData ? component.fetchData({ dispatch, location, params, appConfig, pageConfig }, req) : null;
9 | });
10 |
11 | let lastComponent = components[components.length - 1].WrappedComponent ? components[components.length - 1].WrappedComponent : components[components.length - 1];
12 | appConfig.pageId = lastComponent && lastComponent.OriginalPage && lastComponent.OriginalPage.pageConfig && lastComponent.OriginalPage.pageConfig.pageId;
13 |
14 | return Promise.all(promises);
15 | }
16 |
17 | export default preRenderMiddleware;
18 |
--------------------------------------------------------------------------------
/server/views/chat.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | <%= locals.title %>
10 | <% if(locals.test) { %>
11 |
12 | <% } else { %>
13 |
14 | <% } %>
15 |
16 |
17 |
18 | <%- locals.html %>
19 |
23 |
42 | <% if(locals.debug) { %>
43 |
44 | <% } else if(locals.test){ %>
45 |
46 | <% } else { %>
47 |
48 | <% } %>
49 |
50 | <% if(locals.debug) { %>
51 |
52 | <% } else if(locals.test){ %>
53 |
54 | <% } else { %>
55 |
56 | <% } %>
57 |
58 |
59 |
--------------------------------------------------------------------------------
/server/views/error.ejs:
--------------------------------------------------------------------------------
1 | <% include ./partials/header %>
2 | <%- message %>
3 | <%- error.status %>
4 | <%- error.stack %>
5 | <% include ./partials/footer %>
6 |
--------------------------------------------------------------------------------
/server/views/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | <%= locals.title %>
10 | <% if(locals.test) { %>
11 |
12 | <% } else { %>
13 |
14 | <% } %>
15 |
16 |
17 |
18 | <%- locals.html %>
19 |
20 |
24 |
43 | <% if(locals.debug) { %>
44 |
45 | <% } else if(locals.test){ %>
46 |
47 | <% } else { %>
48 |
49 | <% } %>
50 | <% if(locals.debug) { %>
51 |
52 | <% } else if(locals.test){ %>
53 |
54 | <% } else { %>
55 |
56 | <% } %>
57 |
58 |
59 |
--------------------------------------------------------------------------------
/starter.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | let pm2 = require('pm2');
4 |
5 | const instances = process.env.NODE_ENV === 'production'
6 | ? (process.env.WEB_CONCURRENCY || -1) : 1; // Set by Heroku or -1 to scale to max cpu core -1
7 | const maxMemory = process.env.WEB_MEMORY || 512; // " " "
8 |
9 | pm2.connect(function() {
10 | pm2.start({
11 | script : './dist/server.js',
12 | name : 'react-ocean',
13 | exec_mode : 'cluster',
14 | instances : instances,
15 | maxMemoryRestart : `${ maxMemory }M`, // Auto restart if process taking more than XXmo
16 | maxRestarts: 5,
17 | minUptime: 5000,
18 | log_file : './log/combined.outer.log',
19 | error_file: './log/err.log',
20 | out_file: './log/out.log',
21 | merge_logs: true,
22 | env: {
23 | "NODE_ENV": "development"
24 | },
25 | env_testing: {
26 | "NODE_ENV": "test"
27 | },
28 | env_production: {
29 | "NODE_ENV": "production"
30 | }
31 | }, function(err) {
32 | pm2.disconnect(); // Disconnect from PM2
33 |
34 | if (err)
35 | return console.error('Error while launching applications', err.stack || err);
36 |
37 | console.log('PM2 and application has been successfully started');
38 |
39 | // Display logs in standard output
40 | pm2.launchBus(function(err, bus) {
41 | console.log('[PM2] Log streaming started');
42 | bus.on('log:out', function(packet) {
43 | console.log('[App:%s] %s', packet.process.name, packet.data);
44 | });
45 | bus.on('log:err', function(packet) {
46 | console.error('[App:%s][Err] %s', packet.process.name, packet.data);
47 | });
48 | });
49 | });
50 | });
51 |
--------------------------------------------------------------------------------
/webpack-assets.json:
--------------------------------------------------------------------------------
1 | {"async":"883364dc66df5d4fa947","todo":"7c925fbf328875163978","chat":"9ed37d333f9142979733"}
--------------------------------------------------------------------------------
/webpack.config-server.js:
--------------------------------------------------------------------------------
1 | let fs = require('fs');
2 | let path = require('path');
3 | let webpack = require('webpack');
4 | let packageJson = require('./package.json');
5 |
6 |
7 | module.exports = {
8 | entry: path.resolve(__dirname, './server/app.js'),
9 |
10 | output: {
11 | path: path.resolve(__dirname, "./dist"),
12 | pathinfo: true,
13 | filename: 'server.js',
14 | libraryTarget: 'commonjs2'
15 | },
16 |
17 | debug: true,
18 | cache: true,
19 | devtool: 'source-map',
20 |
21 | target: 'node',
22 |
23 | node: {
24 | __filename: true,
25 | __dirname: true
26 | },
27 |
28 | resolve: {
29 | extensions: ['', '.js', '.jsx'],
30 | modulesDirectories: [
31 | // 'client',
32 | 'node_modules',
33 | ],
34 | },
35 |
36 | externals: Object.keys(packageJson.dependencies).filter((item) => {
37 | return (item !== 'react' && item !== 'react-dom')
38 | }).concat([
39 | // {
40 | // 'react': 'react/dist/react.min.js'
41 | // },
42 | 'react',
43 | 'react-dom/server'
44 | ]),
45 |
46 | module: {
47 | loaders: [
48 | {
49 | test: /\.jsx?$/,
50 | exclude: /node_modules/,
51 | loader: 'babel-loader',
52 | // query: {
53 | // presets: [
54 | // 'react'
55 | // ],
56 | // plugins: [
57 | // "transform-es2015-modules-commonjs",
58 | // "transform-async-to-generator",
59 | // ]
60 | // },
61 | }, {
62 | test: /\.json$/,
63 | loader: 'json-loader',
64 | },
65 | ],
66 | },
67 | plugins: [
68 | new webpack.DefinePlugin({
69 | 'process.env': {
70 | NODE_ENV: JSON.stringify('production')
71 | }
72 | }),
73 | new webpack.BannerPlugin('require("source-map-support").install();',
74 | { raw: true, entryOnly: false }),
75 | new webpack.optimize.OccurrenceOrderPlugin(),
76 | new webpack.optimize.DedupePlugin(),
77 | // new webpack.BannerPlugin('require("source-map-support").install();',
78 | // { raw: true, entryOnly: false }),
79 | new webpack.IgnorePlugin(/(\.(css|less)$)|zepto/)
80 | ],
81 | };
82 |
83 |
--------------------------------------------------------------------------------