<commit_before>Ext.define('MilestoneApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',

    launch: function() {
      this._loadMilestones();
      this._loadPortfolioItemTypes();
      window.mapp = this;
    },
   _loadMilestones: function() {
        Ext.create('Rally.data.WsapiDataStore', {
              autoLoad : true,
              limit : "Infinity",
              model : "Milestone",
              fetch : ["Name", "TargetDate"],
              listeners : {
                  scope : this,
                  load : function(store, data) {
                      this.milestones = store;
                      if(this.pfstore) this._onDataReady();
                  }
              }
          });
    },
    _loadPortfolioItemTypes: function() {
      //Usually PortfolioItem/Feature, but the name
      //could be changed in workspace so we need to
      //dynamically determine lowest level

       var self = this;
       Ext.create('Rally.data.wsapi.Store', {
        model: 'TypeDefinition',
        autoLoad:true,
        filters: [{
          property: "TypePath",
          operator: "contains",
          value: "PortfolioItem/"
        }],
        listeners: {
            load: function(store, data, success) {
              self._loadPortfolioItems(data[0].data.TypePath);
            }
        }
      });
    },
    _loadPortfolioItems: function(typePath) {

        Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
            models: [typePath],
            autoLoad: true,
            enableHierarchy: false,
            context: null,
            sortOnLoad: false,
            sorters: [{
              property: 'Name',
              direction: 'ASC'
            }],
            filters: [
            {
              property: 'Milestones.ObjectID',
              operator: "!=",
              value: null
            }],
            listeners: {
                load: this._onDataLoaded,
                scope: this
            },
            getState: function() {
              return {};
            },
            applyState: function() {

            }
        }).then({
            success: this._onStoreBuilt.bind(this, typePath),
            scope: this
        });
    },
    _onDataLoaded: function(store, node, data) {
      this.pfstore = store;
      if(this.milestones) this._onDataReady();

    },
    _onDataReady: function() {
      var self = this;
      //window.pfstore = this.pfstore;
      _.map(this.pfstore.getTopLevelNodes(), function(record) {
        record.self.addField('DaysLate');
        record.self.addField('Milestone');
        record.self.addField('TargetDate');

        var milestone = self._findFirstMilestone(record.get("Milestones"));
        if(milestone) {

          var plannedEndDate = record.get("PlannedEndDate");
          var targetDate = milestone.get("TargetDate");
          // TODO: Date format can be changed in workspace settings
          // should use same format
          var targetDateString = moment(targetDate).format("YYYY-MM-DD");
          var plannedEndDateString = moment(plannedEndDate).format("YYYY-MM-DD");
          record.set("Milestone", milestone.data.Name);
          record.set("TargetDate", targetDateString);

          var daysLate = moment(plannedEndDate).diff(moment(targetDate), 'days') + 1;
          //TODO: plannedEndDate is just before midnight and results in
          // daysLate 1 if plannedDate and targetDate are the same.
          // as workaround just check for that condition explicitly
          if( daysLate > 0 && plannedEndDateString != targetDateString) {
            record.set("DaysLate", daysLate);
          } else {
            // record.remove() will flag record as removed and delete on server
            // when any other change is made.
            //pfstore.tree.root.childNodes = _.remove(pfstore.tree.root.childNodes, record);
          }
        }

      });
    },

    _findFirstMilestone: function(pfmilestones) {
      var refs = _.pluck(pfmilestones._tagsNameArray, "_ref");

      var mdata = _.filter(this.milestones.data.items, function(milestone) {
        return _.contains(refs, milestone.data._ref);
      });
      var sorted = _.sortBy(mdata, function(milestone) {
        return milestone.data.TargetDate;
      });
      return _.first(sorted);
    },
    _onStoreBuilt: function(modelName, store) {

        var modelNames = [modelName],
            context = this.getContext();

        store.model.addField({name: "Milestone"});
        store.model.addField({name: "TargetDate"});
        store.model.addField({name: "DaysLate"});

        this.gridBoard = this.add({
            xtype: 'rallygridboard',
            context: context,
            modelNames: modelNames,
            toggleState: 'grid',
            stateful: false,
//            plugins: [
//                {
//                    ptype: 'rallygridboardfieldpicker',
//                    headerPosition: 'right',
//                    modelNames: modelNames,
//                    stateful: true,
//                    stateId: context.getScopedStateId('milestone-app')
//                }
//            ],
            gridConfig: {
                store: store,
                expandAllInColumnHeaderEnabled: true,
                columnCfgs: [
                    'Name',
                    'Project',
                    'Parent',
                    'Owner',
                    'PlannedEndDate',
                    'Milestones',
                    {
                      text: 'First Target Date',
                      dataIndex: 'TargetDate'
                    },
                    {
                      text: 'Days Late',
                      dataIndex: 'DaysLate'
                    }

                ],
                plugins: [
                {
                  ptype: "rallytreegridexpandedrowpersistence",
                  enableExpandLoadingMask:false
                }],
                getState: function() {
                  return {};
                },
                applyState: function() {

                }

            },
            height: this.getHeight()

        });
    }

});
<commit_msg>Sort on Days late after data has loaded<commit_after>Ext.define('MilestoneApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',

    launch: function() {
      this._loadMilestones();
      this._loadPortfolioItemTypes();
      window.mapp = this;
    },
   _loadMilestones: function() {
        Ext.create('Rally.data.WsapiDataStore', {
              autoLoad : true,
              limit : "Infinity",
              model : "Milestone",
              fetch : ["Name", "TargetDate"],
              listeners : {
                  scope : this,
                  load : function(store, data) {
                      this.milestones = store;
                      if(this.pfstore) this._onDataReady();
                  }
              }
          });
    },
    _loadPortfolioItemTypes: function() {
      //Usually PortfolioItem/Feature, but the name
      //could be changed in workspace so we need to
      //dynamically determine lowest level

       var self = this;
       Ext.create('Rally.data.wsapi.Store', {
        model: 'TypeDefinition',
        autoLoad:true,
        filters: [{
          property: "TypePath",
          operator: "contains",
          value: "PortfolioItem/"
        }],
        listeners: {
            load: function(store, data, success) {
              self._loadPortfolioItems(data[0].data.TypePath);
            }
        }
      });
    },
    _loadPortfolioItems: function(typePath) {

        Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
            models: [typePath],
            autoLoad: true,
            enableHierarchy: false,
            context: null,
            sortOnLoad: false,
            filters: [
            {
              property: 'Milestones.ObjectID',
              operator: "!=",
              value: null
            }],
            listeners: {
                load: this._onDataLoaded,
                scope: this
            }
        }).then({
            success: this._onStoreBuilt.bind(this, typePath),
            scope: this
        });
    },
    _onDataLoaded: function(store, node, data) {
      this.pfstore = store;
      if(this.milestones) this._onDataReady();

    },
    _onDataReady: function() {
      var self = this;
      //window.pfstore = this.pfstore;
      _.map(this.pfstore.getTopLevelNodes(), function(record) {
        record.self.addField('DaysLate');
        record.self.addField('Milestone');
        record.self.addField('TargetDate');

        var milestone = self._findFirstMilestone(record.get("Milestones"));
        if(milestone) {

          var plannedEndDate = record.get("PlannedEndDate");
          var targetDate = milestone.get("TargetDate");
          // TODO: Date format can be changed in workspace settings
          // should use same format
          var targetDateString = moment(targetDate).format("YYYY-MM-DD");
          var plannedEndDateString = moment(plannedEndDate).format("YYYY-MM-DD");
          record.set("Milestone", milestone.data.Name);
          record.set("TargetDate", targetDateString);

          var daysLate = moment(plannedEndDate).diff(moment(targetDate), 'days') + 1;
          //TODO: plannedEndDate is just before midnight and results in
          // daysLate 1 if plannedDate and targetDate are the same.
          // as workaround just check for that condition explicitly
          if( daysLate > 0 && plannedEndDateString != targetDateString) {
            record.set("DaysLate", daysLate);
          } else {
            // record.remove() will flag record as removed and delete on server
            // when any other change is made.
            //pfstore.tree.root.childNodes = _.remove(pfstore.tree.root.childNodes, record);
          }
        }

      });
      this.pfstore.sort({property: "DaysLate", direction: "DESC"});
    },

    _findFirstMilestone: function(pfmilestones) {
      var refs = _.pluck(pfmilestones._tagsNameArray, "_ref");

      var mdata = _.filter(this.milestones.data.items, function(milestone) {
        return _.contains(refs, milestone.data._ref);
      });
      var sorted = _.sortBy(mdata, function(milestone) {
        return milestone.data.TargetDate;
      });
      return _.first(sorted);
    },
    _onStoreBuilt: function(modelName, store) {

        var modelNames = [modelName],
            context = this.getContext();

        store.model.addField({name: "Milestone"});
        store.model.addField({name: "TargetDate"});
        store.model.addField({name: "DaysLate"});

        this.gridBoard = this.add({
            xtype: 'rallygridboard',
            context: context,
            modelNames: modelNames,
            toggleState: 'grid',
            stateful: false,
//            plugins: [
//                {
//                    ptype: 'rallygridboardfieldpicker',
//                    headerPosition: 'right',
//                    modelNames: modelNames,
//                    stateful: true,
//                    stateId: context.getScopedStateId('milestone-app')
//                }
//            ],
            gridConfig: {
                store: store,
                expandAllInColumnHeaderEnabled: true,
                columnCfgs: [
                    'Name',
                    'Project',
                    'Parent',
                    'Owner',
                    'PlannedEndDate',
                    'Milestones',
                    {
                      text: 'First Target Date',
                      dataIndex: 'TargetDate'
                    },
                    {
                      text: 'Days Late',
                      dataIndex: 'DaysLate'
                    }

                ],
                plugins: [
                {
                  ptype: "rallytreegridexpandedrowpersistence",
                  enableExpandLoadingMask:false
                }],
                getState: function() {
                  return {};
                },
                applyState: function() {

                }

            },
            height: this.getHeight()

        });
    }

});
<|endoftext|>


<commit_before>'use strict';

const stringUtils = require('ember-cli-string-utils');
const validComponentName = require('ember-cli-valid-component-name');
const normalizeEntityName = require('ember-cli-normalize-entity-name');

module.exports = {
  description: 'Generates a component. Name must contain a hyphen.',

  normalizeEntityName(entityName) {
    return validComponentName(normalizeEntityName(entityName));
  },

  fileMapTokens() {
    return {
      __name__(options) {
        return options.dasherizedModuleName;
      },
    };
  },

  locals(options) {
    let className = stringUtils.classify(options.entity.name);
    return { className };
  },
};
<commit_msg>blueprints: Add "Component" suffix to generated class name<commit_after>'use strict';

const stringUtils = require('ember-cli-string-utils');
const validComponentName = require('ember-cli-valid-component-name');
const normalizeEntityName = require('ember-cli-normalize-entity-name');

module.exports = {
  description: 'Generates a component. Name must contain a hyphen.',

  normalizeEntityName(entityName) {
    return validComponentName(normalizeEntityName(entityName));
  },

  fileMapTokens() {
    return {
      __name__(options) {
        return options.dasherizedModuleName;
      },
    };
  },

  locals(options) {
    let className = `${stringUtils.classify(options.entity.name)}Component`;
    return { className };
  },
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { connect } from 'react-redux';
import selectBook from '../actions/index';
import { bindActionCreators } from 'redux';

class BookList extends Component {
  renderList() {
    return this.props.books.map((book) => {
      return (

 this.props.selectBook(book)}
          className="list-group-item">
          {book.title}

      );
    });
  }

  render() {
    return (

        {this.renderList()}

    )
  }
}

// Whatever is returned will show up as props
// inside of BookList
function mapStateToProps(state) {
    // Here, State refers to application state.
    // so if u use like : return { fdacda : 12r32eq}
    // we can have this.props.fdacda and get 12r32eq as reture

    return {
        books: state.books
    };
}

// Anything returned form this function will end up as props
// on the BookList container
function mapDispatchToProps(dispatch) {
  // Whenever selectBook is called, the result should be passed
  // to all of our reducers by the funnal disaptch
  return bindActionCreators({ selectBook: selectBook }, dispatch);
}

// Promote BookList from a component to a container - it needs to know
// about this new dispatch method, selectBook. Make it available
// as a prop.
export default connect(mapStateToProps, mapDispatchToProps)(BookList);
<commit_msg>new way for test connect<commit_after>import React, { Component } from 'react';
import { connect } from 'react-redux';
import selectBook from '../actions/index';
import { bindActionCreators } from 'redux';

class BookList extends Component {
  renderList() {
    return this.props.books.map((book) => {
      return (

 this.props.selectBook(book)}
          className="list-group-item">
          {book.title}

      );
    });
  }

  render() {
    return (

        {this.renderList()}

    )
  }
}

// Whatever is returned will show up as props
// inside of BookList
function mapStateToProps(state) {
    // Here, State refers to application state.
    // so if u use like : return { fdacda : 12r32eq}
    // we can have this.props.fdacda and get 12r32eq as reture

    return {
        books: state.books
    };
}

// Anything returned form this function will end up as props
// on the BookList container
function mapDispatchToProps(dispatch) {
  // Whenever selectBook is called, the result should be passed
  // to all of our reducers by the funnal disaptch
  return bindActionCreators({ selectBook }, dispatch);
}

// Promote BookList from a component to a container - it needs to know
// about this new dispatch method, selectBook. Make it available
// as a prop.

// export default connect(mapStateToProps, mapDispatchToProps)(BookList);
export default connect(mapStateToProps, { selectBook })(BookList);
<|endoftext|>


<commit_before>module.exports = function(grunt, config, parameters, done) {
	var zipUrl = parameters.releaseSourceZip || 'https://github.com/concrete5/concrete5/archive/release/5.7.5.10.zip';
	var workFolder = parameters.releaseWorkFolder || './release';
	function endForError(e) {
		process.stderr.write(e.message || e);
		done(false);
	}
	try {
		var fs = require('fs'),
			path = require('path')
			download = require('download'),
			c5fs = require('../../libraries/fs'),
			shell = require('shelljs');
		if(c5fs.isDirectory(workFolder)) {
			process.stdout.write('Removing working folder... ');
			shell.rm('-rf', workFolder);
			if(c5fs.isDirectory(workFolder)) {
				throw new Error('Unable to remove ' + workFolder);
			}
			process.stdout.write('done.\n')
		}
		fs.mkdir(workFolder);
		process.stdout.write('Downloading & unzipping archive... ');
		var stream = download(
			zipUrl,
			workFolder,
			{
				extract: true
			}
		);
		stream.on('close', function() {
			process.stdout.write('done.\n');
			var extractedFolder = null;
			fs.readdirSync(workFolder).forEach(function(item) {
				if(item.indexOf('.') !== 0) {
					if(extractedFolder === null) {
						extractedFolder = item;
					}
					else {
						throw new Error('Multiple items in the root of the extract archive!');
					}
				}
			});
			if(extractedFolder === null) {
				throw new Error('No items extracted!');
			}
			fs.renameSync(path.join(workFolder, extractedFolder), path.join(workFolder, 'source'));
			done();
		});
	}
	catch(e) {
		endForError(e);
		return;
	}
};<commit_msg>updating build<commit_after>module.exports = function(grunt, config, parameters, done) {
	var zipUrl = parameters.releaseSourceZip || 'https://github.com/concrete5/concrete5/archive/release/5.7.5.11.zip';
	var workFolder = parameters.releaseWorkFolder || './release';
	function endForError(e) {
		process.stderr.write(e.message || e);
		done(false);
	}
	try {
		var fs = require('fs'),
			path = require('path')
			download = require('download'),
			c5fs = require('../../libraries/fs'),
			shell = require('shelljs');
		if(c5fs.isDirectory(workFolder)) {
			process.stdout.write('Removing working folder... ');
			shell.rm('-rf', workFolder);
			if(c5fs.isDirectory(workFolder)) {
				throw new Error('Unable to remove ' + workFolder);
			}
			process.stdout.write('done.\n')
		}
		fs.mkdir(workFolder);
		process.stdout.write('Downloading & unzipping archive... ');
		var stream = download(
			zipUrl,
			workFolder,
			{
				extract: true
			}
		);
		stream.on('close', function() {
			process.stdout.write('done.\n');
			var extractedFolder = null;
			fs.readdirSync(workFolder).forEach(function(item) {
				if(item.indexOf('.') !== 0) {
					if(extractedFolder === null) {
						extractedFolder = item;
					}
					else {
						throw new Error('Multiple items in the root of the extract archive!');
					}
				}
			});
			if(extractedFolder === null) {
				throw new Error('No items extracted!');
			}
			fs.renameSync(path.join(workFolder, extractedFolder), path.join(workFolder, 'source'));
			done();
		});
	}
	catch(e) {
		endForError(e);
		return;
	}
};<|endoftext|>


<commit_before>
var config = {
  server_port: 5000,
  server_opts: {}
};

var server = require('http').Server();
var serverio = require('socket.io').listen(server, config.server_opts);
server.listen(config.server_port);

var players = [];

var red_cards = require('../data/red.json'),
  green_cards = require('../data/green.json');

serverio.of('/game').on('connection', function(socket) {
  // TODO: add socket

  socket.on('disconnect', function() {
    // TODO: remove socket
  });

  socket.on('authme', function() {

  });
});
<commit_msg>Use json file in reading<commit_after>
var config = {
  server_port: 5000,
  server_opts: {}
};

var server = require('http').Server();
var serverio = require('socket.io').listen(server, config.server_opts);
server.listen(config.server_port);

var players = [];

var data = require('../data/apples.json');
var red = data.red,
  green = data.green;

serverio.of('/game').on('connection', function(socket) {
  // TODO: add socket

  socket.on('disconnect', function() {
    // TODO: remove socket
  });

  socket.on('authme', function() {

  });
});
<|endoftext|>


<commit_before>/**
 * React Starter Kit for Firebase and GraphQL
 * https://github.com/kriasoft/react-firebase-starter
 * Copyright (c) 2015-present Kriasoft | MIT License
 */

/* @flow */

import React from 'react';
import UniversalRouter from 'universal-router/main.js';

// The list of all application routes where each route contains a URL path string (pattern),
// the list of components to load asynchroneously (chunks), data requirements (GraphQL query),
// and a render() function which shapes the result to be passed into the top-level (App) component.
// For more information visit https://github.com/kriasoft/universal-router
const routes = [
  {
    path: '',
    components: () => [import(/* webpackChunkName: 'home' */ './Home')],
    render: ({ user, components: [Home] }) => ({
      title: 'React Starter Kit for Firebase and GraphQL',
      body: <Home user={user} />,
    }),
  },
  {
    path: '/account',
    components: () => [import(/* webpackChunkName: 'Account' */ './Account')],
    render: ({ user, components: [Account] }) => ({
      title: 'My Account • React Firebase Starter',
      body: <Account user={user} />,
    }),
  },
  {
    path: '/about',
    components: () => [import(/* webpackChunkName: 'about' */ './About')],
    render: ({ user, components: [About] }) => ({
      title: 'About Us • React Firebase Starter',
      body: <About user={user} />,
    }),
  },
  {
    path: '/privacy',
    components: () => [import(/* webpackChunkName: 'privacy' */ './Privacy')],
    render: ({ user, components: [Privacy] }) => ({
      title: 'Privacy Policy • React Firebase Starter',
      body: <Privacy user={user} />,
    }),
  },
];

function resolveRoute(ctx) {
  const { route } = ctx;

  if (!route.render) {
    return ctx.next();
  }

  return Promise.all(route.components()).then(components =>
    ctx.render({
      user: ctx.user,
      location: ctx.location,
      route: route.render({
        user: ctx.user,
        location: ctx.ocation,
        components: components.map(x => x.default),
      }),
    }),
  );
}

export default new UniversalRouter(routes, { resolveRoute });
<commit_msg>Fix a typo in src/routes/index.js (#276)<commit_after>/**
 * React Starter Kit for Firebase and GraphQL
 * https://github.com/kriasoft/react-firebase-starter
 * Copyright (c) 2015-present Kriasoft | MIT License
 */

/* @flow */

import React from 'react';
import UniversalRouter from 'universal-router/main.js';

// The list of all application routes where each route contains a URL path string (pattern),
// the list of components to load asynchroneously (chunks), data requirements (GraphQL query),
// and a render() function which shapes the result to be passed into the top-level (App) component.
// For more information visit https://github.com/kriasoft/universal-router
const routes = [
  {
    path: '',
    components: () => [import(/* webpackChunkName: 'home' */ './Home')],
    render: ({ user, components: [Home] }) => ({
      title: 'React Starter Kit for Firebase and GraphQL',
      body: <Home user={user} />,
    }),
  },
  {
    path: '/account',
    components: () => [import(/* webpackChunkName: 'Account' */ './Account')],
    render: ({ user, components: [Account] }) => ({
      title: 'My Account • React Firebase Starter',
      body: <Account user={user} />,
    }),
  },
  {
    path: '/about',
    components: () => [import(/* webpackChunkName: 'about' */ './About')],
    render: ({ user, components: [About] }) => ({
      title: 'About Us • React Firebase Starter',
      body: <About user={user} />,
    }),
  },
  {
    path: '/privacy',
    components: () => [import(/* webpackChunkName: 'privacy' */ './Privacy')],
    render: ({ user, components: [Privacy] }) => ({
      title: 'Privacy Policy • React Firebase Starter',
      body: <Privacy user={user} />,
    }),
  },
];

function resolveRoute(ctx) {
  const { route } = ctx;

  if (!route.render) {
    return ctx.next();
  }

  return Promise.all(route.components()).then(components =>
    ctx.render({
      user: ctx.user,
      location: ctx.location,
      route: route.render({
        user: ctx.user,
        location: ctx.location,
        components: components.map(x => x.default),
      }),
    }),
  );
}

export default new UniversalRouter(routes, { resolveRoute });
<|endoftext|>


<commit_before>import React from 'react'
import { Route, IndexRoute, Router } from 'dva/router'
import CoreLayout from '../containers/layout'
import HotGoods from 'views/Hotgoods/page'
import MyCustom from 'views/MyCustom/page'
import SelfSupport from 'views/SelfSupport/page'
import GatherGoods from 'views/GatherGoods/page'
import GatherStore from 'views/GatherStore/page'
import ShopActivity from 'views/ShopActivity/page'

import Order from "views/Order/page"
import BannerEntry from "views/Activity/bannerEntry"
import Banner01 from "views/Activity/banner01"
import ChannelEntry from "views/Activity/channelEntry"
import bannerDetail from "views/Activity/bannerDetail"
import IconDoc from "views/IconDoc/page"
import FlexLayout from "views/FlexLayout/page"

export default function (ref) {
  return (
    <Router history={ref.history}>
      <Route path='/' component={CoreLayout} name="有好货">
        <IndexRoute component={GatherGoods} name="聚好货"/>
        <Route path='/FlexLayout' component={FlexLayout} name="布局" />
        <Route path='/HotGoods' component={HotGoods} name="热卖好货" />
        <Route path='/MyCustom' component={MyCustom} name="我的定制" />
        <Route path='/SelfSupport' component={SelfSupport} name="钱宝自营" />
        <Route path='/ShopActivity' component={ShopActivity} name="店铺活动页"/>
        <Route path='/GatherGoods' component={GatherGoods} name="聚好货" />
        <Route path='/GatherStore' component={GatherStore} name="聚好店"/>
        <Route path='/Order' component={Order} name="我的好货"/>
        <Route path='/BannerEntry' component={BannerEntry} name="活动页面"/>
        <Route path='/Ju/:id' component={Banner01} name="聚好货页面"/>
        <Route path='/bannerDetail/:id' component={bannerDetail} name="Banner详细页面" />
        <Route path='/ChannelEntry/1' component={ChannelEntry} name="女神学穿搭" />
        <Route path='/ChannelEntry/2' component={ChannelEntry} name="个护化妆" />
        <Route path='/ChannelEntry/3' component={ChannelEntry} name="运动户外" />
        <Route path='/ChannelEntry/4' component={ChannelEntry} name="创意电器" />
        <Route path='/ChannelEntry/5' component={ChannelEntry} name="母婴联合馆" />
        <Route path='/ChannelEntry/6' component={ChannelEntry} name="焕然居家" />
        <Route path='/IconDoc' component={IconDoc} name="Icon Document" />

      </Route>
    </Router>
  )
}
<commit_msg>router update<commit_after>import React from 'react'
import { Route, IndexRoute, Router } from 'dva/router'
import CoreLayout from '../containers/layout'
import HotGoods from 'views/Hotgoods/page'
import MyCustom from 'views/MyCustom/page'
import SelfSupport from 'views/SelfSupport/page'
import GatherGoods from 'views/GatherGoods/page'
import GatherStore from 'views/GatherStore/page'
import ShopActivity from 'views/ShopActivity/page'

import Order from "views/Order/page"
import BannerEntry from "views/Activity/bannerEntry"
import Banner01 from "views/Activity/banner01"
import ChannelEntry from "views/Activity/channelEntry"
import bannerDetail from "views/Activity/bannerDetail"
import SignIn from "views/Activity/signIn"
import IconDoc from "views/IconDoc/page"
import FlexLayout from "views/FlexLayout/page"

export default function (ref) {
  return (
    <Router history={ref.history}>
      <Route path='/' component={CoreLayout} name="有好货">
        <IndexRoute component={GatherGoods} name="聚好货"/>
        <Route path='/FlexLayout' component={FlexLayout} name="布局" />
        <Route path='/HotGoods' component={HotGoods} name="热卖好货" />
        <Route path='/MyCustom' component={MyCustom} name="我的定制" />
        <Route path='/SelfSupport' component={SelfSupport} name="钱宝自营" />
        <Route path='/ShopActivity' component={ShopActivity} name="店铺活动页"/>
        <Route path='/GatherGoods' component={GatherGoods} name="聚好货" />
        <Route path='/GatherStore' component={GatherStore} name="聚好店"/>
        <Route path='/Order' component={Order} name="我的好货"/>
        <Route path='/BannerEntry' component={BannerEntry} name="活动页面"/>
        <Route path='/Ju/:id' component={Banner01} name="聚好货页面"/>
        <Route path='/bannerDetail/:id' component={bannerDetail} name="Banner详细页面" />
        <Route path='/SignIn' component={SignIn} name="今日清单" />
        <Route path='/ChannelEntry/1' component={ChannelEntry} name="女神学穿搭" />
        <Route path='/ChannelEntry/2' component={ChannelEntry} name="个护化妆" />
        <Route path='/ChannelEntry/3' component={ChannelEntry} name="运动户外" />
        <Route path='/ChannelEntry/4' component={ChannelEntry} name="创意电器" />
        <Route path='/ChannelEntry/5' component={ChannelEntry} name="母婴联合馆" />
        <Route path='/ChannelEntry/6' component={ChannelEntry} name="焕然居家" />
        <Route path='/IconDoc' component={IconDoc} name="Icon Document" />

      </Route>
    </Router>
  )
}
<|endoftext|>


<commit_before>'use strict';

const express = require('express');
const cors = require('cors');
const MockCtrl = require('../controllers/MockCtrl');

module.exports = function({Configuration, Logger, app}) {
  // Cross-domain management
  app.use(cors());

  // Index route
  app.use(express.static('./public'));

  // Mocks route
  app.use(function(req, res) {
    new MockCtrl({Configuration, Logger}).buildResponse(req, res);
  });
};
<commit_msg>Fix public route not working correctly in some cases<commit_after>'use strict';

const express = require('express');
const cors = require('cors');
const path = require('path');
const MockCtrl = require('../controllers/MockCtrl');

module.exports = function({Configuration, Logger, app}) {
  // Cross-domain management
  app.use(cors());

  // Index route
  app.use(express.static(path.join(__dirname, '../../public')));

  // Mocks route
  app.use(function(req, res) {
    new MockCtrl({Configuration, Logger}).buildResponse(req, res);
  });
};
<|endoftext|>


<commit_before>const express = require('express');
/* eslint-disable new-cap */
const router = express.Router();

const slackAPI = require('../models/slack');
const twilioAPI = require('../models/twilio');

router.post('/slack', slackAPI.sendToSlack);
router.post('/twilio', twilioAPI.sendToTwilio);

module.exports = router;
<commit_msg>Patches bug with routes<commit_after>const express = require('express');
/* eslint-disable new-cap */
const router = express.Router();

const slackAPI = require('../models/slack');
const twilioAPI = require('../models/twilio');

router.post('/twilio', slackAPI.sendToSlack);
router.post('/slack', twilioAPI.sendToTwilio);

module.exports = router;
<|endoftext|>


<commit_before>import { updateChatSession } from '../actionCreators';
import { tripDialogReply } from '../tripDialog';
import { WitDriver } from 'calamars';
const { getEntity, getEntities, getEntityValue, getEntityMeta } = WitDriver;

const placesConfidenceThreshold = 0.7;

const extractEntities = outcomes => {
    const unknownPlace = getEntity(outcomes, 'places');
    const unknownPlaces = getEntities(outcomes, 'places');
    const origin = getEntity(outcomes, 'origin');
    const origins = getEntities(outcomes, 'origin');
    const originMeta = getEntityMeta(origin);
    const destination = getEntity(outcomes, 'destination');
    const destinationMeta = getEntityMeta(destination);
    const dateTime = getEntity(outcomes, 'datetime');
    const timeFilter = dateTime ? {
        from: !dateTime.from ? dateTime : dateTime.from,
        to: dateTime.to ? dateTime.to : null
    } : null;
    return {
        unknownPlace,
        unknownPlaces,
        origin,
        origins,
        originMeta,
        destination,
        destinationMeta,
        timeFilter
    };
};

const routes = [[
    outcomes => getEntityValue(outcomes, 'trip') === 'info',
    (outcomes, { store, chat } = {}) => {
        const {
            origin,
            origins,
            originMeta,
            destination,
            destinationMeta,
            unknownPlace,
            unknownPlaces,
            timeFilter
        } = extractEntities(outcomes);
        const context = chat && chat.session ? chat.session : {};
        let nextContext = Object.assign({}, context);
        nextContext.timeFilter = timeFilter;
        if (destination && destination.confidence >= placesConfidenceThreshold) {
            nextContext.destination = destination.value;
            nextContext.destinationMeta = destinationMeta;
        }
        if (origin && origin.confidence >= placesConfidenceThreshold) {
            nextContext.origin = origin.value;
            nextContext.originMeta = originMeta;
            if (!destination) {
                if (
                    origins && origins.length > 1 &&
                    origins[1].confidence >= placesConfidenceThreshold
                ) {
                    nextContext.destination = origins[1].value;
                    nextContext.destinationMeta = getEntityMeta(origins[1]);
                } else if (unknownPlace) {
                    nextContext.destination = unknownPlace.value;
                    nextContext.destinationMeta = getEntityMeta(unknownPlace);
                }
            }
        }
        if (!origin && !destination && unknownPlaces && unknownPlaces.length > 1) {
            console.log('[issue #25]: 2 places and no role');
            nextContext.origin = unknownPlaces[0].value;
            nextContext.originMeta = getEntityMeta(unknownPlaces[0]);
            nextContext.destination = unknownPlaces[1].value;
            nextContext.destinationMeta = getEntityMeta(unknownPlaces[1]);
        }
        if (unknownPlaces && nextContext.destination && !nextContext.origin) {
            nextContext.origin = unknownPlaces[0].value;
            nextContext.originMeta = getEntityMeta(unknownPlaces[0]);
        }
        if (
            (unknownPlaces && nextContext.origin && !nextContext.destination)
            || (unknownPlaces && !nextContext.origin && !nextContext.destination)
        ) {
            nextContext.destination = unknownPlaces[0].value;
            nextContext.destinationMeta = getEntityMeta(unknownPlaces[0]);
        }
        if (store) {
            store.dispatch(updateChatSession({
                chat: { ...chat, session: nextContext }
            }));
        }
        return tripDialogReply(nextContext);
    }
], [
    outcomes => (getEntityValue(outcomes, 'trip') !== 'info' && (
        getEntityValue(outcomes, 'places') ||
        getEntityValue(outcomes, 'origin') ||
        getEntityValue(outcomes, 'destination'
    ))),
    (outcomes, { store, chat } = {}) => {
        const context = chat && chat.session ? chat.session : {};
        const {
            unknownPlace,
            origin,
            destination,
            timeFilter
        } = extractEntities(outcomes);
        const place = unknownPlace || origin || destination;
        const placeMeta = getEntityMeta(place);
        let nextContext = Object.assign({}, context);
        nextContext.timeFilter = timeFilter;
        if (origin && destination) {
            console.log('[issue #24, comment 1] has origin and destination');
            nextContext.origin = origin.value;
            nextContext.originMeta = getEntityMeta(origin);
            nextContext.destination = destination.value;
            nextContext.destinationMeta = getEntityMeta(destination);
        }
        if (unknownPlace && destination) {
            console.log('[issue #24] has places with no role and destination');
            nextContext.origin = unknownPlace.value;
            nextContext.originMeta = getEntityMeta(unknownPlace);
            nextContext.destination = destination.value;
            nextContext.destinationMeta = getEntityMeta(destination);
        }
        if (nextContext.destination && !nextContext.origin) {
            nextContext.origin = place.value;
            nextContext.originMeta = placeMeta;
        } else if (
            (!nextContext.destination && nextContext.origin) ||
            (!nextContext.destination && !nextContext.origin)
        ) {
            nextContext.destination = place.value;
            if (placeMeta) {
                nextContext.destinationMeta = placeMeta;
            }
        }
        if (store) {
            store.dispatch(updateChatSession({
                chat: { ...chat, session: nextContext }
            }));
        }
        return tripDialogReply(nextContext);
    }
]];
export default routes;
<commit_msg>better handling of outcomes with places and no trip intent, fix #60 fix #21 fix #74<commit_after>import { updateChatSession } from '../actionCreators';
import { tripDialogReply } from '../tripDialog';
import { WitDriver } from 'calamars';
const { getEntity, getEntities, getEntityValue, getEntityMeta } = WitDriver;

const placesConfidenceThreshold = 0.7;

const extractEntities = outcomes => {
    const unknownPlace = getEntity(outcomes, 'places');
    const unknownPlaces = getEntities(outcomes, 'places');
    const origin = getEntity(outcomes, 'origin');
    const origins = getEntities(outcomes, 'origin');
    const originMeta = getEntityMeta(origin);
    const destination = getEntity(outcomes, 'destination');
    const destinationMeta = getEntityMeta(destination);
    const dateTime = getEntity(outcomes, 'datetime');
    const timeFilter = dateTime ? {
        from: !dateTime.from ? dateTime : dateTime.from,
        to: dateTime.to ? dateTime.to : null
    } : null;
    return {
        unknownPlace,
        unknownPlaces,
        origin,
        origins,
        originMeta,
        destination,
        destinationMeta,
        timeFilter
    };
};

const routes = [[
    outcomes => getEntityValue(outcomes, 'trip') === 'info',
    (outcomes, { store, chat } = {}) => {
        const {
            origin,
            origins,
            originMeta,
            destination,
            destinationMeta,
            unknownPlace,
            unknownPlaces,
            timeFilter
        } = extractEntities(outcomes);
        const context = chat && chat.session ? chat.session : {};
        let nextContext = Object.assign({}, context);
        if (timeFilter) {
            nextContext.timeFilter = timeFilter;
        }
        if (destination && destination.confidence >= placesConfidenceThreshold) {
            nextContext.destination = destination.value;
            nextContext.destinationMeta = destinationMeta;
        }
        if (origin && origin.confidence >= placesConfidenceThreshold) {
            nextContext.origin = origin.value;
            nextContext.originMeta = originMeta;
            if (!destination) {
                if (
                    origins && origins.length > 1 &&
                    origins[1].confidence >= placesConfidenceThreshold
                ) {
                    nextContext.destination = origins[1].value;
                    nextContext.destinationMeta = getEntityMeta(origins[1]);
                } else if (unknownPlace) {
                    nextContext.destination = unknownPlace.value;
                    nextContext.destinationMeta = getEntityMeta(unknownPlace);
                }
            }
        }
        if (!origin && !destination && unknownPlaces && unknownPlaces.length > 1) {
            console.log('[issue #25]: 2 places and no role');
            nextContext.origin = unknownPlaces[0].value;
            nextContext.originMeta = getEntityMeta(unknownPlaces[0]);
            nextContext.destination = unknownPlaces[1].value;
            nextContext.destinationMeta = getEntityMeta(unknownPlaces[1]);
        }
        if (unknownPlaces && nextContext.destination && !nextContext.origin) {
            nextContext.origin = unknownPlaces[0].value;
            nextContext.originMeta = getEntityMeta(unknownPlaces[0]);
        }
        if (
            (unknownPlaces && nextContext.origin && !nextContext.destination)
            || (unknownPlaces && !nextContext.origin && !nextContext.destination)
        ) {
            nextContext.destination = unknownPlaces[0].value;
            nextContext.destinationMeta = getEntityMeta(unknownPlaces[0]);
        }
        if (store) {
            store.dispatch(updateChatSession({
                chat: { ...chat, session: nextContext }
            }));
        }
        return tripDialogReply(nextContext);
    }
], [
    outcomes => {
        const {
            unknownPlace,
            origin,
            destination,
            timeFilter
        } = extractEntities(outcomes);
        const place = unknownPlace || origin || destination;
        const result = (
            (origin && destination) ||
            (unknownPlace && destination) ||
            place ||
            timeFilter
        );
        return result;
    },
    (outcomes, { store, chat } = {}) => {
        const context = chat && chat.session ? chat.session : {};
        const {
            unknownPlace,
            origin,
            destination,
            timeFilter
        } = extractEntities(outcomes);
        const place = unknownPlace || origin || destination;
        const placeMeta = getEntityMeta(place);
        let nextContext = Object.assign({}, context);
        if (timeFilter) {
            nextContext.timeFilter = timeFilter;
        }
        if (destination) {
            nextContext.destination = destination.value;
            nextContext.destinationMeta = getEntityMeta(destination);
        }
        if (origin) {
            nextContext.origin = origin.value;
            nextContext.originMeta = getEntityMeta(origin);
        }
        if (unknownPlace && destination) {
            console.log('[issue #24] has places with no role and destination');
            nextContext.origin = unknownPlace.value;
            nextContext.originMeta = getEntityMeta(unknownPlace);
        }
        if (nextContext.destination && !nextContext.origin && place) {
            nextContext.origin = place.value;
            nextContext.originMeta = placeMeta;
        } else {
            nextContext.destination = place.value;
            nextContext.destinationMeta = placeMeta;
        }
        if (store) {
            store.dispatch(updateChatSession({
                chat: { ...chat, session: nextContext }
            }));
        }
        return tripDialogReply(nextContext);
    }
]];
export default routes;
<|endoftext|>


<commit_before>const {Schema} = require("prosemirror-model")

// :: Object
//
//   doc:: NodeSpec The top level document node.
//
//   paragraph:: NodeSpec A plain paragraph textblock.
//
//   blockquote:: NodeSpec A blockquote wrapping one or more blocks.
//
//   horizontal_rule:: NodeSpec A horizontal rule.
//
//   heading:: NodeSpec A heading textblock, with a `level`
//   attribute that should hold the number 1 to 6.
//
//   code_block:: NodeSpec A code listing. Disallows marks or
//   non-text inline nodes by default.
//
//   text:: NodeSpec The text node.
//
//   image:: NodeSpec An inline image node. Supports `src`, `alt`, and
//   `href` attributes. The latter two default to the empty string.
//
//   hard_break:: NodeSpec A hard line break.
const nodes = {
  doc: {
    content: "block+"
  },

  paragraph: {
    content: "inline<_>*",
    group: "block",
    parseDOM: [{tag: "p"}],
    toDOM() { return ["p", 0] }
  },

  blockquote: {
    content: "block+",
    group: "block",
    parseDOM: [{tag: "blockquote"}],
    toDOM() { return ["blockquote", 0] }
  },

  horizontal_rule: {
    group: "block",
    parseDOM: [{tag: "hr"}],
    toDOM() { return ["div", ["hr"]] }
  },

  heading: {
    attrs: {level: {default: 1}},
    content: "inline<_>*",
    group: "block",
    parseDOM: [{tag: "h1", attrs: {level: 1}},
               {tag: "h2", attrs: {level: 2}},
               {tag: "h3", attrs: {level: 3}},
               {tag: "h4", attrs: {level: 4}},
               {tag: "h5", attrs: {level: 5}},
               {tag: "h6", attrs: {level: 6}}],
    toDOM(node) { return ["h" + node.attrs.level, 0] }
  },

  code_block: {
    content: "text*",
    group: "block",
    code: true,
    parseDOM: [{tag: "pre", preserveWhitespace: true}],
    toDOM() { return ["pre", ["code", 0]] }
  },

  text: {
    text: true,
    group: "inline",
    toDOM(node) { return node.text }
  },

  image: {
    inline: true,
    attrs: {
      src: {},
      alt: {default: ""},
      title: {default: ""}
    },
    group: "inline",
    draggable: true,
    parseDOM: [{tag: "img[src]", getAttrs(dom) {
      return {
        src: dom.getAttribute("src"),
        title: dom.getAttribute("title"),
        alt: dom.getAttribute("alt")
      }
    }}],
    toDOM(node) { return ["img", node.attrs] }
  },

  hard_break: {
    inline: true,
    group: "inline",
    selectable: false,
    isBR: true,
    parseDOM: [{tag: "br"}],
    toDOM() { return ["br"] }
  }
}
exports.nodes = nodes

// :: Object
//
//  em:: MarkSpec An emphasis mark.
//
//  strong:: MarkSpec A strong mark.
//
//  link:: MarkSpec A link. Has `href` and `title` attributes.
//  `title` defaults to the empty string.
//
//  code:: MarkSpec Code font mark.
const marks = {
  em: {
    parseDOM: [{tag: "i"}, {tag: "em"},
               {style: "font-style", getAttrs: value => value == "italic" && null}],
    toDOM() { return ["em"] }
  },

  strong: {
    parseDOM: [{tag: "b"}, {tag: "strong"},
               {style: "font-weight", getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null}],
    toDOM() { return ["strong"] }
  },

  link: {
    attrs: {
      href: {},
      title: {default: ""}
    },
    parseDOM: [{tag: "a[href]", getAttrs(dom) {
      return {href: dom.getAttribute("href"), title: dom.getAttribute("title")}
    }}],
    toDOM(node) { return ["a", node.attrs] }
  },

  code: {
    parseDOM: [{tag: "code"}],
    toDOM() { return ["code"] }
  }
}
exports.marks = marks

// :: Schema
// This schema rougly corresponds to the document schema used by
// CommonMark, minus the list elements, which are defined in the
// [schema-list](#schema-list) module.
//
// To reuse elements from this schema, extend or read from its
// [`nodeSpec`](#model.Schema.nodeSpec) and
// [`markSpec`](#model.Schema.markSpec) properties.
const schema = new Schema({nodes, marks})
exports.schema = schema
<commit_msg>Drop isBR node property<commit_after>const {Schema} = require("prosemirror-model")

// :: Object
//
//   doc:: NodeSpec The top level document node.
//
//   paragraph:: NodeSpec A plain paragraph textblock.
//
//   blockquote:: NodeSpec A blockquote wrapping one or more blocks.
//
//   horizontal_rule:: NodeSpec A horizontal rule.
//
//   heading:: NodeSpec A heading textblock, with a `level`
//   attribute that should hold the number 1 to 6.
//
//   code_block:: NodeSpec A code listing. Disallows marks or
//   non-text inline nodes by default.
//
//   text:: NodeSpec The text node.
//
//   image:: NodeSpec An inline image node. Supports `src`, `alt`, and
//   `href` attributes. The latter two default to the empty string.
//
//   hard_break:: NodeSpec A hard line break.
const nodes = {
  doc: {
    content: "block+"
  },

  paragraph: {
    content: "inline<_>*",
    group: "block",
    parseDOM: [{tag: "p"}],
    toDOM() { return ["p", 0] }
  },

  blockquote: {
    content: "block+",
    group: "block",
    parseDOM: [{tag: "blockquote"}],
    toDOM() { return ["blockquote", 0] }
  },

  horizontal_rule: {
    group: "block",
    parseDOM: [{tag: "hr"}],
    toDOM() { return ["div", ["hr"]] }
  },

  heading: {
    attrs: {level: {default: 1}},
    content: "inline<_>*",
    group: "block",
    parseDOM: [{tag: "h1", attrs: {level: 1}},
               {tag: "h2", attrs: {level: 2}},
               {tag: "h3", attrs: {level: 3}},
               {tag: "h4", attrs: {level: 4}},
               {tag: "h5", attrs: {level: 5}},
               {tag: "h6", attrs: {level: 6}}],
    toDOM(node) { return ["h" + node.attrs.level, 0] }
  },

  code_block: {
    content: "text*",
    group: "block",
    code: true,
    parseDOM: [{tag: "pre", preserveWhitespace: true}],
    toDOM() { return ["pre", ["code", 0]] }
  },

  text: {
    text: true,
    group: "inline",
    toDOM(node) { return node.text }
  },

  image: {
    inline: true,
    attrs: {
      src: {},
      alt: {default: ""},
      title: {default: ""}
    },
    group: "inline",
    draggable: true,
    parseDOM: [{tag: "img[src]", getAttrs(dom) {
      return {
        src: dom.getAttribute("src"),
        title: dom.getAttribute("title"),
        alt: dom.getAttribute("alt")
      }
    }}],
    toDOM(node) { return ["img", node.attrs] }
  },

  hard_break: {
    inline: true,
    group: "inline",
    selectable: false,
    parseDOM: [{tag: "br"}],
    toDOM() { return ["br"] }
  }
}
exports.nodes = nodes

// :: Object
//
//  em:: MarkSpec An emphasis mark.
//
//  strong:: MarkSpec A strong mark.
//
//  link:: MarkSpec A link. Has `href` and `title` attributes.
//  `title` defaults to the empty string.
//
//  code:: MarkSpec Code font mark.
const marks = {
  em: {
    parseDOM: [{tag: "i"}, {tag: "em"},
               {style: "font-style", getAttrs: value => value == "italic" && null}],
    toDOM() { return ["em"] }
  },

  strong: {
    parseDOM: [{tag: "b"}, {tag: "strong"},
               {style: "font-weight", getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null}],
    toDOM() { return ["strong"] }
  },

  link: {
    attrs: {
      href: {},
      title: {default: ""}
    },
    parseDOM: [{tag: "a[href]", getAttrs(dom) {
      return {href: dom.getAttribute("href"), title: dom.getAttribute("title")}
    }}],
    toDOM(node) { return ["a", node.attrs] }
  },

  code: {
    parseDOM: [{tag: "code"}],
    toDOM() { return ["code"] }
  }
}
exports.marks = marks

// :: Schema
// This schema rougly corresponds to the document schema used by
// CommonMark, minus the list elements, which are defined in the
// [schema-list](#schema-list) module.
//
// To reuse elements from this schema, extend or read from its
// [`nodeSpec`](#model.Schema.nodeSpec) and
// [`markSpec`](#model.Schema.markSpec) properties.
const schema = new Schema({nodes, marks})
exports.schema = schema
<|endoftext|>


<commit_before>(function() {

  // Search
  const version = 'latest';

  let debounce = function (fn) {
    let timeout;
    return function () {
      let args  = Array.prototype.slice.call(arguments);
      let ctx   = this;

      clearTimeout(timeout)
      timeout = setTimeout(() => { fn.apply(ctx, args) }, 100)
    }
  }

  const searchInput = $('.docs-search__input');
  searchInput.attr('disabled', 'disabled');

  // Navigation
  Array.prototype.forEach.call($('.docs-nav__item_folder a'), el => {
    $(el).on('click', function(e) {
      docsMenu.css('maxHeight', null); // remove max-height set by mobile docs menu

      if($(e.currentTarget).hasClass('docs-nav__item__arrow')) e.preventDefault();
      else if(!$(e.currentTarget).attr('data-path')) return;

      let parent = $($(e.currentTarget).parent());
      let img = $($(e.currentTarget).find('img'));

      parent.hasClass('docs-nav__item--closed') ? parent.removeClass('docs-nav__item--closed') : parent.addClass('docs-nav__item--closed')
      let isActive = $(parent.find('.docs-nav__item__title')).hasClass('active');
      let isClosed = parent.hasClass('docs-nav__item--closed');

      if(isActive) {
        isClosed ? img.attr('src', '/assets/images/icons/arrow-right-docs-selected.svg') : img.attr('src', '/assets/images/icons/arrow-down-docs.svg');
      } else {
        isClosed ? img.attr('src', '/assets/images/icons/arrow-right-docs.svg') : img.attr('src', '/assets/images/icons/arrow-down-docs-unselected.svg');
      }
    });
  });

  // Mobile docs menu
  let mobileDocsMenu = $('.docs-menu-mobile');
  let docsMenu = $(mobileDocsMenu.find('.docs-menu-mobile-container'));
  let docsMenuButton = $(mobileDocsMenu.find('.open-docs-menu'));
  let docsMenuHeight;
  let docsMenuActive;

  if(!docsMenu) return;
  initDocsMenu();

  function initDocsMenu () {
    docsMenuHeight = docsMenu.offsetHeight;
    docsMenuActive = false;

    docsMenu.addClass('hidden');
  }

  docsMenuButton.on('click', () => {
    if (docsMenuActive) docsMenuHeight = docsMenu.offsetHeight;

    $(docsMenu).css('maxHeight', `${docsMenuHeight}px`);

    setTimeout(() => {
      docsMenu.toggleClass('hidden');
      docsMenu.toggleClass('active');
      docsMenuButton.toggleClass('active');

      docsMenuActive = !docsMenuActive;
    });
  });

  // Highlight.js
  Array.prototype.forEach.call($('pre code'), el => {
    hljs.highlightBlock(el);
  });

  // Feedback
  Array.prototype.forEach.call($('#submit-feedback'), el => {
    $(el).href = `https://github.com/dcos/dcos-docs/issues/new?body=${encodeURI(window.location.href)}`;
  });

})()
<commit_msg>This is jquery 💁<commit_after>(function() {

  // Search
  const version = 'latest';

  let debounce = function (fn) {
    let timeout;
    return function () {
      let args  = Array.prototype.slice.call(arguments);
      let ctx   = this;

      clearTimeout(timeout)
      timeout = setTimeout(() => { fn.apply(ctx, args) }, 100)
    }
  }

  const searchInput = $('.docs-search__input');
  searchInput.attr('disabled', 'disabled');

  // Navigation
  Array.prototype.forEach.call($('.docs-nav__item_folder a'), el => {
    $(el).on('click', function(e) {
      docsMenu.css('maxHeight', null); // remove max-height set by mobile docs menu

      if($(e.currentTarget).hasClass('docs-nav__item__arrow') || $(e.currentTarget).attr('href') === '#') e.preventDefault();
      else if(!$(e.currentTarget).attr('data-path')) return;

      let parent = $($(e.currentTarget).parent());
      let img = $(parent.find('img')).first();

      parent.hasClass('docs-nav__item--closed') ? parent.removeClass('docs-nav__item--closed') : parent.addClass('docs-nav__item--closed')
      let isActive = $(parent.find('.docs-nav__item__title')).hasClass('active');
      let isClosed = parent.hasClass('docs-nav__item--closed');

      if(isActive) {
        isClosed ? img.attr('src', '/assets/images/icons/arrow-right-docs-selected.svg') : img.attr('src', '/assets/images/icons/arrow-down-docs.svg');
      } else {
        isClosed ? img.attr('src', '/assets/images/icons/arrow-right-docs.svg') : img.attr('src', '/assets/images/icons/arrow-down-docs-unselected.svg');
      }
    });
  });

  // Mobile docs menu
  let mobileDocsMenu = $('.docs-menu-mobile');
  let docsMenu = $(mobileDocsMenu.find('.docs-menu-mobile-container'));
  let docsMenuButton = $(mobileDocsMenu.find('.open-docs-menu'));
  let docsMenuHeight;
  let docsMenuActive;

  if(!docsMenu) return;
  initDocsMenu();

  function initDocsMenu () {
    docsMenuHeight = docsMenu.offsetHeight;
    docsMenuActive = false;

    docsMenu.addClass('hidden');
  }

  docsMenuButton.on('click', () => {
    if (docsMenuActive) docsMenuHeight = docsMenu.offsetHeight;

    $(docsMenu).css('maxHeight', `${docsMenuHeight}px`);

    setTimeout(() => {
      docsMenu.toggleClass('hidden');
      docsMenu.toggleClass('active');
      docsMenuButton.toggleClass('active');

      docsMenuActive = !docsMenuActive;
    });
  });

  // Highlight.js
  Array.prototype.forEach.call($('pre code'), el => {
    hljs.highlightBlock(el);
  });

  // Feedback
  Array.prototype.forEach.call($('#submit-feedback'), el => {
    $(el).href = `https://github.com/dcos/dcos-docs/issues/new?body=${encodeURI(window.location.href)}`;
  });

})()
<|endoftext|>


<commit_before>/*
 * Copyright 2014, Gregg Tavares.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Gregg Tavares. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
"use strict";

define(function() {

  var copyProperties = function(src, dst) {
    for (var name in src) {
      if (!src.hasOwnProperty(name)) {
        continue;
      }
      var value = src[name];
      if (value instanceof Array) {
        var newDst = dst[name];
        if (!newDst) {
          newDst = [];
          dst[name] = newDst;
        }
        copyProperties(value, newDst);
      } else if (value instanceof Object &&
                 !(value instanceof Function) &&
                 !(value instanceof HTMLElement)) {
        var newDst = dst[name];  // eslint-disable-line
        if (!newDst) {
          newDst = {};
          dst[name] = newDst;
        }
        copyProperties(value, newDst);
      } else {
        dst[name] = value;
      }
    }
    return dst;
  };

  // Reads the query values from a URL like string.
  // @param {String} url URL like string eg. http://foo?key=value
  // @param {Object} [opt_obj] Object to attach key values to
  // @return {Object} Object with key values from URL
  function searchStringToObject(str, opt_obj) {
    if (str[0] === '?') {
      str = str.substring(1);
    }
    var results = opt_obj || {};
    str.split("&").forEach(function(part) {
      var pair = part.split("=").map(decodeURIComponent);
      results[pair[0]] = pair[1] !== undefined ? pair[1] : true;
    });
    return results;
  }

  function objectToSearchString(obj) {
    return "?" + Object.keys(obj).map(function(key) {
      return encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]);
    }).join("&");
  }

  // Reads the query values from a URL like string.
  // @param {string} url URL like string eg. http://foo?key=value
  // @param {object} opt_obj Object to attach key values to
  // @return {object} Object with key values from URL
  var parseUrlQueryString = function(str, opt_obj) {
    var dst = opt_obj || {};
    try {
      var q = str.indexOf("?");
      var e = str.indexOf("#");
      if (e < 0) {
        e = str.length;
      }
      var query = str.substring(q + 1, e);
      dst = searchStringToObject(query, dst);
    } catch (e) {
      console.error(e);
    }
    return dst;
  };

  // Reads the query values from the current URL.
  // @param {object} opt_obj Object to attach key values to
  // @return {object} Object with key values from URL
  var parseUrlQuery = function(opt_obj) {
    return searchStringToObject(window.location.search, opt_obj);
  };

  // Read `settings` from URL. Assume settings it a
  // JSON like URL as in http://foo?settings={key:value},
  // Note that unlike real JSON we don't require quoting
  // keys if they are alpha_numeric.
  //
  // @param {object} opt_obj object to apply settings to.
  // @param {string} opt_argumentName name of key for settings, default = 'settings'.
  // @return {object} object with settings
  var fixKeysRE = new RegExp("([a-zA-Z0-9_]+)\:", "g");

  var applyUrlSettings = function(opt_obj, opt_argumentName) {
    var argumentName = opt_argumentName || 'settings';
    var src = parseUrlQuery();
    var dst = opt_obj || {};
    if (src[argumentName]) {
      var json = src[argumentName].replace(fixKeysRE, '"$1":');
      var settings = JSON.parse(json);
      copyProperties(settings, dst);
    }
    return dst;
  };

  var randInt = function(value) {
    return Math.floor(Math.random() * value);
  };

  var randCSSColor = function() {
    var strong = randInt(3);
    var colors = [];
    for (var ii = 0; ii < 3; ++ii) {
      colors.push(randInt(128) + (ii === strong ? 128 : 64));
    }
    return "rgb(" + colors.join(",") + ")";
  };

  var findCSSStyleRule = function(selector) {
    for (var ii = 0; ii < document.styleSheets.length; ++ii) {
      var styleSheet = document.styleSheets[ii];
      var rules = styleSheet.cssRules || styleSheet.rules;
      if (rules) {
        for (var rr = 0; rr < rules.length; ++rr) {
          var rule = rules[rr];
          if (rule.selectorText === selector) {
            return rule;
          }
        }
      }
    }
  };

  var createTextNode = function(element) {
    var txt = document.createTextNode("");
    element.appendChild(txt);
    return txt;
  };

  /**
   * Returns the absolute position of an element for certain browsers.
   * @param {HTML Element} element The element to get a position for.
   * @return {Object} An object containing x and y as the absolute position
   *   of the given element.
   */
  var getAbsolutePosition = function(element) {
    var r = { x: element.offsetLeft, y: element.offsetTop };
    if (element.offsetParent) {
      var tmp = getAbsolutePosition(element.offsetParent);
      r.x += tmp.x;
      r.y += tmp.y;
    }
    return r;
  };

  var clamp = function(v, min, max) {
    return Math.max(min, Math.min(max, v));
  };

  var clampPlusMinus = function(v, max) {
    return clamp(v, -max, max);
  };

  var sign = function(v) {
    return v < 0 ? -1 : (v > 0 ? 1 : 0);
  };

  // Takes which ever is closer to zero
  // In other words minToZero(-2, -1) = -1 and minToZero(2, 1) = 1
  var minToZero = function(v, min) {
    return Math.abs(v) < Math.abs(min) ? v : min;
  };

  // flips 0->max to max<-0 and 0->min to min->
  // In otherwords
  //   max: 3, v: 2.7  =  0.3
  //   max: 3, v:-2.7  = -0.3
  //   max: 3, v: 0.2  =  2.8
  //   max: 3, v:-0.2  = -2.8
  var invertPlusMinusRange = function(v, max) {
    return sign(v) * (max - Math.min(max, Math.abs(v)));
  };

  var degToRad = function(d) {
    return d * Math.PI / 180;
  };

  var radToDeg = function(r) {
    return r * 180 / Math.PI;
  };

  // Resizes a cavnas to match its CSS displayed size.
  var resize = function(canvas, useDevicePixelRatio) {
    var mult = useDevicePixelRatio ? window.devicePixelRatio : 1;
    mult = mult || 1;
    var width  = Math.floor(canvas.clientWidth  * mult);
    var height = Math.floor(canvas.clientHeight * mult);
    if (canvas.width !== width ||
        canvas.height !== height) {
      canvas.width = width;
      canvas.height = height;
      return true;
    }
  };

  return {
    applyUrlSettings: applyUrlSettings,
    clamp: clamp,
    clampPlusMinus: clampPlusMinus,
    copyProperties: copyProperties,
    createTextNode: createTextNode,
    degToRad: degToRad,
    findCSSStyleRule: findCSSStyleRule,
    getAbsolutePosition: getAbsolutePosition,
    invertPlusMinusRange: invertPlusMinusRange,
    minToZero: minToZero,
    objectToSearchString: objectToSearchString,
    parseUrlQuery: parseUrlQuery,
    parseUrlQueryString: parseUrlQueryString,
    searchStringToObject: searchStringToObject,
    radToDeg: radToDeg,
    randInt: randInt,
    randCSSColor: randCSSColor,
    resize: resize,
    sign: sign,
  };
});

<commit_msg>make objectToSearchString not inlcude undefined keys<commit_after>/*
 * Copyright 2014, Gregg Tavares.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Gregg Tavares. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
"use strict";

define(function() {

  var copyProperties = function(src, dst) {
    for (var name in src) {
      if (!src.hasOwnProperty(name)) {
        continue;
      }
      var value = src[name];
      if (value instanceof Array) {
        var newDst = dst[name];
        if (!newDst) {
          newDst = [];
          dst[name] = newDst;
        }
        copyProperties(value, newDst);
      } else if (value instanceof Object &&
                 !(value instanceof Function) &&
                 !(value instanceof HTMLElement)) {
        var newDst = dst[name];  // eslint-disable-line
        if (!newDst) {
          newDst = {};
          dst[name] = newDst;
        }
        copyProperties(value, newDst);
      } else {
        dst[name] = value;
      }
    }
    return dst;
  };

  // Reads the query values from a URL like string.
  // @param {String} url URL like string eg. http://foo?key=value
  // @param {Object} [opt_obj] Object to attach key values to
  // @return {Object} Object with key values from URL
  function searchStringToObject(str, opt_obj) {
    if (str[0] === '?') {
      str = str.substring(1);
    }
    var results = opt_obj || {};
    str.split("&").forEach(function(part) {
      var pair = part.split("=").map(decodeURIComponent);
      results[pair[0]] = pair[1] !== undefined ? pair[1] : true;
    });
    return results;
  }

  function objectToSearchString(obj) {
    return "?" + Object.keys(obj).filter(function(key) {
      return obj[key] !== undefined;
    }).map(function(key) {
      return encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]);
    }).join("&");
  }

  // Reads the query values from a URL like string.
  // @param {string} url URL like string eg. http://foo?key=value
  // @param {object} opt_obj Object to attach key values to
  // @return {object} Object with key values from URL
  var parseUrlQueryString = function(str, opt_obj) {
    var dst = opt_obj || {};
    try {
      var q = str.indexOf("?");
      var e = str.indexOf("#");
      if (e < 0) {
        e = str.length;
      }
      var query = str.substring(q + 1, e);
      dst = searchStringToObject(query, dst);
    } catch (e) {
      console.error(e);
    }
    return dst;
  };

  // Reads the query values from the current URL.
  // @param {object} opt_obj Object to attach key values to
  // @return {object} Object with key values from URL
  var parseUrlQuery = function(opt_obj) {
    return searchStringToObject(window.location.search, opt_obj);
  };

  // Read `settings` from URL. Assume settings it a
  // JSON like URL as in http://foo?settings={key:value},
  // Note that unlike real JSON we don't require quoting
  // keys if they are alpha_numeric.
  //
  // @param {object} opt_obj object to apply settings to.
  // @param {string} opt_argumentName name of key for settings, default = 'settings'.
  // @return {object} object with settings
  var fixKeysRE = new RegExp("([a-zA-Z0-9_]+)\:", "g");

  var applyUrlSettings = function(opt_obj, opt_argumentName) {
    var argumentName = opt_argumentName || 'settings';
    var src = parseUrlQuery();
    var dst = opt_obj || {};
    if (src[argumentName]) {
      var json = src[argumentName].replace(fixKeysRE, '"$1":');
      var settings = JSON.parse(json);
      copyProperties(settings, dst);
    }
    return dst;
  };

  var randInt = function(value) {
    return Math.floor(Math.random() * value);
  };

  var randCSSColor = function() {
    var strong = randInt(3);
    var colors = [];
    for (var ii = 0; ii < 3; ++ii) {
      colors.push(randInt(128) + (ii === strong ? 128 : 64));
    }
    return "rgb(" + colors.join(",") + ")";
  };

  var findCSSStyleRule = function(selector) {
    for (var ii = 0; ii < document.styleSheets.length; ++ii) {
      var styleSheet = document.styleSheets[ii];
      var rules = styleSheet.cssRules || styleSheet.rules;
      if (rules) {
        for (var rr = 0; rr < rules.length; ++rr) {
          var rule = rules[rr];
          if (rule.selectorText === selector) {
            return rule;
          }
        }
      }
    }
  };

  var createTextNode = function(element) {
    var txt = document.createTextNode("");
    element.appendChild(txt);
    return txt;
  };

  /**
   * Returns the absolute position of an element for certain browsers.
   * @param {HTML Element} element The element to get a position for.
   * @return {Object} An object containing x and y as the absolute position
   *   of the given element.
   */
  var getAbsolutePosition = function(element) {
    var r = { x: element.offsetLeft, y: element.offsetTop };
    if (element.offsetParent) {
      var tmp = getAbsolutePosition(element.offsetParent);
      r.x += tmp.x;
      r.y += tmp.y;
    }
    return r;
  };

  var clamp = function(v, min, max) {
    return Math.max(min, Math.min(max, v));
  };

  var clampPlusMinus = function(v, max) {
    return clamp(v, -max, max);
  };

  var sign = function(v) {
    return v < 0 ? -1 : (v > 0 ? 1 : 0);
  };

  // Takes which ever is closer to zero
  // In other words minToZero(-2, -1) = -1 and minToZero(2, 1) = 1
  var minToZero = function(v, min) {
    return Math.abs(v) < Math.abs(min) ? v : min;
  };

  // flips 0->max to max<-0 and 0->min to min->
  // In otherwords
  //   max: 3, v: 2.7  =  0.3
  //   max: 3, v:-2.7  = -0.3
  //   max: 3, v: 0.2  =  2.8
  //   max: 3, v:-0.2  = -2.8
  var invertPlusMinusRange = function(v, max) {
    return sign(v) * (max - Math.min(max, Math.abs(v)));
  };

  var degToRad = function(d) {
    return d * Math.PI / 180;
  };

  var radToDeg = function(r) {
    return r * 180 / Math.PI;
  };

  // Resizes a cavnas to match its CSS displayed size.
  var resize = function(canvas, useDevicePixelRatio) {
    var mult = useDevicePixelRatio ? window.devicePixelRatio : 1;
    mult = mult || 1;
    var width  = Math.floor(canvas.clientWidth  * mult);
    var height = Math.floor(canvas.clientHeight * mult);
    if (canvas.width !== width ||
        canvas.height !== height) {
      canvas.width = width;
      canvas.height = height;
      return true;
    }
  };

  return {
    applyUrlSettings: applyUrlSettings,
    clamp: clamp,
    clampPlusMinus: clampPlusMinus,
    copyProperties: copyProperties,
    createTextNode: createTextNode,
    degToRad: degToRad,
    findCSSStyleRule: findCSSStyleRule,
    getAbsolutePosition: getAbsolutePosition,
    invertPlusMinusRange: invertPlusMinusRange,
    minToZero: minToZero,
    objectToSearchString: objectToSearchString,
    parseUrlQuery: parseUrlQuery,
    parseUrlQueryString: parseUrlQueryString,
    searchStringToObject: searchStringToObject,
    radToDeg: radToDeg,
    randInt: randInt,
    randCSSColor: randCSSColor,
    resize: resize,
    sign: sign,
  };
});

<|endoftext|>


<commit_before>'use strict';

import { remote } from 'electron';
import path from 'path';
import i18n from '../i18n/index.js';

const { Tray, Menu } = remote;

const mainWindow = remote.getCurrentWindow();

const icons = {
	win32: {
		dir: 'windows',
	},
	linux: {
		dir: 'linux',
	},
	darwin: {
		dir: 'osx',
	},
};

const statusBullet = {
	online: '\u001B[32m•',
	away: '\u001B[33m•',
	busy: '\u001B[31m•',
	offline: '\u001B[37m•',
};

const messageCountColor = {
	white: '\u001B[37m',
	black: '\u001B[0m',
};

function getTrayImagePath(badge) {
	let iconFilename;
	if (badge.title === '•') {
		iconFilename = 'icon-tray-dot';
	} else if (badge.count > 0) {
		if (badge.count > 9) {
			iconFilename = 'icon-tray-9plus';
		} else {
			iconFilename = `icon-tray-${ badge.count }`;
		}
	} else if (badge.showAlert) {
		iconFilename = 'icon-tray-alert';
	} else {
		iconFilename = 'icon-tray-Template';
	}

	if (process.platform === 'win32') {
		iconFilename += '.ico';
	} else {
		iconFilename += '.png';
	}

	return path.join(__dirname, 'images', icons[process.platform].dir, iconFilename);
}

function createAppTray() {
	const _tray = new Tray(getTrayImagePath({ title:'', count:0, showAlert:false }));
	mainWindow.tray = _tray;

	const contextMenuShow = Menu.buildFromTemplate([{
		label: i18n.__('Show'),
		click() {
			mainWindow.show();
		},
	}, {
		label: i18n.__('Quit'),
		click() {
			remote.app.quit();
		},
	}]);

	const contextMenuHide = Menu.buildFromTemplate([{
		label: i18n.__('Hide'),
		click() {
			mainWindow.hide();
		},
	}, {
		label: i18n.__('Quit'),
		click() {
			remote.app.quit();
		},
	}]);

	if (!mainWindow.isMinimized() && !mainWindow.isVisible()) {
		_tray.setContextMenu(contextMenuShow);
	} else {
		_tray.setContextMenu(contextMenuHide);
	}

	const onShow = function() {
		_tray.setContextMenu(contextMenuHide);
	};

	const onHide = function() {
		_tray.setContextMenu(contextMenuShow);
	};

	mainWindow.on('show', onShow);
	mainWindow.on('restore', onShow);

	mainWindow.on('hide', onHide);
	mainWindow.on('minimize', onHide);

	_tray.setToolTip(remote.app.getName());

	_tray.on('right-click', function(e, b) {
		_tray.popUpContextMenu(undefined, b);
	});

	_tray.on('click', () => {
		if (mainWindow.isVisible()) {
			return mainWindow.hide();
		}

		mainWindow.show();
	});

	mainWindow.destroyTray = function() {
		mainWindow.removeListener('show', onShow);
		mainWindow.removeListener('hide', onHide);
		_tray.destroy();
		mainWindow.emit('tray-destroyed');
	};

	mainWindow.emit('tray-created');
}

let state = {
	badge: null,
	status: 'online',
};

function showTrayAlert(badge, status = 'online') {
	if (mainWindow.tray === null || mainWindow.tray === undefined) {
		return;
	}

	state = {
		...state,
		badge,
		status,
	};

	const trayDisplayed = localStorage.getItem('hideTray') !== 'true';
	const statusDisplayed = (localStorage.getItem('showUserStatusInTray') || 'true') === 'true';
	const hasMentions = badge.showAlert && badge.count > 0;

	if (!mainWindow.isFocused()) {
		mainWindow.flashFrame(hasMentions);
	}

	if (process.platform === 'win32') {
		if (hasMentions) {
			mainWindow.webContents.send('render-taskbar-icon', badge.count);
		} else {
			mainWindow.setOverlayIcon(null, '');
		}
	}

	if (process.platform === 'darwin') {
		let countColor = messageCountColor.black;
		if (remote.systemPreferences.isDarkMode()) {
			countColor = messageCountColor.white;
		}

		const trayTitle = [
			statusDisplayed && statusBullet[status],
			hasMentions && `${ countColor }${ badge.title }`,
		].filter(Boolean).join(' ');
		remote.app.dock.setBadge(badge.title);
		if (trayDisplayed) {
			mainWindow.tray.setTitle(trayTitle);
		}
	}

	if (process.platform === 'linux') {
		remote.app.setBadgeCount(badge.count);
	}

	if (trayDisplayed) {
		mainWindow.tray.setImage(getTrayImagePath(badge));
	}
}

function removeAppTray() {
	mainWindow.destroyTray();
}

function toggle() {
	if (localStorage.getItem('hideTray') === 'true') {
		createAppTray();
		localStorage.setItem('hideTray', 'false');
		showTrayAlert(state.badge, state.status);
	} else {
		removeAppTray();
		localStorage.setItem('hideTray', 'true');
	}
}

function toggleStatus() {
	if (localStorage.getItem('showUserStatusInTray') === 'true') {
		localStorage.setItem('showUserStatusInTray', 'false');
	} else {
		localStorage.setItem('showUserStatusInTray', 'true');
	}

	if (localStorage.getItem('hideTray') !== 'true') {
		showTrayAlert(state.badge, state.status);
	}
}

if (localStorage.getItem('hideTray') !== 'true') {
	createAppTray();
}

export default {
	showTrayAlert,
	toggle,
	toggleStatus,
};
<commit_msg>Fix crash on toggle tray icon<commit_after>'use strict';

import { remote } from 'electron';
import path from 'path';
import i18n from '../i18n/index.js';

const { Tray, Menu, getCurrentWindow } = remote;

const mainWindow = getCurrentWindow();

const icons = {
	win32: {
		dir: 'windows',
	},
	linux: {
		dir: 'linux',
	},
	darwin: {
		dir: 'osx',
	},
};

const statusBullet = {
	online: '\u001B[32m•',
	away: '\u001B[33m•',
	busy: '\u001B[31m•',
	offline: '\u001B[37m•',
};

const messageCountColor = {
	white: '\u001B[37m',
	black: '\u001B[0m',
};

function getTrayImagePath(badge) {
	let iconFilename;
	if (badge.title === '•') {
		iconFilename = 'icon-tray-dot';
	} else if (badge.count > 0) {
		if (badge.count > 9) {
			iconFilename = 'icon-tray-9plus';
		} else {
			iconFilename = `icon-tray-${ badge.count }`;
		}
	} else if (badge.showAlert) {
		iconFilename = 'icon-tray-alert';
	} else {
		iconFilename = 'icon-tray-Template';
	}

	if (process.platform === 'win32') {
		iconFilename += '.ico';
	} else {
		iconFilename += '.png';
	}

	return path.join(__dirname, 'images', icons[process.platform].dir, iconFilename);
}

function createAppTray() {
	const _tray = new Tray(getTrayImagePath({ title:'', count:0, showAlert:false }));
	mainWindow.tray = _tray;

	const contextMenuShow = Menu.buildFromTemplate([{
		label: i18n.__('Show'),
		click() {
			mainWindow.show();
		},
	}, {
		label: i18n.__('Quit'),
		click() {
			remote.app.quit();
		},
	}]);

	const contextMenuHide = Menu.buildFromTemplate([{
		label: i18n.__('Hide'),
		click() {
			mainWindow.hide();
		},
	}, {
		label: i18n.__('Quit'),
		click() {
			remote.app.quit();
		},
	}]);

	if (!mainWindow.isMinimized() && !mainWindow.isVisible()) {
		_tray.setContextMenu(contextMenuShow);
	} else {
		_tray.setContextMenu(contextMenuHide);
	}

	const onShow = function() {
		_tray.setContextMenu(contextMenuHide);
	};

	const onHide = function() {
		_tray.setContextMenu(contextMenuShow);
	};

	mainWindow.on('show', onShow);
	mainWindow.on('restore', onShow);

	mainWindow.on('hide', onHide);
	mainWindow.on('minimize', onHide);

	_tray.setToolTip(remote.app.getName());

	_tray.on('right-click', function(e, b) {
		_tray.popUpContextMenu(undefined, b);
	});

	_tray.on('click', () => {
		if (mainWindow.isVisible()) {
			return mainWindow.hide();
		}

		mainWindow.show();
	});

	mainWindow.destroyTray = function() {
		mainWindow.removeListener('show', onShow);
		mainWindow.removeListener('hide', onHide);
		_tray.destroy();
		mainWindow.emit('tray-destroyed');
	};

	mainWindow.emit('tray-created');
}

let state = {
	badge: {
		title: '',
		count: 0,
	},
	status: 'online',
};

function showTrayAlert(badge, status = 'online') {
	if (mainWindow.tray === null || mainWindow.tray === undefined) {
		return;
	}

	state = {
		...state,
		badge,
		status,
	};

	const trayDisplayed = localStorage.getItem('hideTray') !== 'true';
	const statusDisplayed = (localStorage.getItem('showUserStatusInTray') || 'true') === 'true';
	const hasMentions = badge.showAlert && badge.count > 0;

	if (!mainWindow.isFocused()) {
		mainWindow.flashFrame(hasMentions);
	}

	if (process.platform === 'win32') {
		if (hasMentions) {
			mainWindow.webContents.send('render-taskbar-icon', badge.count);
		} else {
			mainWindow.setOverlayIcon(null, '');
		}
	}

	if (process.platform === 'darwin') {
		let countColor = messageCountColor.black;
		if (remote.systemPreferences.isDarkMode()) {
			countColor = messageCountColor.white;
		}

		const trayTitle = [
			statusDisplayed && statusBullet[status],
			hasMentions && `${ countColor }${ badge.title }`,
		].filter(Boolean).join(' ');
		remote.app.dock.setBadge(badge.title);
		if (trayDisplayed) {
			mainWindow.tray.setTitle(trayTitle);
		}
	}

	if (process.platform === 'linux') {
		remote.app.setBadgeCount(badge.count);
	}

	if (trayDisplayed) {
		mainWindow.tray.setImage(getTrayImagePath(badge));
	}
}

function removeAppTray() {
	mainWindow.destroyTray();
}

function toggle() {
	if (localStorage.getItem('hideTray') === 'true') {
		createAppTray();
		localStorage.setItem('hideTray', 'false');
		showTrayAlert(state.badge, state.status);
	} else {
		removeAppTray();
		localStorage.setItem('hideTray', 'true');
	}
}

function toggleStatus() {
	if (localStorage.getItem('showUserStatusInTray') === 'true') {
		localStorage.setItem('showUserStatusInTray', 'false');
	} else {
		localStorage.setItem('showUserStatusInTray', 'true');
	}

	if (localStorage.getItem('hideTray') !== 'true') {
		showTrayAlert(state.badge, state.status);
	}
}

if (localStorage.getItem('hideTray') !== 'true') {
	createAppTray();
}

export default {
	showTrayAlert,
	toggle,
	toggleStatus,
};
<|endoftext|>


<commit_before>const check = require('validator').check;
const db = require('../lib/db');

const Images = db.table('images', {
  fields: [
    'id',
    'slug',
    'url',
    'mimetype',
    'data'
  ],
  methods: {
    toUrl: function toUrl () {
      if (this.url)
        return this.url.toString('ascii');

      if (!this.slug)
        return null;

      return '/images/' + this.slug.toString('ascii');
    }
  },
});

Images.validateRow = function (row) {
  return this.fields.reduce(function (errors, field) {
    try {
      const validator = validation[field] || noop;
      validator(row[field]);
    }
    catch(e) {
      e.field = field;
      errors.push(e);
    }
    return errors;
  }, []);
};

const validation = {
  id: function (id) {
    if (typeof id == 'undefined') return;
    check(id).isInt();
  },
  slug: function (slug) {
    check(slug).len(1, 50);
  },
  url: function (url) {
    if (typeof url == 'undefined') return;
    check(url).isUrl();
  },
  mimetype: function (type) {
    if (typeof type == 'undefined') return;
    // Do we need to check this against an actual list somewhere?
    check(type).is(/^[a-z]+\/\w+([-.]\w+)*(\+\w+)?$/i);
  }
};

function noop() {}

exports = module.exports = Images;
<commit_msg>Use `makeValidator` helper in the image model.<commit_after>const db = require('../lib/db');
const makeValidator = require('../lib/make-validator')
const check = require('validator').check;

const Images = db.table('images', {
  fields: [
    'id',
    'slug',
    'url',
    'mimetype',
    'data'
  ],
  methods: {
    toUrl: function toUrl () {
      if (this.url)
        return this.url.toString('ascii');

      if (!this.slug)
        return null;

      return '/images/' + this.slug.toString('ascii');
    }
  },
});

Images.validateRow = makeValidator({
  id: function (id) {
    if (typeof id == 'undefined') return;
    check(id).isInt();
  },
  slug: function (slug) {
    check(slug).len(1, 50);
  },
  url: function (url) {
    if (typeof url == 'undefined') return;
    check(url).isUrl();
  },
  mimetype: function (type) {
    if (typeof type == 'undefined') return;
    // Do we need to check this against an actual list somewhere?
    check(type).is(/^[a-z]+\/\w+([-.]\w+)*(\+\w+)?$/i);
  }
});

exports = module.exports = Images;
<|endoftext|>


<commit_before>'use strict';

const { chain } = require('../chain');
const middlewares = require('../middleware');
const { mapAsync } = require('../utilities');

const start = async function (opts) {
  const mdw = await applyMiddlewares(opts, middlewares);

  return chain([

    /**
     * Protocol-related middleware
     **/
    // The first middleware (not present here) is the error handler,
    // which sends final response, if errors

    // Sets up protocol format
    mdw.protocolConvertor,
    // Pick the protocol
    mdw.protocolNegotiator,
    // Retrieves timestamp
    mdw.getTimestamp,
    // Sends final response, if success
    mdw.sendResponse,
    // Retrieves input.path
    mdw.getPath,
    // Retrieves IP
    mdw.getIp,
    // General request log
    mdw.logger,
    // Merge request parameters and payload into protocol-agnostic format
    mdw.fillParams,
    // Retrieves input.route, using input.path
    mdw.router,

    /**
     * Interface-related middleware
     **/
    // Convert from protocol format to interface format
    mdw.interfaceConvertor,
    // Pick the interface
    mdw.interfaceNegotiator,
    // Compile JSL helpers, variables, etc.
    mdw.wrapCustomJsl,
    // Translates interface-specific calls into generic instance actions
    mdw.executeInterface,

    /**
     * Middleware transforming one action into 0, 1 or several commands
     **/
    // Convert from interface format to API format
    mdw.apiConvertor,
    // Basic validation layer
    mdw.basicValidation,
    // Turn "create" action into a "create" command
    mdw.createAction,
    // Turn "find" action into a "read" command
    mdw.findAction,
    // Split "update" action into "read" then "update" commands
    mdw.updateAction,
    // Split "upsert" action into "read", then "create" or "update"
    // commands, then a final "read" command
    mdw.upsertAction,
    // Turn "replace" action into an "update" command
    mdw.replaceAction,
    // Turn "delete" action into a "delete" command
    mdw.deleteAction,

    /**
     * Normalization-related middleware
     **/
    // Convert from API format to CRUD format
    mdw.crudConvertor,
    // CRUD basic validation layer
    mdw.crudBasicValidation,
    // Apply system-defined default values, e.g. order_by 'id+'
    mdw.systemDefaults,
    // Apply user-defined default values
    mdw.userDefaults,
    // Normalize input
    mdw.normalization,
    // Only keep minimal attributes in delete response
    mdw.cleanDelete,

    /**
     * Generic API-related middleware
     **/
    // Paginate output
    mdw.pagination,
    // Process transforms
    mdw.transform,
    // Parse filter's JSL, e.g. convert to format processable by database
    mdw.handleFilter,

    /**
     * Validation-related middleware
     **/
    // General validation layer
    mdw.validation,

    /**
     * Database-related middleware
     **/
    // Do the database action, protocol and interface-agnostic
    mdw.executeDatabaseAction,

    /**
     * Catch-all error middleware
     **/
    mdw.noResponse,

  ]);
};

// Apply options
const applyMiddlewares = async function (opts, middlewares) {
  return await mapAsync(middlewares, async mdw => await mdw(opts));
};

module.exports = {
  start,
};
<commit_msg>Reorder statements<commit_after>'use strict';

const { chain } = require('../chain');
const middlewares = require('../middleware');
const { mapAsync } = require('../utilities');

// Apply options
const applyMiddlewares = async function (opts, middlewares) {
  return await mapAsync(middlewares, async mdw => await mdw(opts));
};

const start = async function (opts) {
  const mdw = await applyMiddlewares(opts, middlewares);

  return chain([

    /**
     * Protocol-related middleware
     **/
    // The first middleware (not present here) is the error handler,
    // which sends final response, if errors

    // Sets up protocol format
    mdw.protocolConvertor,
    // Pick the protocol
    mdw.protocolNegotiator,
    // Retrieves timestamp
    mdw.getTimestamp,
    // Sends final response, if success
    mdw.sendResponse,
    // Retrieves input.path
    mdw.getPath,
    // Retrieves IP
    mdw.getIp,
    // General request log
    mdw.logger,
    // Merge request parameters and payload into protocol-agnostic format
    mdw.fillParams,
    // Retrieves input.route, using input.path
    mdw.router,

    /**
     * Interface-related middleware
     **/
    // Convert from protocol format to interface format
    mdw.interfaceConvertor,
    // Pick the interface
    mdw.interfaceNegotiator,
    // Compile JSL helpers, variables, etc.
    mdw.wrapCustomJsl,
    // Translates interface-specific calls into generic instance actions
    mdw.executeInterface,

    /**
     * Middleware transforming one action into 0, 1 or several commands
     **/
    // Convert from interface format to API format
    mdw.apiConvertor,
    // Basic validation layer
    mdw.basicValidation,
    // Turn "create" action into a "create" command
    mdw.createAction,
    // Turn "find" action into a "read" command
    mdw.findAction,
    // Split "update" action into "read" then "update" commands
    mdw.updateAction,
    // Split "upsert" action into "read", then "create" or "update"
    // commands, then a final "read" command
    mdw.upsertAction,
    // Turn "replace" action into an "update" command
    mdw.replaceAction,
    // Turn "delete" action into a "delete" command
    mdw.deleteAction,

    /**
     * Normalization-related middleware
     **/
    // Convert from API format to CRUD format
    mdw.crudConvertor,
    // CRUD basic validation layer
    mdw.crudBasicValidation,
    // Apply system-defined default values, e.g. order_by 'id+'
    mdw.systemDefaults,
    // Apply user-defined default values
    mdw.userDefaults,
    // Normalize input
    mdw.normalization,
    // Only keep minimal attributes in delete response
    mdw.cleanDelete,

    /**
     * Generic API-related middleware
     **/
    // Paginate output
    mdw.pagination,
    // Process transforms
    mdw.transform,
    // Parse filter's JSL, e.g. convert to format processable by database
    mdw.handleFilter,

    /**
     * Validation-related middleware
     **/
    // General validation layer
    mdw.validation,

    /**
     * Database-related middleware
     **/
    // Do the database action, protocol and interface-agnostic
    mdw.executeDatabaseAction,

    /**
     * Catch-all error middleware
     **/
    mdw.noResponse,

  ]);
};

module.exports = {
  start,
};
<|endoftext|>


<commit_before>/* eslint-disable no-console */
/* eslint-disable func-names */
/* eslint-disable arrow-parens */
import Koa from 'koa';
import send from 'koa-send';
import logger from 'koa-logger';
import path from 'path';
import bodyParser from 'koa-bodyparser'

import { log, d, g, b, gr, r, y, yb, redWhite } from './util/logging';

import {
  io,
  socketConnection,
  socketDisconnect,
  socketLogin,
  socketLogout,
  broadcastMessage,
  broadcastPrivateMessage,
  usersTypingStatus,
  broadcastUpdatedMessage,
} from './config/socket';

const app = Koa();
const env = process.env.NODE_ENV || 'dev';
const port = process.env.PORT || 3000;

process.on('uncaughtException', err => {
  console.log(err);
});

// app.use(function* () {
//   yield db();
// })
app.use(logger());
app.use(bodyParser());

app.use(function* () {
  yield send(this, this.path, {
    root: path.join(__dirname, '../../dist/'),
  });
});

io.attach(app);

// Socket.io listeners
io.on('connection', socketConnection);
io.on('disconnect', socketDisconnect);
io.on('login', socketLogin);
io.on('logout', socketLogout);
io.on('message', broadcastMessage);
io.on('privateMessage', broadcastPrivateMessage);
io.on('typing', usersTypingStatus);
io.on('likedMessage', broadcastUpdatedMessage);

app.listen(port, () => {
  log(`Server started on port ${yb(port)}, environment: ${b(env)}`);
});
<commit_msg>fix(server): correct path<commit_after>/* eslint-disable no-console */
/* eslint-disable func-names */
/* eslint-disable arrow-parens */
import Koa from 'koa';
import send from 'koa-send';
import logger from 'koa-logger';
import path from 'path';
import bodyParser from 'koa-bodyparser'

import { log, d, g, b, gr, r, y, yb, redWhite } from './util/logging';

import {
  io,
  socketConnection,
  socketDisconnect,
  socketLogin,
  socketLogout,
  broadcastMessage,
  broadcastPrivateMessage,
  usersTypingStatus,
  broadcastUpdatedMessage,
} from './config/socket';

const app = Koa();
const env = process.env.NODE_ENV || 'dev';
const port = process.env.PORT || 3000;

process.on('uncaughtException', err => {
  console.log(err);
});

// app.use(function* () {
//   yield db();
// })
app.use(logger());
app.use(bodyParser());

app.use(function* () {
  yield send(this, this.path, {
    root: path.join(__dirname, '../../dist/index.html'),
  });
});

io.attach(app);

// Socket.io listeners
io.on('connection', socketConnection);
io.on('disconnect', socketDisconnect);
io.on('login', socketLogin);
io.on('logout', socketLogout);
io.on('message', broadcastMessage);
io.on('privateMessage', broadcastPrivateMessage);
io.on('typing', usersTypingStatus);
io.on('likedMessage', broadcastUpdatedMessage);

app.listen(port, () => {
  log(`Server started on port ${yb(port)}, environment: ${b(env)}`);
});
<|endoftext|>


<commit_before>import 'babel-polyfill'
import express from 'express'
import path from 'path'
import log from './log'
import proxy from 'http-proxy-middleware'
import clientRouteHandler from './client-route-handler'

const app = express()
const port = process.env.PORT
app.enable('trust proxy')

app.get('/', (req, res) => {
  res.redirect('/home')
})

// In development, we use webpack server
if (process.env.NODE_ENV === 'production') {
  app.use(express.static(process.env.PUBLIC_DIR, {
    maxAge: '180 days'
  }))
}

app.use('/go',
  proxy({
    target: 'http:/go.brandnewcongress.org',
    changeOrigin: true,
    pathRewrite: {
      '^/go': '/'
    }
  })
)

app.use([
  '/teams',
  '/forms',
  '/helpdesk',
  '/talentteam',
  '/eventsteam',
  '/legal_team',
  '/moneyteam',
  '/travelteam',
  '/crmteam',
  '/analytics_team',
  '/web_team',
  '/techteam',
  '/platformteam',
  '/creative_team',
  '/social_media',
  '/email_team',
  '/pressteam'],
  proxy({
    target: 'http://go.brandnewcongress.org',
    changeOrigin: true
  }))

app.use([
  '/home',
  '/callteam',
  '/assets',
  '/about',
  '/teams',
  '/abteam',
  '/adteam',
  '/call',
  '/conferencecallteam',
  '/dataentryteam',
  '/faq',
  '/officeteam',
  '/researchteam',
  '/shareteam',
  '/spreadsheetteam',
  '/textingteam',
  '/wikiteam',
  '/travelteam'],
  proxy({
    target: 'http://brandnewcongress.github.io',
    changeOrigin: true
  }))

app.use(clientRouteHandler)
app.listen(port, () => {
  log.info(`Node app is running on port ${port}`)
})
<commit_msg>Redirect /techteam<commit_after>import 'babel-polyfill'
import express from 'express'
import log from './log'
import proxy from 'http-proxy-middleware'
import clientRouteHandler from './client-route-handler'

const app = express()
const port = process.env.PORT
app.enable('trust proxy')

app.get('/', (req, res) => {
  res.redirect('/home')
})

app.get('/techteam', (req, res) => {
  res.redirect('https://github.com/BrandNewCongress/welcome/blob/master/README.md')
})

// In development, we use webpack server
if (process.env.NODE_ENV === 'production') {
  app.use(express.static(process.env.PUBLIC_DIR, {
    maxAge: '180 days'
  }))
}

app.use('/go',
  proxy({
    target: 'http:/go.brandnewcongress.org',
    changeOrigin: true,
    pathRewrite: {
      '^/go': '/'
    }
  })
)

app.use([
  '/teams',
  '/forms',
  '/helpdesk',
  '/talentteam',
  '/eventsteam',
  '/legal_team',
  '/moneyteam',
  '/travelteam',
  '/crmteam',
  '/analytics_team',
  '/web_team',
  '/platformteam',
  '/creative_team',
  '/social_media',
  '/email_team',
  '/pressteam'],
  proxy({
    target: 'http://go.brandnewcongress.org',
    changeOrigin: true
  }))

app.use([
  '/home',
  '/callteam',
  '/assets',
  '/about',
  '/teams',
  '/abteam',
  '/adteam',
  '/call',
  '/conferencecallteam',
  '/dataentryteam',
  '/faq',
  '/officeteam',
  '/researchteam',
  '/shareteam',
  '/spreadsheetteam',
  '/textingteam',
  '/wikiteam',
  '/travelteam'],
  proxy({
    target: 'http://brandnewcongress.github.io',
    changeOrigin: true
  }))

app.use(clientRouteHandler)
app.listen(port, () => {
  log.info(`Node app is running on port ${port}`)
})
<|endoftext|>