<commit_before>var webpack = require('webpack');
var path = require('path');
var fs = require('fs');

var SaveAssetsJson = require('assets-webpack-plugin');

var addons = require('./addons.json');
var root = path.resolve(__dirname, 'website', 'static');
/** Return the absolute path given a path relative to ./website/static */
var staticPath = function(dir) {
    return path.resolve(root, dir);
};
var nodePath = function(dir) {
    return path.resolve(__dirname, 'node_modules', dir);
};
var addonsPath = function(dir) {
    return path.resolve(__dirname, 'addons', dir);
};

/**
 * Each JS module for a page on the OSF is webpack entry point. These are built
 * to website/static/public/
 */
var entry = {
    // JS
    'base-page': staticPath('js/pages/base-page.js'),
    'home-page': staticPath('js/pages/home-page.js'),
    'landing-page': staticPath('js/pages/landing-page.js'),
    'dashboard-page': staticPath('js/pages/dashboard-page.js'),
    'profile-page': staticPath('js/pages/profile-page.js'),
    'project-dashboard': staticPath('js/pages/project-dashboard-page.js'),
    'project-base-page': staticPath('js/pages/project-base-page.js'),
    'project-settings-page': staticPath('js/pages/project-settings-page.js'),
    'project-addons-page': staticPath('js/pages/project-addons-page.js'),
    'project-registrations-page': staticPath('js/pages/project-registrations-page.js'),
    'registration-retraction-page': staticPath('js/pages/registration-retraction-page.js'),
    'registration-edit-page': staticPath('js/pages/registration-edit-page.js'),
    'register-page': staticPath('js/pages/register-page.js'),
    'wiki-edit-page': staticPath('js/pages/wiki-edit-page.js'),
    'statistics-page': staticPath('js/pages/statistics-page.js'),
    'request-access-page': staticPath('js/pages/request-access-page.js'),
    'file-page': staticPath('js/pages/file-page.js'),
    'files-page': staticPath('js/pages/files-page.js'),
    'reg-landing-page': staticPath('js/pages/reg-landing-page.js'),
    'profile-settings-page': staticPath('js/pages/profile-settings-page.js'),
    'profile-account-settings-page': staticPath('js/pages/profile-account-settings-page.js'),
    'profile-settings-applications-list-page': staticPath('js/pages/profile-settings-applications-list-page.js'),
    'profile-settings-applications-detail-page': staticPath('js/pages/profile-settings-applications-detail-page.js'),
    'profile-settings-personal-tokens-list-page': staticPath('js/pages/profile-settings-personal-tokens-list-page.js'),
    'profile-settings-personal-tokens-detail-page': staticPath('js/pages/profile-settings-personal-tokens-detail-page.js'),
    'sharing-page': staticPath('js/pages/sharing-page.js'),
    'conference-page': staticPath('js/pages/conference-page.js'),
    'meetings-page': staticPath('js/pages/meetings-page.js'),
    'view-file-tree-page': staticPath('js/pages/view-file-tree-page.js'),
    'search-page': staticPath('js/pages/search-page.js'),
    'profile-settings-addons-page': staticPath('js/pages/profile-settings-addons-page.js'),
    'forgotpassword-page': staticPath('js/pages/forgotpassword-page.js'),
    'resetpassword-page': staticPath('js/pages/resetpassword-page.js'),
    'claimaccount-page': staticPath('js/pages/claimaccount-page.js'),
    'login-page': staticPath('js/pages/login-page.js'),
    'notifications-config-page': staticPath('js/pages/notifications-config-page.js'),
    'render-nodes': staticPath('js/pages/render-nodes.js'),
    'institution-page': staticPath('js/pages/institution-page.js'),
    // Commons chunk
    'vendor': [
        // Vendor libraries
        'knockout',
        'knockout.validation',
        'moment',
        'bootstrap',
        'bootbox',
        'bootstrap-editable',
        'select2',
        'dropzone',
        'knockout-sortable',
        'loaders.css',
        'treebeard',
        'lodash.get',
        'js-cookie',
        'URIjs',
        // Common internal modules
        'js/fangorn',
        'js/citations',
        'js/osfHelpers',
        'js/osfToggleHeight',
        'mithril',
        // Main CSS files that get loaded above the fold
        nodePath('select2/select2.css'),
        nodePath('bootstrap/dist/css/bootstrap.css'),
        '@centerforopenscience/osf-style',
        staticPath('css/style.css'),
    ],
};

// Collect log text from addons
var mainLogs = require(staticPath('js/logActionsList.json'));
var anonymousLogs = require(staticPath('js/anonymousLogActionsList.json'));
var addonLog;
var anonymousAddonLog;

// Collect addons endpoints. If an addon's static folder has
// any of the following files, it will be added as an entry point
// and output to website/static/public/js/<addon-name>/files.js
var addonModules = ['files.js', 'node-cfg.js', 'user-cfg.js', 'file-detail.js', 'widget-cfg.js'];
addons.addons.forEach(function(addonName) {
    var baseDir = addonName + '/';
    addonModules.forEach(function(module) {
        var modulePath = path.resolve(__dirname, 'addons',
                                  addonName, 'static', module);
        if (fs.existsSync(modulePath)) {
            var entryPoint = baseDir + module.split('.')[0];
            entry[entryPoint] =  modulePath;
        }
    });
    var logTextPath = path.resolve(__dirname, 'addons',
        addonName, 'static', addonName + 'LogActionList.json');
    if(fs.existsSync(logTextPath)){
        addonLog = require(logTextPath);
        for (var attrname in addonLog) { mainLogs[attrname] = addonLog[attrname]; }
    }
    var anonymousLogTextPath = path.resolve(__dirname, 'addons',
        addonName, 'static', addonName + 'AnonymousLogActionList.json');
    if(fs.existsSync(anonymousLogTextPath)) {
        anonymousAddonLog = require(anonymousLogTextPath);
        for (var log in anonymousAddonLog) { anonymousLogs[log] = anonymousAddonLog[log]; }
    }
});

fs.writeFileSync(staticPath('js/_allLogTexts.json'), JSON.stringify(mainLogs));
fs.writeFileSync(staticPath('js/_anonymousLogTexts.json'), JSON.stringify(anonymousLogs));

var resolve = {
    modules: [
        root,
        './website/static/vendor/bower_components',
        'node_modules',
    ],
    extensions: ['*', '.es6.js', '.js', '.min.js'],
    // Need to alias libraries that aren't managed by bower or npm
    alias: {
        'knockout-sortable': staticPath('vendor/knockout-sortable/knockout-sortable.js'),
        'bootstrap-editable': staticPath('vendor/bootstrap-editable-custom/js/bootstrap-editable.js'),
        'jquery-blockui': staticPath('vendor/jquery-blockui/jquery.blockui.js'),
        'bootstrap': nodePath('bootstrap/dist/js/bootstrap.js'),
        'Caret.js': staticPath('vendor/bower_components/Caret.js/dist/jquery.caret.min.js'),
        'osf-panel': staticPath('vendor/bower_components/osf-panel/dist/jquery-osfPanel.min.js'),
        'jquery-qrcode': staticPath('vendor/bower_components/jquery-qrcode/jquery.qrcode.min.js'),
        'jquery-tagsinput': staticPath('vendor/bower_components/jquery.tagsinput/jquery.tagsinput.js'),
        'clipboard': staticPath('vendor/bower_components/clipboard/dist/clipboard.js'),
        'history': nodePath('historyjs/scripts/bundled/html4+html5/jquery.history.js'),
        // Needed for knockout-sortable
        'jquery.ui.sortable': staticPath('vendor/bower_components/jquery-ui/ui/widgets/sortable.js'),
        'truncate': staticPath('vendor/bower_components/truncate/jquery.truncate.js'),
        // Needed for ace code editor in wiki
        'ace-noconflict': staticPath('vendor/bower_components/ace-builds/src-noconflict/ace.js'),
        'ace-ext-language_tools': staticPath('vendor/bower_components/ace-builds/src-noconflict/ext-language_tools.js'),
        'ace-mode-markdown': staticPath('vendor/bower_components/ace-builds/src-noconflict/mode-markdown.js'),
        'pagedown-ace-converter': addonsPath('wiki/static/pagedown-ace/Markdown.Converter.js'),
        'pagedown-ace-sanitizer': addonsPath('wiki/static/pagedown-ace/Markdown.Sanitizer.js'),
        'pagedown-ace-editor': addonsPath('wiki/static/pagedown-ace/Markdown.Editor.js'),
        'wikiPage': addonsPath('wiki/static/wikiPage.js'),
        'typo': staticPath('vendor/ace-plugins/typo.js'),
        'highlight-css': nodePath('highlight.js/styles/default.css'),
        'pikaday-css': nodePath('pikaday/css/pikaday.css'),
        // Also alias some internal libraries for easy access
        'addons': path.resolve(__dirname, 'addons'),
        'tests': staticPath('js/tests'),
        // GASP Items not defined as main in its package.json
        'TweenLite' : nodePath('gsap/src/minified/TweenLite.min.js'),
        'EasePack' : nodePath('gsap/src/minified/easing/EasePack.min.js'),
        'keen-dataset' : nodePath('keen-dataviz/lib/dataset/'),
    }
};

var externals = {
    // require("jquery") is external and available
    //  on the global var jQuery, which is loaded with CDN
    'jquery': 'jQuery',
    'jquery-ui': 'jQuery.ui',
    'raven-js': 'Raven',
    'MathJax': 'MathJax'
};

var plugins = [
    // Bundle common code between modules
    new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: 'vendor.js' }),
    // Make jQuery available in all modules without having to do require('jquery')
    new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery'
    }),
    // Slight hack to make sure that CommonJS is always used
    new webpack.DefinePlugin({
        'define.amd': false,
        '__ENABLE_DEV_MODE_CONTROLS': fs.existsSync(staticPath(path.join('built', 'git_logs.json')))
    }),
];

var output = {
    path: path.resolve(__dirname, 'website', 'static', 'public', 'js'),
    // publicPath: '/static/', // used to generate urls to e.g. images
    filename: '[name].js',
    sourcePrefix: ''
};

module.exports = {
    entry: entry,
    resolve: resolve,
    devtool: 'source-map',
    externals: externals,
    plugins: plugins,
    output: output,
    module: {
        rules: [
            {test: /\.es6\.js$/, exclude: [/node_modules/, /bower_components/, /vendor/], loader: 'babel-loader'},
            {test: /\.css$/, use: [{loader: 'style-loader'}, {loader: 'css-loader'}]},
            // url-loader uses DataUrls; files-loader emits files
            {test: /\.png$/, loader: 'url-loader?limit=100000&mimetype=image/ng'},
            {test: /\.gif$/, loader: 'url-loader?limit=10000&mimetype=image/gif'},
            {test: /\.jpg$/, loader: 'url-loader?limit=10000&mimetype=image/jpg'},
            {test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?mimetype=application/font-woff'},
            {test: /\.svg/, loader: 'file-loader'},
            {test: /\.eot/, loader: 'file-loader'},
            {test: /\.ttf/, loader: 'file-loader'},
            { parser: { amd: false }}
        ]
    },
    node: {
       fs: 'empty'
    }
};
<commit_msg>typo in image/png for url-loader<commit_after>var webpack = require('webpack');
var path = require('path');
var fs = require('fs');

var SaveAssetsJson = require('assets-webpack-plugin');

var addons = require('./addons.json');
var root = path.resolve(__dirname, 'website', 'static');
/** Return the absolute path given a path relative to ./website/static */
var staticPath = function(dir) {
    return path.resolve(root, dir);
};
var nodePath = function(dir) {
    return path.resolve(__dirname, 'node_modules', dir);
};
var addonsPath = function(dir) {
    return path.resolve(__dirname, 'addons', dir);
};

/**
 * Each JS module for a page on the OSF is webpack entry point. These are built
 * to website/static/public/
 */
var entry = {
    // JS
    'base-page': staticPath('js/pages/base-page.js'),
    'home-page': staticPath('js/pages/home-page.js'),
    'landing-page': staticPath('js/pages/landing-page.js'),
    'dashboard-page': staticPath('js/pages/dashboard-page.js'),
    'profile-page': staticPath('js/pages/profile-page.js'),
    'project-dashboard': staticPath('js/pages/project-dashboard-page.js'),
    'project-base-page': staticPath('js/pages/project-base-page.js'),
    'project-settings-page': staticPath('js/pages/project-settings-page.js'),
    'project-addons-page': staticPath('js/pages/project-addons-page.js'),
    'project-registrations-page': staticPath('js/pages/project-registrations-page.js'),
    'registration-retraction-page': staticPath('js/pages/registration-retraction-page.js'),
    'registration-edit-page': staticPath('js/pages/registration-edit-page.js'),
    'register-page': staticPath('js/pages/register-page.js'),
    'wiki-edit-page': staticPath('js/pages/wiki-edit-page.js'),
    'statistics-page': staticPath('js/pages/statistics-page.js'),
    'request-access-page': staticPath('js/pages/request-access-page.js'),
    'file-page': staticPath('js/pages/file-page.js'),
    'files-page': staticPath('js/pages/files-page.js'),
    'reg-landing-page': staticPath('js/pages/reg-landing-page.js'),
    'profile-settings-page': staticPath('js/pages/profile-settings-page.js'),
    'profile-account-settings-page': staticPath('js/pages/profile-account-settings-page.js'),
    'profile-settings-applications-list-page': staticPath('js/pages/profile-settings-applications-list-page.js'),
    'profile-settings-applications-detail-page': staticPath('js/pages/profile-settings-applications-detail-page.js'),
    'profile-settings-personal-tokens-list-page': staticPath('js/pages/profile-settings-personal-tokens-list-page.js'),
    'profile-settings-personal-tokens-detail-page': staticPath('js/pages/profile-settings-personal-tokens-detail-page.js'),
    'sharing-page': staticPath('js/pages/sharing-page.js'),
    'conference-page': staticPath('js/pages/conference-page.js'),
    'meetings-page': staticPath('js/pages/meetings-page.js'),
    'view-file-tree-page': staticPath('js/pages/view-file-tree-page.js'),
    'search-page': staticPath('js/pages/search-page.js'),
    'profile-settings-addons-page': staticPath('js/pages/profile-settings-addons-page.js'),
    'forgotpassword-page': staticPath('js/pages/forgotpassword-page.js'),
    'resetpassword-page': staticPath('js/pages/resetpassword-page.js'),
    'claimaccount-page': staticPath('js/pages/claimaccount-page.js'),
    'login-page': staticPath('js/pages/login-page.js'),
    'notifications-config-page': staticPath('js/pages/notifications-config-page.js'),
    'render-nodes': staticPath('js/pages/render-nodes.js'),
    'institution-page': staticPath('js/pages/institution-page.js'),
    // Commons chunk
    'vendor': [
        // Vendor libraries
        'knockout',
        'knockout.validation',
        'moment',
        'bootstrap',
        'bootbox',
        'bootstrap-editable',
        'select2',
        'dropzone',
        'knockout-sortable',
        'loaders.css',
        'treebeard',
        'lodash.get',
        'js-cookie',
        'URIjs',
        // Common internal modules
        'js/fangorn',
        'js/citations',
        'js/osfHelpers',
        'js/osfToggleHeight',
        'mithril',
        // Main CSS files that get loaded above the fold
        nodePath('select2/select2.css'),
        nodePath('bootstrap/dist/css/bootstrap.css'),
        '@centerforopenscience/osf-style',
        staticPath('css/style.css'),
    ],
};

// Collect log text from addons
var mainLogs = require(staticPath('js/logActionsList.json'));
var anonymousLogs = require(staticPath('js/anonymousLogActionsList.json'));
var addonLog;
var anonymousAddonLog;

// Collect addons endpoints. If an addon's static folder has
// any of the following files, it will be added as an entry point
// and output to website/static/public/js/<addon-name>/files.js
var addonModules = ['files.js', 'node-cfg.js', 'user-cfg.js', 'file-detail.js', 'widget-cfg.js'];
addons.addons.forEach(function(addonName) {
    var baseDir = addonName + '/';
    addonModules.forEach(function(module) {
        var modulePath = path.resolve(__dirname, 'addons',
                                  addonName, 'static', module);
        if (fs.existsSync(modulePath)) {
            var entryPoint = baseDir + module.split('.')[0];
            entry[entryPoint] =  modulePath;
        }
    });
    var logTextPath = path.resolve(__dirname, 'addons',
        addonName, 'static', addonName + 'LogActionList.json');
    if(fs.existsSync(logTextPath)){
        addonLog = require(logTextPath);
        for (var attrname in addonLog) { mainLogs[attrname] = addonLog[attrname]; }
    }
    var anonymousLogTextPath = path.resolve(__dirname, 'addons',
        addonName, 'static', addonName + 'AnonymousLogActionList.json');
    if(fs.existsSync(anonymousLogTextPath)) {
        anonymousAddonLog = require(anonymousLogTextPath);
        for (var log in anonymousAddonLog) { anonymousLogs[log] = anonymousAddonLog[log]; }
    }
});

fs.writeFileSync(staticPath('js/_allLogTexts.json'), JSON.stringify(mainLogs));
fs.writeFileSync(staticPath('js/_anonymousLogTexts.json'), JSON.stringify(anonymousLogs));

var resolve = {
    modules: [
        root,
        './website/static/vendor/bower_components',
        'node_modules',
    ],
    extensions: ['*', '.es6.js', '.js', '.min.js'],
    // Need to alias libraries that aren't managed by bower or npm
    alias: {
        'knockout-sortable': staticPath('vendor/knockout-sortable/knockout-sortable.js'),
        'bootstrap-editable': staticPath('vendor/bootstrap-editable-custom/js/bootstrap-editable.js'),
        'jquery-blockui': staticPath('vendor/jquery-blockui/jquery.blockui.js'),
        'bootstrap': nodePath('bootstrap/dist/js/bootstrap.js'),
        'Caret.js': staticPath('vendor/bower_components/Caret.js/dist/jquery.caret.min.js'),
        'osf-panel': staticPath('vendor/bower_components/osf-panel/dist/jquery-osfPanel.min.js'),
        'jquery-qrcode': staticPath('vendor/bower_components/jquery-qrcode/jquery.qrcode.min.js'),
        'jquery-tagsinput': staticPath('vendor/bower_components/jquery.tagsinput/jquery.tagsinput.js'),
        'clipboard': staticPath('vendor/bower_components/clipboard/dist/clipboard.js'),
        'history': nodePath('historyjs/scripts/bundled/html4+html5/jquery.history.js'),
        // Needed for knockout-sortable
        'jquery.ui.sortable': staticPath('vendor/bower_components/jquery-ui/ui/widgets/sortable.js'),
        'truncate': staticPath('vendor/bower_components/truncate/jquery.truncate.js'),
        // Needed for ace code editor in wiki
        'ace-noconflict': staticPath('vendor/bower_components/ace-builds/src-noconflict/ace.js'),
        'ace-ext-language_tools': staticPath('vendor/bower_components/ace-builds/src-noconflict/ext-language_tools.js'),
        'ace-mode-markdown': staticPath('vendor/bower_components/ace-builds/src-noconflict/mode-markdown.js'),
        'pagedown-ace-converter': addonsPath('wiki/static/pagedown-ace/Markdown.Converter.js'),
        'pagedown-ace-sanitizer': addonsPath('wiki/static/pagedown-ace/Markdown.Sanitizer.js'),
        'pagedown-ace-editor': addonsPath('wiki/static/pagedown-ace/Markdown.Editor.js'),
        'wikiPage': addonsPath('wiki/static/wikiPage.js'),
        'typo': staticPath('vendor/ace-plugins/typo.js'),
        'highlight-css': nodePath('highlight.js/styles/default.css'),
        'pikaday-css': nodePath('pikaday/css/pikaday.css'),
        // Also alias some internal libraries for easy access
        'addons': path.resolve(__dirname, 'addons'),
        'tests': staticPath('js/tests'),
        // GASP Items not defined as main in its package.json
        'TweenLite' : nodePath('gsap/src/minified/TweenLite.min.js'),
        'EasePack' : nodePath('gsap/src/minified/easing/EasePack.min.js'),
        'keen-dataset' : nodePath('keen-dataviz/lib/dataset/'),
    }
};

var externals = {
    // require("jquery") is external and available
    //  on the global var jQuery, which is loaded with CDN
    'jquery': 'jQuery',
    'jquery-ui': 'jQuery.ui',
    'raven-js': 'Raven',
    'MathJax': 'MathJax'
};

var plugins = [
    // Bundle common code between modules
    new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: 'vendor.js' }),
    // Make jQuery available in all modules without having to do require('jquery')
    new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery'
    }),
    // Slight hack to make sure that CommonJS is always used
    new webpack.DefinePlugin({
        'define.amd': false,
        '__ENABLE_DEV_MODE_CONTROLS': fs.existsSync(staticPath(path.join('built', 'git_logs.json')))
    }),
];

var output = {
    path: path.resolve(__dirname, 'website', 'static', 'public', 'js'),
    // publicPath: '/static/', // used to generate urls to e.g. images
    filename: '[name].js',
    sourcePrefix: ''
};

module.exports = {
    entry: entry,
    resolve: resolve,
    devtool: 'source-map',
    externals: externals,
    plugins: plugins,
    output: output,
    module: {
        rules: [
            {test: /\.es6\.js$/, exclude: [/node_modules/, /bower_components/, /vendor/], loader: 'babel-loader'},
            {test: /\.css$/, use: [{loader: 'style-loader'}, {loader: 'css-loader'}]},
            // url-loader uses DataUrls; files-loader emits files
            {test: /\.png$/, loader: 'url-loader?limit=100000&mimetype=image/png'},
            {test: /\.gif$/, loader: 'url-loader?limit=10000&mimetype=image/gif'},
            {test: /\.jpg$/, loader: 'url-loader?limit=10000&mimetype=image/jpg'},
            {test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?mimetype=application/font-woff'},
            {test: /\.svg/, loader: 'file-loader'},
            {test: /\.eot/, loader: 'file-loader'},
            {test: /\.ttf/, loader: 'file-loader'},
            { parser: { amd: false }}
        ]
    },
    node: {
       fs: 'empty'
    }
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Provider } from 'react-redux';
import Appbase from 'appbase-js';
import { ThemeProvider } from 'emotion-theming';

import configureStore from '@appbaseio/reactivecore';
import types from '@appbaseio/reactivecore/lib/utils/types';
import URLParamsProvider from './URLParamsProvider';

import theme from '../../styles/theme';

const URLSearchParams = require('url-search-params');

class ReactiveBase extends Component {
	constructor(props) {
		super(props);

		this.type = props.type ? props.type : '*';

		const credentials = props.url && props.url.trim() !== '' && props.credentials
			? props.credentials
			: null;

		const config = {
			url: props.url && props.url.trim() !== '' ? props.url : 'https://scalr.api.appbase.io',
			app: props.app,
			credentials,
			type: this.type,
		};

		this.params = new URLSearchParams(window.location.search);
		let selectedValues = {};

		try {
			Array.from(this.params.keys()).forEach((key) => {
				selectedValues = { ...selectedValues, [key]: { value: JSON.parse(this.params.get(key)) } };
			});
		} catch (e) {
			selectedValues = {};
		}

		const appbaseRef = new Appbase(config);
		this.store = configureStore({ config, appbaseRef, selectedValues });
	}

	render() {
		return (
			<ThemeProvider theme={{ ...theme, ...this.props.theme }}>
				<Provider store={this.store}>
					<URLParamsProvider params={this.params}>
						{this.props.children}
					</URLParamsProvider>
				</Provider>
			</ThemeProvider>
		);
	}
}

ReactiveBase.defaultProps = {
	theme: {},
};

ReactiveBase.propTypes = {
	type: types.string,
	url: types.string,
	credentials: types.string,
	app: types.stringRequired,
	children: types.children,
	theme: types.style,
};

export default ReactiveBase;
<commit_msg>web: fix credentials defaults<commit_after>import React, { Component } from 'react';
import { Provider } from 'react-redux';
import Appbase from 'appbase-js';
import { ThemeProvider } from 'emotion-theming';

import configureStore from '@appbaseio/reactivecore';
import types from '@appbaseio/reactivecore/lib/utils/types';
import URLParamsProvider from './URLParamsProvider';

import theme from '../../styles/theme';

const URLSearchParams = require('url-search-params');

class ReactiveBase extends Component {
	constructor(props) {
		super(props);

		this.type = props.type ? props.type : '*';

		const credentials = props.url && props.url.trim() !== '' && !props.credentials
			? 'user:pass'
			: props.credentials;

		const config = {
			url: props.url && props.url.trim() !== '' ? props.url : 'https://scalr.api.appbase.io',
			app: props.app,
			credentials,
			type: this.type,
		};

		this.params = new URLSearchParams(window.location.search);
		let selectedValues = {};

		try {
			Array.from(this.params.keys()).forEach((key) => {
				selectedValues = { ...selectedValues, [key]: { value: JSON.parse(this.params.get(key)) } };
			});
		} catch (e) {
			selectedValues = {};
		}

		const appbaseRef = new Appbase(config);
		this.store = configureStore({ config, appbaseRef, selectedValues });
	}

	render() {
		return (
			<ThemeProvider theme={{ ...theme, ...this.props.theme }}>
				<Provider store={this.store}>
					<URLParamsProvider params={this.params}>
						{this.props.children}
					</URLParamsProvider>
				</Provider>
			</ThemeProvider>
		);
	}
}

ReactiveBase.defaultProps = {
	theme: {},
};

ReactiveBase.propTypes = {
	type: types.string,
	url: types.string,
	credentials: types.string,
	app: types.stringRequired,
	children: types.children,
	theme: types.style,
};

export default ReactiveBase;
<|endoftext|>


<commit_before>#!/usr/bin/env node

/* eslint-disable */

var cli = require('promisify-cli');
var npm = require('promisify-npm');
var fs = require('promisify-fs');
var path = require('path');
var npmlog = require('npmlog');
/*npm log configuration*/
npmlog.heading = 'wbp';

/**log utils**/
function getModuleLog(module_name) {
  return {
    info: function (message, prefix) {
      npmlog.info(module_name + (prefix || ''), message);
    },
    warn: function (message, prefix) {
      npmlog.warn(module_name + (prefix || ''), message);
    },
    error: function (message, prefix) {
      npmlog.error(module_name + (prefix || ''), message);
    },
  }
}

/**
 * WBP Class
 */
var WBP = function () {
  this.log = getModuleLog('wbp');
}

/**
 * plugin name need to be normalized
 * {string}
 */
WBP.prototype.normalize = function (plugin_name) {
  var prefix = this.options.hasOwnProperty('prefix') && this.options.prefix === false ? '' : 'wbp-';
  if (!~plugin_name.indexOf(prefix)) return plugin_name = prefix + plugin_name;
  return plugin_name;
}

/**
 * call other plugins in wbp ecosystem, they may be downloaded on-demand.
 * promise
 */
WBP.prototype.call = function (plugin_name, params, options) {
  var self = this;
  var plugin_name = self.normalize(plugin_name);
  npm
    .hasInstalled(plugin_name, self.wbp_home)
    .then(function (installed) {
      if (!installed) {
        return npm.install(plugin_name, self.wbp_home);
      }
    })
    .then(function () {
      return self.wbp_home + '/node_modules/' + plugin_name;
    })
    .then(function (plugin_path) {
      //associated informations.
      var pluginContext = Object.assign({
          //constants
          __plugindir: plugin_path,
          __cwd: process.cwd(),
          __name: plugin_name
        },
        //utils log
        getModuleLog(plugin_name),
        //wbp utils
        {
          call: self.call.bind(self),
          getCwdPath: function (cwdPath) {
            return path.resolve(process.cwd(), cwdPath);
          }
        });

      //plugin is found.
      var pluginExports = require(plugin_path);
      if (pluginExports && pluginExports instanceof Function) {
        self.log.info(plugin_name + ' is loaded and invoked.');
        return pluginExports.call(pluginContext, self.params, self.options);
      } else {
        throw 'the plugin named ' + plugin_name + 'should export a function';
      }
    })
}

/**
 * wbp configuration from package
 * @return {[type]} [description]
 */
WBP.prototype.loadConfig = function () {
  this.log.info('loading wbp configuration.');

  var self = this;
  return fs
    .readFile(__dirname + '/../package.json')
    .then(JSON.parse)
    .get('wbp')
    .then(function (wbp_conf) {
      self.wbp_conf = wbp_conf;
    })
}

/**
 * init wbp constants and cli params and options
 * @return {[type]} [description]
 */
WBP.prototype.initwbp = function () {
  this.log.info('parsing command line interface.');

  var self = this;
  //wbp_home library
  self.wbp_home = self.wbp_conf.home.replace('~', process.env['HOME']);

  return cli()
    .then(function (cli) {
      //at least on param. help and exit
      if (!cli.params.length) {
        cli.help();
      }

      self.options = cli.options;
      self.params = cli.params;
    })
}

/**
 * call Plugin based on first param
 * @return {[type]} [description]
 */
WBP.prototype.callPlugin = function () {
  return this.call(this.params.shift());
}

//wbp is just a task collabrator.
var wbp = new WBP();
wbp
  .loadConfig()
  .then(wbp.initwbp.bind(wbp))
  .then(wbp.callPlugin.bind(wbp))
  .catch(function (e) {
    console.error('catch->', e);
  })

<commit_msg>local_dev_commit<commit_after>#!/usr/bin/env node

/* eslint-disable */

var cli = require('promisify-cli');
var npm = require('promisify-npm');
var fs = require('promisify-fs');
var path = require('path');
var npmlog = require('npmlog');
/*npm log configuration*/
npmlog.heading = 'wbp';

/**log utils**/
function getModuleLog(module_name) {
  return {
    info: function (message, prefix) {
      npmlog.info(module_name + (prefix || ''), message);
    },
    warn: function (message, prefix) {
      npmlog.warn(module_name + (prefix || ''), message);
    },
    error: function (message, prefix) {
      npmlog.error(module_name + (prefix || ''), message);
    },
  }
}

/**
 * WBP Class
 */
var WBP = function () {
  this.log = getModuleLog('wbp');
}

/**
 * plugin name need to be normalized
 * {string}
 */
WBP.prototype.normalize = function (plugin_name) {
  var prefix = this.options.hasOwnProperty('prefix') && this.options.prefix === false ? '' : 'wbp-';
  if (!~plugin_name.indexOf(prefix)) return plugin_name = prefix + plugin_name;
  return plugin_name;
}

/**
 * call other plugins in wbp ecosystem, they may be downloaded on-demand.
 * promise
 */
WBP.prototype.call = function (plugin_name, params, options) {
  var self = this;
  var plugin_name = self.normalize(plugin_name);
  npm
    .hasInstalled(plugin_name, self.wbp_home)
    .then(function (installed) {
      if (!installed) {
        self.log.info('wbp is going to install plugin [' + plugin_name + ']');
        return npm.install(plugin_name, self.wbp_home);
      }
    })
    .then(function () {
      return self.wbp_home + '/node_modules/' + plugin_name;
    })
    .then(function (plugin_path) {
      //associated informations.
      var pluginContext = Object.assign({
          //constants
          __plugindir: plugin_path,
          __cwd: process.cwd(),
          __name: plugin_name
        },
        //utils log
        getModuleLog(plugin_name),
        //wbp utils
        {
          call: self.call.bind(self),
          getCwdPath: function (cwdPath) {
            return path.resolve(process.cwd(), cwdPath);
          }
        });

      //plugin is found.
      var pluginExports = require(plugin_path);
      if (pluginExports && pluginExports instanceof Function) {
        self.log.info(plugin_name + ' is loaded and invoked.');
        return pluginExports.call(pluginContext, self.params, self.options);
      } else {
        throw 'the plugin named ' + plugin_name + 'should export a function';
      }
    })
}

/**
 * wbp configuration from package
 * @return {[type]} [description]
 */
WBP.prototype.loadConfig = function () {
  this.log.info('loading wbp configuration.');

  var self = this;
  return fs
    .readFile(__dirname + '/../package.json')
    .then(JSON.parse)
    .get('wbp')
    .then(function (wbp_conf) {
      self.wbp_conf = wbp_conf;
    })
}

/**
 * init wbp constants and cli params and options
 * @return {[type]} [description]
 */
WBP.prototype.initwbp = function () {
  this.log.info('parsing command line interface.');

  var self = this;
  //wbp_home library
  self.wbp_home = self.wbp_conf.home.replace('~', process.env['HOME']);

  return cli()
    .then(function (cli) {
      //at least on param. help and exit
      if (!cli.params.length) {
        cli.help();
      }

      self.options = cli.options;
      self.params = cli.params;
    })
}

/**
 * call Plugin based on first param
 * @return {[type]} [description]
 */
WBP.prototype.callPlugin = function () {
  return this.call(this.params.shift());
}

//wbp is just a task collabrator.
var wbp = new WBP();
wbp
  .loadConfig()
  .then(wbp.initwbp.bind(wbp))
  .then(wbp.callPlugin.bind(wbp))
  .catch(function (e) {
    console.error('catch->', e);
  })

<|endoftext|>


<commit_before>module.exports = ({ include, exclude } = {}) => ({
	module: {
		rules: [
			{
				test: /\.css$/,
				include,
				exclude,
				use: [
					"style-loader",
					"css-loader",
					{
						loader: "postcss-loader",
						options: {
							plugins: () => ([
								require("autoprefixer")
							])
						}
					}
				]
			}
		]
	}
});
<commit_msg>Reused the autoprefix config part for development.<commit_after>const autoprefix = require("./autoprefix");

module.exports = ({ include, exclude } = {}) => ({
	module: {
		rules: [
			{
				test: /\.css$/,
				include,
				exclude,
				use: [
					"style-loader",
					"css-loader",
					autoprefix()
				]
			}
		]
	}
});
<|endoftext|>


<commit_before>#!/usr/bin/env node

var lintStaged = require('../index')
<commit_msg>Removed ./bin<commit_after><|endoftext|>


<commit_before>/*eslint-env node*/

const path = require('path');
const autoprefixer = require('autoprefixer');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');

module.exports = {
    entry: {
        entry: './src/entry.js',
    },
    output: {
        path: path.resolve('./dist'),
        publicPath: '/dist/',
        filename: '[name].js',
        jsonpFunction: 'entryJsonp',
    },
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.json'],
        mainFields: ['jsnext:main', 'main', 'module', 'browser'],
    },
    node: {
        fs: 'empty',
    },
    module: {
        rules: [
            {
                test: /\.worker\.ts$/,
                use: {
                    loader: 'worker-loader',
                    options: {
                        inline: true,
                    },
                },
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'webpack-strip-block',
                        options: {
                            start: 'IGNORE_WEBPACK:START',
                            end: 'IGNORE_WEBPACK:END',
                        },
                    },
                    {
                        loader: 'babel-loader',
                    },
                ],
            },
            {
                // eslint-disable-next-line max-len
                test: /\.(ico|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|cur)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: 'url-loader',
                options: {
                    name: '[hash].[ext]',
                    limit: 10000,
                },
            },
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
                exclude: /node_modules/,
                options: { transpileOnly: true },
            },
            {
                test: /\.(css|less)$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            // you can specify a publ icPath here
                            // by default it use publicPath in webpackOptions.output
                            publicPath: '../',
                        },
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            url: false,
                            sourceMap: false,
                        },
                    },
                    {
                        loader: require.resolve('postcss-loader'),
                        options: {
                            ident: 'postcss',
                            plugins: () => [
                                require('postcss-flexbugs-fixes'),
                                require('cssnano')({ preset: 'default' }),
                                autoprefixer({
                                    overrideBrowserslist: [
                                        '>1%',
                                        'last 4 versions',
                                        'Firefox ESR',
                                        'not ie < 9', // React doesn't support IE8 anyway
                                    ],
                                    flexbox: 'no-2009',
                                    remove: false,
                                }),
                            ],
                        },
                    },
                    {
                        loader: 'less-loader',
                        options: {
                            sourceMap: false,
                        },
                    },
                ],
            },
        ],
    },
    externals: {
        react: 'React',
        'react-dom': 'ReactDOM',
        '@entrylabs/tool': 'EntryTool',
        'entry-paint': 'EntryPaint',
    },
    plugins: [
        new CleanWebpackPlugin(['dist'], {
            root: path.join(__dirname, '..'),
        }),
        new ManifestPlugin(),
        new MiniCssExtractPlugin({
            // Options similar to the same options in webpackOptions.output
            // both options are optional
            filename: '[name].css',
            chunkFilename: '[id].css',
        }),
    ],
};
<commit_msg>mainFileds 순서 변경<commit_after>/*eslint-env node*/

const path = require('path');
const autoprefixer = require('autoprefixer');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');

module.exports = {
    entry: {
        entry: './src/entry.js',
    },
    output: {
        path: path.resolve('./dist'),
        publicPath: '/dist/',
        filename: '[name].js',
        jsonpFunction: 'entryJsonp',
    },
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.json'],
        mainFields: ['jsnext:main', 'browser', 'main'],
    },
    node: {
        fs: 'empty',
    },
    module: {
        rules: [
            {
                test: /\.worker\.ts$/,
                use: {
                    loader: 'worker-loader',
                    options: {
                        inline: true,
                    },
                },
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'webpack-strip-block',
                        options: {
                            start: 'IGNORE_WEBPACK:START',
                            end: 'IGNORE_WEBPACK:END',
                        },
                    },
                    {
                        loader: 'babel-loader',
                    },
                ],
            },
            {
                // eslint-disable-next-line max-len
                test: /\.(ico|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|cur)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: 'url-loader',
                options: {
                    name: '[hash].[ext]',
                    limit: 10000,
                },
            },
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
                exclude: /node_modules/,
                options: { transpileOnly: true },
            },
            {
                test: /\.(css|less)$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            // you can specify a publ icPath here
                            // by default it use publicPath in webpackOptions.output
                            publicPath: '../',
                        },
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            url: false,
                            sourceMap: false,
                        },
                    },
                    {
                        loader: require.resolve('postcss-loader'),
                        options: {
                            ident: 'postcss',
                            plugins: () => [
                                require('postcss-flexbugs-fixes'),
                                require('cssnano')({ preset: 'default' }),
                                autoprefixer({
                                    overrideBrowserslist: [
                                        '>1%',
                                        'last 4 versions',
                                        'Firefox ESR',
                                        'not ie < 9', // React doesn't support IE8 anyway
                                    ],
                                    flexbox: 'no-2009',
                                    remove: false,
                                }),
                            ],
                        },
                    },
                    {
                        loader: 'less-loader',
                        options: {
                            sourceMap: false,
                        },
                    },
                ],
            },
        ],
    },
    externals: {
        react: 'React',
        'react-dom': 'ReactDOM',
        '@entrylabs/tool': 'EntryTool',
        'entry-paint': 'EntryPaint',
    },
    plugins: [
        new CleanWebpackPlugin(['dist'], {
            root: path.join(__dirname, '..'),
        }),
        new ManifestPlugin(),
        new MiniCssExtractPlugin({
            // Options similar to the same options in webpackOptions.output
            // both options are optional
            filename: '[name].css',
            chunkFilename: '[id].css',
        }),
    ],
};
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react'

class DataExport extends Component {
  componentDidMount () {
    const { dataExportMount } = this.props
    dataExportMount()
  }

  fixzero (value) {
    let valueToString = value.toString()
    return valueToString.length === 1 ? '0' + valueToString : valueToString
  }

  formatExportAt (widget) {
    let datetime = new Date(String(widget.exported_at))
    const date = this.fixzero(datetime.getDate()) + '/' + this.fixzero(datetime.getMonth() + 1) + '/' + datetime.getFullYear()
    const time = this.fixzero(datetime.getHours()) + ':' + this.fixzero(datetime.getMinutes())
    return date + ' às ' + time
  }

  renderLoadingMessage () {
    return

      Aguarde enquanto estamos processando...

  }

  renderExportedMessage () {
    const { widget } = this.props
    return
      Última exportação: {this.formatExportAt(widget)}.

  }

  renderErrorMessage () {
    const { error } = this.props
    return {error}
  }

  renderDisclaimer () {
    return

           Atenção

        Você está utilizando o navegador Safari. Os passos a seguir são
        necessários devido a uma incompatibilidade.

          Clique com o botão direito do mouse no botão abaixo e selecione
          a opção "Transferir Arquivo Vinculado Como..."

          Salve o arquivo com o nome desejado e a extensão .xlsx

  }

  renderSaveAsContainer () {
    const { loading } = this.props
    return

  }
  render () {
    const {
      mobilization,
      loading,
      error,
      success,
      widget,
      // Actions
      asyncWidgetDataExport
    } = this.props

    const filename = mobilization.name + '.xlsx'
    const adownloadSupport = process.env.BROWSER
      ? ('download' in document.createElement('a'))
      : false

    return (

          Exportar

          Clique no botão abaixo para baixar o relatório completo do
          formulário em formato excel.

          <button
            disabled={loading}
            className='btn bg-pagenta white caps p2 rounded'
            onClick={() => asyncWidgetDataExport({ mobilization, widget, filename })}
          >
            {adownloadSupport
              ? 'Clique para baixar a planilha completa.'
              : 'Clique para processar a planilha completa.'
            }
          </button>

          {(loading ? this.renderLoadingMessage() : null)}
          {(widget.exported_at && !loading ? this.renderExportedMessage() : null)}
          {(error ? this.renderErrorMessage() : null)}

        {(!adownloadSupport && !loading && success ? this.renderDisclaimer() : null)}
        {(!adownloadSupport ? this.renderSaveAsContainer() : null)}

    )
  }
}

DataExport.propTypes = {
  params: PropTypes.object.isRequired,
  loading: PropTypes.bool.isRequired,
  success: PropTypes.bool,
  error: PropTypes.object,
  widget: PropTypes.object.isRequired,
  // Actions
  asyncWidgetDataExport: PropTypes.func.isRequired,
  dataExportMount: PropTypes.func.isRequired
}

export default DataExport
<commit_msg>Use `exenv` lib to check use of DOM; Fix form entries report Safari disclaimer #450<commit_after>import React, { Component, PropTypes } from 'react'
import exenv from 'exenv'

class DataExport extends Component {
  componentDidMount () {
    const { dataExportMount } = this.props
    dataExportMount()
  }

  fixzero (value) {
    let valueToString = value.toString()
    return valueToString.length === 1 ? '0' + valueToString : valueToString
  }

  formatExportAt (widget) {
    let datetime = new Date(String(widget.exported_at))
    const date = this.fixzero(datetime.getDate()) + '/' + this.fixzero(datetime.getMonth() + 1) + '/' + datetime.getFullYear()
    const time = this.fixzero(datetime.getHours()) + ':' + this.fixzero(datetime.getMinutes())
    return date + ' às ' + time
  }

  renderLoadingMessage () {
    return

      Aguarde enquanto estamos processando...

  }

  renderExportedMessage () {
    const { widget } = this.props
    return
      Última exportação: {this.formatExportAt(widget)}.

  }

  renderErrorMessage () {
    const { error } = this.props
    return {error}
  }

  renderDisclaimer () {
    return

           Atenção

        Você está utilizando o navegador Safari. Os passos a seguir são
        necessários devido a uma incompatibilidade.

          Clique com o botão direito do mouse no botão abaixo e selecione
          a opção "Transferir Arquivo Vinculado Como..."

          Salve o arquivo com o nome desejado e a extensão .xlsx

  }

  renderSaveAsContainer () {
    const { loading } = this.props
    return

  }
  render () {
    const {
      mobilization,
      loading,
      error,
      success,
      widget,
      // Actions
      asyncWidgetDataExport
    } = this.props

    const filename = mobilization.name + '.xlsx'
    const adownloadSupport = exenv.canUseDOM
      ? ('download' in document.createElement('a'))
      : false

    return (

          Exportar

          Clique no botão abaixo para baixar o relatório completo do
          formulário em formato excel.

          <button
            disabled={loading}
            className='btn bg-pagenta white caps p2 rounded'
            onClick={() => asyncWidgetDataExport({ mobilization, widget, filename })}
          >
            {adownloadSupport
              ? 'Clique para baixar a planilha completa.'
              : 'Clique para processar a planilha completa.'
            }
          </button>

          {(loading ? this.renderLoadingMessage() : null)}
          {(widget.exported_at && !loading ? this.renderExportedMessage() : null)}
          {(error ? this.renderErrorMessage() : null)}

        {(!adownloadSupport && !loading && success ? this.renderDisclaimer() : null)}
        {(!adownloadSupport ? this.renderSaveAsContainer() : null)}

    )
  }
}

DataExport.propTypes = {
  params: PropTypes.object.isRequired,
  loading: PropTypes.bool.isRequired,
  success: PropTypes.bool,
  error: PropTypes.object,
  widget: PropTypes.object.isRequired,
  // Actions
  asyncWidgetDataExport: PropTypes.func.isRequired,
  dataExportMount: PropTypes.func.isRequired
}

export default DataExport
<|endoftext|>


<commit_before>Frontend.Dialog = Class.extend({
    /**
     * History keeper
     *
     * @type object
     */
    _history: {
        upcoming: null,
        entries: []
    },

    /**
     * Modal instance
     *
     * @type object
     */
    _modal: null,

    /**
     * Indicator if modal is currently open
     *
     * @type bool
     */
    _modalOpen: false,

    /**
     * Configuration
     *
     * @type object
     */
    _config: {
        selectTab: false,
        additionalClasses: false,
        initController: true,
        replaceTarget: false,
        preventHistory: false,
        onLoadComplete: false,
        onDialogClose: false
    },

    /**
     * Open dialog from action
     *
     * @param  object  url             Request URL in CakePHP style
     * @param  object  requestOptions  Request options for loadJsonAction
     * @return void
     */
    loadDialog: function(url, requestOptions) {
        if (!this._checkForModalTemplate()) {
            return false;
        }

        this._config = jQuery.extend(this._config, requestOptions, {
            onComplete: function(controller, response) {
                if (response.data.redirect) {
                    var redirectUrl = response.data.redirect;
                    if (typeof redirectUrl === 'object') {
                        redirectUrl = App.Main.Router.url(redirectUrl);
                    }

                    window.location = redirectUrl;
                    return
                }
                // Error handling
                if (!response.data.html) {
                    return console.error('No response HTML available.');
                }

                // Initialize new dialog
                this._modal = $('.modal');
                // Content setter
                this._setContent(response.data.html);

                selectedTab = null;
                // Tab selector
                if (this._config.selectTab) {
                    $(this._config.selectTab).tab('show');
                    selectedTab = this._config.selectTab;
                }

                // Large modal option
                if (this._config.additionalClasses) {
                    $('.modal-dialog', this._modal).addClass(this._config.additionalClasses);
                }

                // Modal Initialize
                this._modal.modal({
                    backdrop: true,
                    keyboard: true,
                    focus: true,
                    show: true
                });

                // History and events
                this._addHistory(url, this._config.preventHistory, selectedTab);
                this._registerHandler();

                if (typeof this._config.onLoadComplete === 'function') {
                    this._config.onLoadComplete(controller, response);
                }

                App.Main.UIBlocker.unblockElement($(this._getBlockElement()));

                if (response.data.closeDialog) {
                    this._cleanupModal();
                }
            }.bind(this)
        });

        App.Main.UIBlocker.blockElement($(this._getBlockElement()));
        App.Main.loadJsonAction(this._ensureDialogAction(url), this._config);
    },

    /**
     * Determine which element to block the ui for
     *
     * @return string
     */
    _getBlockElement: function() {
        var blockElement = 'body';
        if (this._modalOpen) {
            blockElement = '.modal-dialog';
        }

        return blockElement;
    },

    /**
     * Set content of the modal
     *
     * @param  string  content  HTML Content
     * @return void
     */
    _setContent: function(content) {
        this._modal.html(content);
    },

    /**
     * Modal existence checker
     *
     * @return bool
     */
    _checkForModalTemplate: function()
    {
        if (!$('.modal').length) {
            console.error('You need to load the modal template through FrontendBrigeHelper::includeModal function into DOM.');
            return false;
        }

        return true;
    },

    /**
     * Add item to history
     *
     * @param  object  url              Request URL in CakePHP style
     * @param  bool    preventUpcoming  Prevent writing of a new upcoming entry
     * @param  string  selectedTab      Selected tab
     * @return void
     */
    _addHistory: function(url, preventUpcoming, selectedTab) {
        if (this._history.upcoming && !preventUpcoming) {
            this._history.entries.push(this._history.upcoming);
        }
        if (preventUpcoming && this._history.entries.length > 0) {
            url = null;
        }

        if (url) {
            url = {
                url: url,
                title: $('.modal-title', this._modal).html(),
                selectedTab: selectedTab
            };
        }
        this._history.upcoming = url;
    },

    /**
     * Bind handlers and do conditional stuff.
     *
     * @return void
     */
    _registerHandler: function() {
        this._modal.off('hidden.bs.modal').on('hidden.bs.modal', function(e) {
            this._cleanupModal();
            this._history = {
                upcoming: null,
                entries: []
            };
            $('.modal-dialog', this._modal).removeClass('modal-lg');
            this._modalOpen = false;

            if (typeof this._config.onDialogClose === 'function') {
                this._config.onDialogClose(this);
            }
        }.bind(this));

        this._modal.on('shown.bs.modal', function () {
            this._modalOpen = true;
        }.bind(this));

        $(document).on('keyup', function(e) {
            if (!this._modal) {
                return;
            }

            // Escape key
            if (e.keyCode === 27) {
                this._modal.modal('hide');
            }
        }.bind(this));

        $('.modal-header .close, .modal-header .close-btn, .modal-footer .cancel-button', this._modal).off('click').on('click', function(e) {
            e.preventDefault();
            this._modal.modal('hide');
        }.bind(this));

        $('form', this._modal).off('submit').on('submit', function(e) {
            e.preventDefault();

            this._cleanupModal();
            App.Main.UIBlocker.blockElement($(this._getBlockElement()));
            var url = $(e.currentTarget).attr('action');

            var formData = null;
            if (!!window.FormData) {
                formData = new FormData(e.currentTarget);
            } else {
                formData = $(e.currentTarget).serialize();
            }

            this.loadDialog(url, {
                data: formData,
                preventHistory: true
            });
        }.bind(this));

        if (this._history.entries.length > 0) {
            $('.modal-back', this._modal).show();
        } else {
            $('.modal-back', this._modal).hide();
        }

        $('.modal-back', this._modal).off('click').on('click', function(e) {
            if (this._history.entries.length <= 0) {
                return;
            }

            this._cleanupModal();

            App.Main.UIBlocker.blockElement($(this._getBlockElement()));
            var url = this._history.entries.pop();
            this.loadDialog(url.url, {
                preventHistory: true,
                modalTitle: url.title,
                selectTab: url.selectedTab
            });
            App.Main.UIBlocker.unblockElement($(this._getBlockElement()));
        }.bind(this));

        $('.nav-tabs.historized a[data-toggle="tab"]', this._modal).on('shown.bs.tab', function (e) {
            // Update tab in history
            if (typeof $(e.target).attr('class') === 'string' && this._history.upcoming) {
                this._history.upcoming.selectedTab = '.' + $(e.target).attr('class');
            }
        }.bind(this))
    },

    /**
     * Ensure addition of json_action=1 and dialog_action=1 at a url which is no cakephp conform array.
     *
     * @param   mixed  url  URL to check for
     * @return  mixed
     */
    _ensureDialogAction: function(url) {
        if (typeof url === 'object') {
            if (url.hasOwnProperty('query')) {
                url.query.dialog_action = 1;
            } else {
                url.query = {
                    dialog_action: 1
                }
            }

            return url;
        }

        if (typeof url !== 'string') {
            return url;
        }

        if (url.indexOf('json_action=1') !== -1 && url.indexOf('dialog_action=1') !== -1) {
            return url;
        }

        if (url.indexOf('?') !== -1) {
            url += '&';
        } else {
            url += '?';
        }
        url += 'json_action=1&dialog_action=1';

        return url;
    },

    /**
     * Removes controller instance from instance keeper.
     *
     * @return void
     */
    _cleanupModal: function() {
        if (!this._modal) {
            return;
        }

        App.Main.cleanControllerInstances(this._modal);
    }
});
<commit_msg>Add option to prevent ajax submission of forms<commit_after>Frontend.Dialog = Class.extend({
    /**
     * History keeper
     *
     * @type object
     */
    _history: {
        upcoming: null,
        entries: []
    },

    /**
     * Modal instance
     *
     * @type object
     */
    _modal: null,

    /**
     * Indicator if modal is currently open
     *
     * @type bool
     */
    _modalOpen: false,

    /**
     * Configuration
     *
     * @type object
     */
    _config: {
        selectTab: false,
        additionalClasses: false,
        initController: true,
        replaceTarget: false,
        preventHistory: false,
        onLoadComplete: false,
        onDialogClose: false
    },

    /**
     * Open dialog from action
     *
     * @param  object  url             Request URL in CakePHP style
     * @param  object  requestOptions  Request options for loadJsonAction
     * @return void
     */
    loadDialog: function(url, requestOptions) {
        if (!this._checkForModalTemplate()) {
            return false;
        }

        this._config = jQuery.extend(this._config, requestOptions, {
            onComplete: function(controller, response) {
                if (response.data.redirect) {
                    var redirectUrl = response.data.redirect;
                    if (typeof redirectUrl === 'object') {
                        redirectUrl = App.Main.Router.url(redirectUrl);
                    }

                    window.location = redirectUrl;
                    return
                }
                // Error handling
                if (!response.data.html) {
                    return console.error('No response HTML available.');
                }

                // Initialize new dialog
                this._modal = $('.modal');
                // Content setter
                this._setContent(response.data.html);

                selectedTab = null;
                // Tab selector
                if (this._config.selectTab) {
                    $(this._config.selectTab).tab('show');
                    selectedTab = this._config.selectTab;
                }

                // Large modal option
                if (this._config.additionalClasses) {
                    $('.modal-dialog', this._modal).addClass(this._config.additionalClasses);
                }

                // Modal Initialize
                this._modal.modal({
                    backdrop: true,
                    keyboard: true,
                    focus: true,
                    show: true
                });

                // History and events
                this._addHistory(url, this._config.preventHistory, selectedTab);
                this._registerHandler();

                if (typeof this._config.onLoadComplete === 'function') {
                    this._config.onLoadComplete(controller, response);
                }

                App.Main.UIBlocker.unblockElement($(this._getBlockElement()));

                if (response.data.closeDialog) {
                    this._cleanupModal();
                }
            }.bind(this)
        });

        App.Main.UIBlocker.blockElement($(this._getBlockElement()));
        App.Main.loadJsonAction(this._ensureDialogAction(url), this._config);
    },

    /**
     * Determine which element to block the ui for
     *
     * @return string
     */
    _getBlockElement: function() {
        var blockElement = 'body';
        if (this._modalOpen) {
            blockElement = '.modal-dialog';
        }

        return blockElement;
    },

    /**
     * Set content of the modal
     *
     * @param  string  content  HTML Content
     * @return void
     */
    _setContent: function(content) {
        this._modal.html(content);
    },

    /**
     * Modal existence checker
     *
     * @return bool
     */
    _checkForModalTemplate: function()
    {
        if (!$('.modal').length) {
            console.error('You need to load the modal template through FrontendBrigeHelper::includeModal function into DOM.');
            return false;
        }

        return true;
    },

    /**
     * Add item to history
     *
     * @param  object  url              Request URL in CakePHP style
     * @param  bool    preventUpcoming  Prevent writing of a new upcoming entry
     * @param  string  selectedTab      Selected tab
     * @return void
     */
    _addHistory: function(url, preventUpcoming, selectedTab) {
        if (this._history.upcoming && !preventUpcoming) {
            this._history.entries.push(this._history.upcoming);
        }
        if (preventUpcoming && this._history.entries.length > 0) {
            url = null;
        }

        if (url) {
            url = {
                url: url,
                title: $('.modal-title', this._modal).html(),
                selectedTab: selectedTab
            };
        }
        this._history.upcoming = url;
    },

    /**
     * Bind handlers and do conditional stuff.
     *
     * @return void
     */
    _registerHandler: function() {
        this._modal.off('hidden.bs.modal').on('hidden.bs.modal', function(e) {
            this._cleanupModal();
            this._history = {
                upcoming: null,
                entries: []
            };
            $('.modal-dialog', this._modal).removeClass('modal-lg');
            this._modalOpen = false;

            if (typeof this._config.onDialogClose === 'function') {
                this._config.onDialogClose(this);
            }
        }.bind(this));

        this._modal.on('shown.bs.modal', function () {
            this._modalOpen = true;
        }.bind(this));

        $(document).on('keyup', function(e) {
            if (!this._modal) {
                return;
            }

            // Escape key
            if (e.keyCode === 27) {
                this._modal.modal('hide');
            }
        }.bind(this));

        $('.modal-header .close, .modal-header .close-btn, .modal-footer .cancel-button', this._modal).off('click').on('click', function(e) {
            e.preventDefault();
            this._modal.modal('hide');
        }.bind(this));

        $('form', this._modal).off('submit').on('submit', function(e) {
            var $target = $(e.currentTarget);
            if($target.data('ajax-submit') === 0) {
                return;
            }

            e.preventDefault();

            this._cleanupModal();
            App.Main.UIBlocker.blockElement($(this._getBlockElement()));
            var url = $(e.currentTarget).attr('action');

            var formData = null;
            if (!!window.FormData) {
                formData = new FormData(e.currentTarget);
            } else {
                formData = $(e.currentTarget).serialize();
            }

            this.loadDialog(url, {
                data: formData,
                preventHistory: true
            });
        }.bind(this));

        if (this._history.entries.length > 0) {
            $('.modal-back', this._modal).show();
        } else {
            $('.modal-back', this._modal).hide();
        }

        $('.modal-back', this._modal).off('click').on('click', function(e) {
            if (this._history.entries.length <= 0) {
                return;
            }

            this._cleanupModal();

            App.Main.UIBlocker.blockElement($(this._getBlockElement()));
            var url = this._history.entries.pop();
            this.loadDialog(url.url, {
                preventHistory: true,
                modalTitle: url.title,
                selectTab: url.selectedTab
            });
            App.Main.UIBlocker.unblockElement($(this._getBlockElement()));
        }.bind(this));

        $('.nav-tabs.historized a[data-toggle="tab"]', this._modal).on('shown.bs.tab', function (e) {
            // Update tab in history
            if (typeof $(e.target).attr('class') === 'string' && this._history.upcoming) {
                this._history.upcoming.selectedTab = '.' + $(e.target).attr('class');
            }
        }.bind(this))
    },

    /**
     * Ensure addition of json_action=1 and dialog_action=1 at a url which is no cakephp conform array.
     *
     * @param   mixed  url  URL to check for
     * @return  mixed
     */
    _ensureDialogAction: function(url) {
        if (typeof url === 'object') {
            if (url.hasOwnProperty('query')) {
                url.query.dialog_action = 1;
            } else {
                url.query = {
                    dialog_action: 1
                }
            }

            return url;
        }

        if (typeof url !== 'string') {
            return url;
        }

        if (url.indexOf('json_action=1') !== -1 && url.indexOf('dialog_action=1') !== -1) {
            return url;
        }

        if (url.indexOf('?') !== -1) {
            url += '&';
        } else {
            url += '?';
        }
        url += 'json_action=1&dialog_action=1';

        return url;
    },

    /**
     * Removes controller instance from instance keeper.
     *
     * @return void
     */
    _cleanupModal: function() {
        if (!this._modal) {
            return;
        }

        App.Main.cleanControllerInstances(this._modal);
    }
});
<|endoftext|>


<commit_before>#!/usr/bin/env node

const formatter = require('../index');
const pkg = require('../package');

const program = require('commander')
    .version(pkg.version)
    .description(`${pkg.name} (v${pkg.version}): ${pkg.description}`)
    .usage('<file>')
    .arguments('<file>')
    .parse(process.argv);

formatter(program.args[0])
    .then(html => console.log(html));<commit_msg>fix(bin): adjust bin file after changes to signature of index.js<commit_after>#!/usr/bin/env node

const formatter = require('../index');
const pkg = require('../package');
const path = require('path');
const promisifyAll = require('bluebird').promisifyAll;
const fs = promisifyAll(require('fs'));

const program = require('commander')
    .version(pkg.version)
    .description(`${pkg.name} (v${pkg.version}): ${pkg.description}`)
    .usage('<file>')
    .arguments('<file>')
    .parse(process.argv);

const srcFilename = path.join(program.args[0]);

fs.readFileAsync(srcFilename, 'utf8')
    .then(readme => formatter(readme))
    .then(html => console.log(html))
    .catch(err => console.error(err));<|endoftext|>


<commit_before>import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import { Grid, Row, Col } from 'react-bootstrap';

// Import Components
import PostList from '../../components/PostList';
import PostCreateWidget from '../../components/PostCreateWidget/PostCreateWidget';

// Import Actions
import { addPostRequest, fetchPosts, deletePostRequest, editPostRequest } from '../../PostActions';
import { toggleAddPost, showAddPost } from '../../../App/AppActions';

// Import Selectors
import { getShowAddPost } from '../../../App/AppReducer';
import { getPosts } from '../../PostReducer';

class PostListPage extends Component {
  componentDidMount() {
    this.props.dispatch(fetchPosts());
  }

  editingPost = null;

  handleDeletePost = post => {
    if (confirm('Haluatko varmasti poistaa viestin?')) { // eslint-disable-line
      this.props.dispatch(deletePostRequest(post));
    }
  };

  handleAddPost = (name, content, important) => {
    this.props.dispatch(toggleAddPost());
    this.props.dispatch(addPostRequest({ name, content, important }));
    this.props.dispatch(fetchPosts());
  };

  handleEditPost = post => {

    this.props.dispatch(toggleAddPost());
    this.props.dispatch(editPostRequest(post));
    setTimeout(100)
    this.props.dispatch(fetchPosts());
    this.editingPost = null;

  };

  handleHidePost = () => {

    this.props.dispatch(toggleAddPost());
    this.editingPost = null;
  };

  openEditPost = post => {
    this.editingPost = post;
    this.props.dispatch(showAddPost());
    this.setState({}); //update ui

  };

  render() {
    return (

        <PostCreateWidget
          addPost={this.handleAddPost} showAddPost={this.props.showAddPost}
          hideAddPost={this.handleHidePost} editPost={this.handleEditPost}
          originalPost={this.editingPost}
        />
        <Grid>
          <Row className="show-grid">
            <Col xs={16} md={4}>
              <PostList
                handleDeletePost={this.handleDeletePost} posts={this.props.posts}
                handleEditPost={this.openEditPost} importanceColumn={true}
              />
            </Col>
            <Col xs={12} md={7}>
              <PostList
                handleDeletePost={this.handleDeletePost} posts={this.props.posts}
                handleEditPost={this.openEditPost} importanceColumn={false}
              />
            </Col>
          </Row>
        </Grid>

    );
  }
}

// Actions required to provide data for this component to render in sever side.
PostListPage.need = [() => { return fetchPosts(); }];

// Retrieve data from store as props
function mapStateToProps(state) {
  return {
    showAddPost: getShowAddPost(state),
    posts: getPosts(state),
  };
}

PostListPage.propTypes = {
  posts: PropTypes.arrayOf(PropTypes.shape({
    name: PropTypes.string.isRequired,
    content: PropTypes.string.isRequired,
    important: PropTypes.bool.isRequired,
  })).isRequired,
  showAddPost: PropTypes.bool.isRequired,
  dispatch: PropTypes.func.isRequired,
};

PostListPage.contextTypes = {
  router: React.PropTypes.object,
};

export default connect(mapStateToProps)(PostListPage);
<commit_msg>Turhat fetchPosts poistettu<commit_after>import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import { Grid, Row, Col } from 'react-bootstrap';

// Import Components
import PostList from '../../components/PostList';
import PostCreateWidget from '../../components/PostCreateWidget/PostCreateWidget';

// Import Actions
import { addPostRequest, fetchPosts, deletePostRequest, editPostRequest } from '../../PostActions';
import { toggleAddPost, showAddPost } from '../../../App/AppActions';

// Import Selectors
import { getShowAddPost } from '../../../App/AppReducer';
import { getPosts } from '../../PostReducer';

class PostListPage extends Component {
  componentDidMount() {
    this.props.dispatch(fetchPosts());
  }

  editingPost = null;

  handleDeletePost = post => {
    if (confirm('Haluatko varmasti poistaa viestin?')) { // eslint-disable-line
      this.props.dispatch(deletePostRequest(post));
    }
  };

  handleAddPost = (name, content, important) => {
    this.props.dispatch(toggleAddPost());
    this.props.dispatch(addPostRequest({ name, content, important }));
    };

  handleEditPost = post => {

    this.props.dispatch(toggleAddPost());
    this.props.dispatch(editPostRequest(post));
    setTimeout(100)
    this.editingPost = null;

  };

  handleHidePost = () => {

    this.props.dispatch(toggleAddPost());
    this.editingPost = null;
  };

  openEditPost = post => {
    this.editingPost = post;
    this.props.dispatch(showAddPost());
    this.setState({}); //update ui

  };

  render() {
    return (

        <PostCreateWidget
          addPost={this.handleAddPost} showAddPost={this.props.showAddPost}
          hideAddPost={this.handleHidePost} editPost={this.handleEditPost}
          originalPost={this.editingPost}
        />
        <Grid>
          <Row className="show-grid">
            <Col xs={16} md={4}>
              <PostList
                handleDeletePost={this.handleDeletePost} posts={this.props.posts}
                handleEditPost={this.openEditPost} importanceColumn={true}
              />
            </Col>
            <Col xs={12} md={7}>
              <PostList
                handleDeletePost={this.handleDeletePost} posts={this.props.posts}
                handleEditPost={this.openEditPost} importanceColumn={false}
              />
            </Col>
          </Row>
        </Grid>

    );
  }
}

// Actions required to provide data for this component to render in sever side.
PostListPage.need = [() => { return fetchPosts(); }];

// Retrieve data from store as props
function mapStateToProps(state) {
  return {
    showAddPost: getShowAddPost(state),
    posts: getPosts(state),
  };
}

PostListPage.propTypes = {
  posts: PropTypes.arrayOf(PropTypes.shape({
    name: PropTypes.string.isRequired,
    content: PropTypes.string.isRequired,
    important: PropTypes.bool.isRequired,
  })).isRequired,
  showAddPost: PropTypes.bool.isRequired,
  dispatch: PropTypes.func.isRequired,
};

PostListPage.contextTypes = {
  router: React.PropTypes.object,
};

export default connect(mapStateToProps)(PostListPage);
<|endoftext|>


<commit_before>/**
 * fileOverview Client code etc.
 */

var dataMap, URL_REGEXP, QUERY_URL_REGEXP;

/**
 * Map for canvas data.
 * @type {Object}
 */
dataMap = {};

/**
 * @type {RegExp}
 */
URL_REGEXP = /^https?:\/\//

/**
 * @type {RegExp}
 */
QUERY_URL_REGEXP = /^.*https?:\/\//

/**
 * @return {boolean}
 */
Template.secretForm.isMissingSecret = function() {
  var hasSecret = Config.findOne({hasSecret: true});
  return !hasSecret;
};

Template.secretForm.events({
  /**
   * @param {Object} event
   */
  'submit form' : function(event) {
    var secret, channel, nick;
    event.preventDefault();
    secret = $('.secret-input').val();
    channel = $('.channel-input').val();
    nick = $('.nick-input').val();
    Config.insert({
      hasSecret: true,
      secret: secret,
      channel: channel,
      nick: nick
    });
  }
});

Template.dashboard.namesCount = function() {
  var names;
  names = Names.find({}, {sort: {ts: -1}, limit: 1}).fetch();
  if (_.isEmpty(names)) {
    return 0;
  }
  return names[0].names.length;
};

Template.dashboard.recentMessages = function() {
  var messages;
  messages = Messages.find({}, {sort: {ts:-1}, limit: 20});
  return Template.list(messages);
};

/**
 * @param {Object.<string, number>}
 * @return {Array.<Object>}
 */
function getLeaderBoardFromMap(map) {
  var results;
  results = _.map(map, function(count, name) {
    return {name: name, count: count};
  });
  results = _.sortBy(results, function(person) {
    return person.count * -1;
  });
  return Template.leaderboard(results);
};

Template.dashboard.topAactive = function() {
  var messages, countMap;
  messages = Messages.find({});
  countMap = {};
  messages.forEach(function(message) {
    if(!_.has(countMap, message.nick)) {
      return countMap[message.nick] = 1;
    }
    countMap[message.nick] += 1;
  });
  return getLeaderBoardFromMap(countMap);
};

Template.linechart.rendered = function() {
  var id, element;
  element = this.find('svg');
  id = $(element).attr('data-id');
  drawLine(dataMap[id], element);
};

Template.dashboard.online = function() {
  var names, data;
  names = Names.find({});
  data = [];
  names.forEach(function(nameset) {
    data.push({
      count: nameset.names.length,
      ts: nameset.ts
    });
  });
  dataMap.online = data;
  return Template.linechart({id: 'online'});
};

/**
 * @param {number} interval
 */
function getMessagesPerInterval(interval) {
  var messages, data, currentTime, currentCount, i;
  now = new Date().getTime();
  data = [];
  messages = Messages.find({}, {sort: {ts: 1}}).fetch();
  if (_.isEmpty(messages)) {
    return [];
  }
  message = messages[0];
  currentTime = message.ts;
  i = 0;
  while(currentTime < now) {
    currentCount = 0;
    if (i >= messages.length) {
      // No more messages, just add 0 for remaining hours.
      data.push({count: currentCount, ts: currentTime});
      currentTime += interval;
      continue;
    }
    while(message.ts < currentTime + interval) {
      currentCount += 1;
      i += 1;
      if (i >= messages.length) {
        break;
      }
      message = messages[i];
    }
    data.push({
      count: currentCount,
      ts: currentTime
    });
    currentTime += interval;
  }
  console.log('data', data);
  return data;
}

Template.dashboard.messagesPerHour = function() {
  dataMap.messagesPerHour = getMessagesPerInterval(60 * 60 * 1000);
  return Template.linechart({id: 'messagesPerHour'});
};

Template.dashboard.messagesPerDay = function() {
  dataMap.messagesPerDay = getMessagesPerInterval(24 * 60 * 60 * 1000);
  return Template.linechart({id: 'messagesPerDay'});
};

Template.dashboard.topURLs = function() {
  var messages, URLs;
  URLs = {};
  messages = Messages.find({message: {$regex: QUERY_URL_REGEXP}});
  messages.forEach(function(m) {
    var words, urls
    words = m.message.split(' ');
    urls = _.filter(words, function(word) {
      console.log('word', word);
      return URL_REGEXP.test(word);
    });
    _.each(urls, function(url) {
      if (!_.has(URLs, url)) {
        return URLs[url] = 1;
      }
      URLs[url] += 1;
    });
  });
  console.log('urls', URLs);
  return getLeaderBoardFromMap(URLs);
};

/**
 * @param {Array.<Object>} data
 * @param {Element} element
 */
function drawLine(data, svg) {
  var e, width, height, line, xValues, yValues, yAxis, xAxis;
  width = 300;
  height = 100;
  e = d3.select(svg)
    .attr('width', width)
    .attr('height', height);
  x = d3.time.scale().range([0, width]);
  y = d3.scale.linear().range([height, 0]);
  xValues = _.map(_.values(data), function(d) {
    return d.ts;
  });
  yValues = _.map(_.values(data), function(d) {
    return d.count;
  });
  x.domain([d3.min(xValues), d3.max(xValues)]);
  y.domain([d3.min(yValues), d3.max(yValues)]);
  line = d3.svg.line()
    .interpolate('basis')
    .x(function(d) {
      return x(d.ts);
    })
    .y(function(d) {
      return y(d.count);
    })
  yAxis = d3.svg.axis()
    .scale(y)
    .ticks(4)
    .tickSubdivide(0)
    .tickFormat(function(value) {
      var floored;
      floored = Math.round(value);
      if (floored !== value) {
        return;
      }
      return value;
    })
    .orient('left');
  xAxis = d3.svg.axis()
    .scale(x)
    .orient('bottom')
  e.append('g')
    .attr('class', 'y axis')
    .call(yAxis)
    .append('text')
    .attr('transform', 'rotate(-90)')
    .attr('y', 6)
    .attr('dy', '.71em')
    .style('text-anchor', 'end')
  e.append('g')
    .attr('class', 'x axis')
    .attr('transform', 'translate(0,' + height + ')')
    .call(xAxis);
  e.append('path').attr('d', line(data))
    .style('stroke', '#00f')
    .style('stroke-width', '1px')
    .style('fill', 'none');

}
<commit_msg>Cut off day charts at beginning of day.<commit_after>/**
 * fileOverview Client code etc.
 */

var dataMap, URL_REGEXP, QUERY_URL_REGEXP;

/**
 * Map for canvas data.
 * @type {Object}
 */
dataMap = {};

/**
 * @type {RegExp}
 */
URL_REGEXP = /^https?:\/\//

/**
 * @type {RegExp}
 */
QUERY_URL_REGEXP = /^.*https?:\/\//

/**
 * @return {boolean}
 */
Template.secretForm.isMissingSecret = function() {
  var hasSecret = Config.findOne({hasSecret: true});
  return !hasSecret;
};

Template.secretForm.events({
  /**
   * @param {Object} event
   */
  'submit form' : function(event) {
    var secret, channel, nick;
    event.preventDefault();
    secret = $('.secret-input').val();
    channel = $('.channel-input').val();
    nick = $('.nick-input').val();
    Config.insert({
      hasSecret: true,
      secret: secret,
      channel: channel,
      nick: nick
    });
  }
});

Template.dashboard.namesCount = function() {
  var names;
  names = Names.find({}, {sort: {ts: -1}, limit: 1}).fetch();
  if (_.isEmpty(names)) {
    return 0;
  }
  return names[0].names.length;
};

Template.dashboard.recentMessages = function() {
  var messages;
  messages = Messages.find({}, {sort: {ts:-1}, limit: 20});
  return Template.list(messages);
};

/**
 * @param {Object.<string, number>}
 * @return {Array.<Object>}
 */
function getLeaderBoardFromMap(map) {
  var results;
  results = _.map(map, function(count, name) {
    return {name: name, count: count};
  });
  results = _.sortBy(results, function(person) {
    return person.count * -1;
  });
  return Template.leaderboard(results);
};

Template.dashboard.topAactive = function() {
  var messages, countMap;
  messages = Messages.find({});
  countMap = {};
  messages.forEach(function(message) {
    if(!_.has(countMap, message.nick)) {
      return countMap[message.nick] = 1;
    }
    countMap[message.nick] += 1;
  });
  return getLeaderBoardFromMap(countMap);
};

Template.linechart.rendered = function() {
  var id, element;
  element = this.find('svg');
  id = $(element).attr('data-id');
  drawLine(dataMap[id], element);
};

Template.dashboard.online = function() {
  var names, data;
  names = Names.find({});
  data = [];
  names.forEach(function(nameset) {
    data.push({
      count: nameset.names.length,
      ts: nameset.ts
    });
  });
  dataMap.online = data;
  return Template.linechart({id: 'online'});
};

/**
 * @param {number} interval
 */
function getMessagesPerInterval(interval) {
  var messages, data, currentTime, currentCount, i, currentDate;
  now = new Date().getTime();
  data = [];
  messages = Messages.find({}, {sort: {ts: 1}}).fetch();
  if (_.isEmpty(messages)) {
    return [];
  }
  message = messages[0];
  currentDate = new Date(message.ts);
  currentDate.setHours(0);
  currentDate.setMinutes(0);
  currentDate.setSeconds(0);
  currentTime = currentDate.getTime();
  i = 0;
  while(currentTime < now) {
    currentCount = 0;
    if (i >= messages.length) {
      // No more messages, just add 0 for remaining hours.
      data.push({count: currentCount, ts: currentTime});
      currentTime += interval;
      continue;
    }
    while(message.ts < currentTime + interval) {
      currentCount += 1;
      i += 1;
      if (i >= messages.length) {
        break;
      }
      message = messages[i];
    }
    data.push({
      count: currentCount,
      ts: currentTime
    });
    currentTime += interval;
  }
  return data;
}

Template.dashboard.messagesPerHour = function() {
  dataMap.messagesPerHour = getMessagesPerInterval(60 * 60 * 1000);
  return Template.linechart({id: 'messagesPerHour'});
};

Template.dashboard.messagesPerDay = function() {
  dataMap.messagesPerDay = getMessagesPerInterval(24 * 60 * 60 * 1000);
  return Template.linechart({id: 'messagesPerDay'});
};

Template.dashboard.topURLs = function() {
  var messages, URLs;
  URLs = {};
  messages = Messages.find({message: {$regex: QUERY_URL_REGEXP}});
  messages.forEach(function(m) {
    var words, urls
    words = m.message.split(' ');
    urls = _.filter(words, function(word) {
      return URL_REGEXP.test(word);
    });
    _.each(urls, function(url) {
      if (!_.has(URLs, url)) {
        return URLs[url] = 1;
      }
      URLs[url] += 1;
    });
  });
  return getLeaderBoardFromMap(URLs);
};

/**
 * @param {Array.<Object>} data
 * @param {Element} element
 */
function drawLine(data, svg) {
  var e, width, height, line, xValues, yValues, yAxis, xAxis;
  width = 300;
  height = 100;
  e = d3.select(svg)
    .attr('width', width)
    .attr('height', height);
  x = d3.time.scale().range([0, width]);
  y = d3.scale.linear().range([height, 0]);
  xValues = _.map(_.values(data), function(d) {
    return d.ts;
  });
  yValues = _.map(_.values(data), function(d) {
    return d.count;
  });
  x.domain([d3.min(xValues), d3.max(xValues)]);
  y.domain([d3.min(yValues), d3.max(yValues)]);
  line = d3.svg.line()
    .interpolate('basis')
    .x(function(d) {
      return x(d.ts);
    })
    .y(function(d) {
      return y(d.count);
    })
  yAxis = d3.svg.axis()
    .scale(y)
    .ticks(4)
    .tickSubdivide(0)
    .tickFormat(function(value) {
      var floored;
      floored = Math.round(value);
      if (floored !== value) {
        return;
      }
      return value;
    })
    .orient('left');
  xAxis = d3.svg.axis()
    .scale(x)
    .orient('bottom')
  e.append('g')
    .attr('class', 'y axis')
    .call(yAxis)
    .append('text')
    .attr('transform', 'rotate(-90)')
    .attr('y', 6)
    .attr('dy', '.71em')
    .style('text-anchor', 'end')
  e.append('g')
    .attr('class', 'x axis')
    .attr('transform', 'translate(0,' + height + ')')
    .call(xAxis);
  e.append('path').attr('d', line(data))
    .style('stroke', '#00f')
    .style('stroke-width', '1px')
    .style('fill', 'none');

}
<|endoftext|>


<commit_before>var express = require('express');
var app = express();
var bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

/**
 *
 * args:
 *   keywords - keywords separated by comma
 *   width - display width
 *   height - display height
 *   src - source web address
**/
app.get('/getDonationLink', function (req, res) {
  var keywords = req.query.keywords;
  var width = req.query.width;
  var height = req.query.height;
  var src = req.query.src;
  res.type('html');

  console.log('keywords: [%s], width: [%s], height: [%s]', keywords, width, height);

  if (!isValidArgument(keywords, width, height)) {
    res.send('invalid arugment');
    return;
  }

  keywords = keywords.split(',');

  res.send(getDonationLink(keywords, width, height, src));
});

var getDonationLink = function(keywords, width, height, src) {
  // add entry to database to keep track of all queries

  // derive and return html

  return 'hello world';
}

var isValidArgument = function(keywords, width, height) {
  if (!keywords || !width || !height) {
    return false;
  }

  if (!isNumeric(width) || !isNumeric(height)) {
    return false;
  }

  return true;
}

var isNumeric = function(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

var server = app.listen(process.env.PORT || 7080, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});
<commit_msg>add additional meta_keywords and more updates<commit_after>var express = require('express');
var app = express();
var bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

/**
 *
 * args:
 *   keywords - comma separated keywords inputed by user
 *   meta_keywords - comma separated keywords auto extracted from web src
 *   width - display width in pixels
 *   height - display height in pixels
 *   src - source web address
**/
app.get('/getDonationLink', function (req, res) {
  var args = {
    keywords: req.query.keywords || '',
    meta_keywords: req.query.meta_keywords || '',
    width: req.query.width || 500,
    height: req.query.height || 110,
    src: req.query.src || null
  }
  var argError = validateArgs(args);

  console.log('keywords: [%s], argError: [%s]', JSON.stringify(args), argError);
  res.type('text/html');

  if (argError) {
    res.send(argError);
    return;
  }

  res.send(getDonationLink(args));
});

var getDonationLink = function(args) {
  // add entry to database to keep track of all queries

  // derive and return html

  return 'hello world';
}

var validateArgs = function(args) {
  if (args.keywords.length == 0 && args.meta_keywords.length == 0) {
    return 'missing keywords, please provide keywords';
  }

  if (!isNumeric(args.width)) {
    return 'invalid width';
  }

  if (!isNumeric(args.height)) {
    return 'invalid height';
  }

  args.width = Math.round(args.width);
  args.height = Math.round(args.height);

  return null;
}

var isNumeric = function(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

var server = app.listen(process.env.PORT || 7080, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});
<|endoftext|>


<commit_before>export const HEX_WIDTH = 100
export const HEX_HEIGHT = Math.sqrt(3) / 2 * HEX_WIDTH
const HEX_OFFSET_RATIO = 1.1
const HEX_OFFSET_WIDTH = HEX_OFFSET_RATIO * 3 / 4 * HEX_WIDTH
const HEX_OFFSET_HEIGHT = HEX_OFFSET_RATIO * HEX_HEIGHT
const HEX_STRENGTH_SIZE = 0.25 * HEX_HEIGHT

const COLOR_HEX_ACTIVE = 0xFFFFFF
const COLOR_HEX_INACTIVE = 0x999999

export default class CellInterface {
  /**
   * @param {Cell} cell
   * @param {PIXI.Application} pixiApp
   * @param {Game} game
   */
  constructor (cell, pixiApp, game) {
    /** @type {Cell} */
    this.cell = cell

    /** @type {PIXI.Application} */
    this.pixiApp = pixiApp

    /** @type {Game} */
    this.game = game

    /** @type {PIXI.Graphics|null} */
    this.hex = null
  }

  initialize () {
    let self = this

    this.hex = this.createHex(this.cell)

    this.pixiApp.stage.addChild(this.hex)

    this.game.events.listen('cellDrained', function (data) {
      if (self.cell === data.cell) {
        self.hex.strength.text = self.cell.strength !== 0 ? self.cell.strength : ''
      }
    })
    this.game.events.listen('gameStateChanged', function (data) {
      self.hex.tint = data.state.canClickCell(self.cell) ? COLOR_HEX_ACTIVE : COLOR_HEX_INACTIVE
      self.hex.strength.style.stroke = self.hex.tint
    })
  }

  /**
   * @param {Cell} cell
   * @return {PIXI.Sprite}
   */
  createHex (cell) {
    let hex = new PIXI.Graphics()

    hex.lineStyle(10, COLOR_HEX_ACTIVE, 1)
    hex.beginFill(cell.config.color)
    hex.drawPolygon(
      new PIXI.Point(0, HEX_HEIGHT / 2),
      new PIXI.Point(HEX_WIDTH / 4, 0),
      new PIXI.Point(3 * HEX_WIDTH / 4, 0),
      new PIXI.Point(HEX_WIDTH, HEX_HEIGHT / 2),
      new PIXI.Point(3 * HEX_WIDTH / 4, HEX_HEIGHT),
      new PIXI.Point(HEX_WIDTH / 4, HEX_HEIGHT),
      new PIXI.Point(0, HEX_HEIGHT / 2)
    )
    hex.endFill()
    hex.pivot = new PIXI.Point(HEX_WIDTH / 2, HEX_HEIGHT / 2)
    hex.tint = this.game.state.canClickCell(this.cell) ? COLOR_HEX_ACTIVE : COLOR_HEX_INACTIVE

    let size = this.calculateSize()

    hex.width = size * HEX_WIDTH
    hex.height = size * HEX_HEIGHT

    let coordinate = cell.coordinate
    hex.x = size * HEX_OFFSET_WIDTH * coordinate.x + this.pixiApp.renderer.width / 2
    hex.y = size * HEX_OFFSET_HEIGHT * (coordinate.z + coordinate.x / 2) + this.pixiApp.renderer.height / 2

    hex.strength = new PIXI.Text(cell.strength !== 0 ? cell.strength : '', {
      stroke: hex.tint,
      strokeThickness: HEX_STRENGTH_SIZE / 3,
      fontSize: HEX_STRENGTH_SIZE,
      fontWeight: 900
    })
    hex.strength.x = HEX_WIDTH / 4
    hex.strength.y = 0
    hex.strength.anchor = new PIXI.Point(0.25, 0.25)
    hex.addChild(hex.strength)

    hex.interactive = true
    hex.on('mouseup', () => this.game.cellClick(cell))

    return hex
  }

  /**
   * @return {number}
   */
  calculateSize () {
    let boardSize = this.game.board.gameConfig.boardSize

    let xSize = this.pixiApp.renderer.width / HEX_OFFSET_WIDTH / (boardSize * 2 + 1)
    let ySize = this.pixiApp.renderer.height / HEX_OFFSET_HEIGHT / (boardSize * 2 + 1)

    return Math.min(xSize, ySize)
  }

  remove () {
    this.pixiApp.stage.removeChild(this.hex)
  }
}
<commit_msg>refactoring: CellInterface.createHex does not accept argument, reads data from this.cell instead<commit_after>export const HEX_WIDTH = 100
export const HEX_HEIGHT = Math.sqrt(3) / 2 * HEX_WIDTH
const HEX_OFFSET_RATIO = 1.1
const HEX_OFFSET_WIDTH = HEX_OFFSET_RATIO * 3 / 4 * HEX_WIDTH
const HEX_OFFSET_HEIGHT = HEX_OFFSET_RATIO * HEX_HEIGHT
const HEX_STRENGTH_SIZE = 0.25 * HEX_HEIGHT

const COLOR_HEX_ACTIVE = 0xFFFFFF
const COLOR_HEX_INACTIVE = 0x999999

export default class CellInterface {
  /**
   * @param {Cell} cell
   * @param {PIXI.Application} pixiApp
   * @param {Game} game
   */
  constructor (cell, pixiApp, game) {
    /** @type {Cell} */
    this.cell = cell

    /** @type {PIXI.Application} */
    this.pixiApp = pixiApp

    /** @type {Game} */
    this.game = game

    /** @type {PIXI.Graphics|null} */
    this.hex = null
  }

  initialize () {
    let self = this

    this.hex = this.createHex()

    this.pixiApp.stage.addChild(this.hex)

    this.game.events.listen('cellDrained', function (data) {
      if (self.cell === data.cell) {
        self.hex.strength.text = self.cell.strength !== 0 ? self.cell.strength : ''
      }
    })
    this.game.events.listen('gameStateChanged', function (data) {
      self.hex.tint = data.state.canClickCell(self.cell) ? COLOR_HEX_ACTIVE : COLOR_HEX_INACTIVE
      self.hex.strength.style.stroke = self.hex.tint
    })
  }

  /**
   * @return {PIXI.Sprite}
   */
  createHex () {
    let hex = new PIXI.Graphics()

    hex.lineStyle(10, COLOR_HEX_ACTIVE, 1)
    hex.beginFill(this.cell.config.color)
    hex.drawPolygon(
      new PIXI.Point(0, HEX_HEIGHT / 2),
      new PIXI.Point(HEX_WIDTH / 4, 0),
      new PIXI.Point(3 * HEX_WIDTH / 4, 0),
      new PIXI.Point(HEX_WIDTH, HEX_HEIGHT / 2),
      new PIXI.Point(3 * HEX_WIDTH / 4, HEX_HEIGHT),
      new PIXI.Point(HEX_WIDTH / 4, HEX_HEIGHT),
      new PIXI.Point(0, HEX_HEIGHT / 2)
    )
    hex.endFill()
    hex.pivot = new PIXI.Point(HEX_WIDTH / 2, HEX_HEIGHT / 2)
    hex.tint = this.game.state.canClickCell(this.cell) ? COLOR_HEX_ACTIVE : COLOR_HEX_INACTIVE

    let size = this.calculateSize()

    hex.width = size * HEX_WIDTH
    hex.height = size * HEX_HEIGHT

    let coordinate = this.cell.coordinate
    hex.x = size * HEX_OFFSET_WIDTH * coordinate.x + this.pixiApp.renderer.width / 2
    hex.y = size * HEX_OFFSET_HEIGHT * (coordinate.z + coordinate.x / 2) + this.pixiApp.renderer.height / 2

    hex.strength = new PIXI.Text(this.cell.strength !== 0 ? this.cell.strength : '', {
      stroke: hex.tint,
      strokeThickness: HEX_STRENGTH_SIZE / 3,
      fontSize: HEX_STRENGTH_SIZE,
      fontWeight: 900
    })
    hex.strength.x = HEX_WIDTH / 4
    hex.strength.y = 0
    hex.strength.anchor = new PIXI.Point(0.25, 0.25)
    hex.addChild(hex.strength)

    hex.interactive = true
    hex.on('mouseup', () => this.game.cellClick(this.cell))

    return hex
  }

  /**
   * @return {number}
   */
  calculateSize () {
    let boardSize = this.game.board.gameConfig.boardSize

    let xSize = this.pixiApp.renderer.width / HEX_OFFSET_WIDTH / (boardSize * 2 + 1)
    let ySize = this.pixiApp.renderer.height / HEX_OFFSET_HEIGHT / (boardSize * 2 + 1)

    return Math.min(xSize, ySize)
  }

  remove () {
    this.pixiApp.stage.removeChild(this.hex)
  }
}
<|endoftext|>