<commit_before>'use strict';

var iteratorSymbol = require('es6-symbol').iterator
  , toArray        = require('es5-ext/array/to-array')
  , Map            = require('../../primitive')

  , compare, mapToResults;

compare = function (a, b) {
	if (!a.value) return -1;
	if (!b.value) return 1;
	return a.value[0].localeCompare(b.value[0]);
};

mapToResults = function (arr) {
	return arr.sort().map(function (value) {
		return { done: false, value: value };
	});
};

module.exports = function (T) {
	return {
		"": function (a) {
			var arr, it, y, z, map, result = [];

			arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'],
				['cztery', 'four'], ['pięć', 'five']];
			map = new Map(arr);

			it = new T(map);
			a(it[iteratorSymbol](), it, "@@iterator");
			y = it.next();
			result.push(y);
			z = it.next();
			a.not(y, z, "Recreate result");
			result.push(z);
			result.push(it.next());
			result.push(it.next());
			result.push(it.next());
			a.deep(result.sort(compare), mapToResults(arr));
			a.deep(y = it.next(), { done: true, value: undefined }, "End");
			a.not(y, it.next(), "Recreate result on dead");
		},
		"Emited": function (a) {
			var arr, it, map, result = [];

			arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'],
				['cztery', 'four'], ['pięć', 'five']];
			map = new Map(arr);

			it = new T(map);
			result.push(it.next());
			result.push(it.next());
			map.set('sześć', 'six');
			arr.push(['sześć', 'six']);
			result.push(it.next());
			map.delete('pięć');
			arr.splice(4, 1);
			result.push(it.next());
			result.push(it.next());
			a.deep(result.sort(compare), mapToResults(arr));
			a.deep(it.next(), { done: true, value: undefined }, "End");
		},
		"Emited #2": function (a) {
			var arr, it, map, result = [];

			arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'],
				['cztery', 'four'], ['pięć', 'five'], ['sześć', 'six']];
			map = new Map(arr);

			it = new T(map);
			result.push(it.next());
			result.push(it.next());
			map.set('siedem', 'seven');
			map.delete('siedem');
			result.push(it.next());
			result.push(it.next());
			map.delete('pięć');
			arr.splice(4, 1);
			result.push(it.next());
			a.deep(result.sort(compare), mapToResults(arr));
			a.deep(it.next(), { done: true, value: undefined }, "End");
		},
		"Emited: Clear #1": function (a) {
			var arr, it, map, result = [];

			arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'],
				['cztery', 'four'], ['pięć', 'five'], ['sześć', 'six']];
			map = new Map(arr);

			it = new T(map);
			result.push(it.next());
			result.push(it.next());
			arr = [['raz', 'one'], ['dwa', 'two']];
			map.clear();
			a.deep(result.sort(compare), mapToResults(arr));
			a.deep(it.next(), { done: true, value: undefined }, "End");
		},
		"Emited: Clear #2": function (a) {
			var arr, it, map, result = [];

			arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'],
				['cztery', 'four'], ['pięć', 'five'], ['sześć', 'six']];
			map = new Map(arr);

			it = new T(map);
			result.push(it.next());
			result.push(it.next());
			map.clear();
			map.set('foo', 'bru');
			map.set('bar', 'far');
			arr = [['raz', 'one'], ['dwa', 'two'], ['foo', 'bru'], ['bar', 'far']];
			result.push(it.next());
			result.push(it.next());
			a.deep(result.sort(compare), mapToResults(arr));
			a.deep(it.next(), { done: true, value: undefined }, "End");
		},
		"Kinds": function (a) {
			var arr = [['raz', 'one'], ['dwa', 'two']], map = new Map(arr);

			a.deep(toArray(new T(map)).sort(), arr.sort(), "Default");
			a.deep(toArray(new T(map, 'key+value')).sort(), arr.sort(),
				"Key + Value");
			a.deep(toArray(new T(map, 'value')).sort(), ['one', 'two'].sort(),
				"Value");
			a.deep(toArray(new T(map, 'key')).sort(), ['raz', 'dwa'].sort(),
				"Key");
		}
	};
};
<commit_msg>-- lint<commit_after>'use strict';

var iteratorSymbol = require('es6-symbol').iterator
  , toArray        = require('es5-ext/array/to-array')
  , Map            = require('../../primitive')

  , compare, mapToResults;

compare = function (a, b) {
	if (!a.value) return -1;
	if (!b.value) return 1;
	return a.value[0].localeCompare(b.value[0]);
};

mapToResults = function (arr) {
	return arr.sort().map(function (value) {
		return { done: false, value: value };
	});
};

module.exports = function (T) {
	return {
		"": function (a) {
			var arr, it, y, z, map, result = [];

			arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'],
				['cztery', 'four'], ['pięć', 'five']];
			map = new Map(arr);

			it = new T(map);
			a(it[iteratorSymbol](), it, "@@iterator");
			y = it.next();
			result.push(y);
			z = it.next();
			a.not(y, z, "Recreate result");
			result.push(z);
			result.push(it.next());
			result.push(it.next());
			result.push(it.next());
			a.deep(result.sort(compare), mapToResults(arr));
			a.deep(y = it.next(), { done: true, value: undefined }, "End");
			a.not(y, it.next(), "Recreate result on dead");
		},
		Emited: function (a) {
			var arr, it, map, result = [];

			arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'],
				['cztery', 'four'], ['pięć', 'five']];
			map = new Map(arr);

			it = new T(map);
			result.push(it.next());
			result.push(it.next());
			map.set('sześć', 'six');
			arr.push(['sześć', 'six']);
			result.push(it.next());
			map.delete('pięć');
			arr.splice(4, 1);
			result.push(it.next());
			result.push(it.next());
			a.deep(result.sort(compare), mapToResults(arr));
			a.deep(it.next(), { done: true, value: undefined }, "End");
		},
		"Emited #2": function (a) {
			var arr, it, map, result = [];

			arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'],
				['cztery', 'four'], ['pięć', 'five'], ['sześć', 'six']];
			map = new Map(arr);

			it = new T(map);
			result.push(it.next());
			result.push(it.next());
			map.set('siedem', 'seven');
			map.delete('siedem');
			result.push(it.next());
			result.push(it.next());
			map.delete('pięć');
			arr.splice(4, 1);
			result.push(it.next());
			a.deep(result.sort(compare), mapToResults(arr));
			a.deep(it.next(), { done: true, value: undefined }, "End");
		},
		"Emited: Clear #1": function (a) {
			var arr, it, map, result = [];

			arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'],
				['cztery', 'four'], ['pięć', 'five'], ['sześć', 'six']];
			map = new Map(arr);

			it = new T(map);
			result.push(it.next());
			result.push(it.next());
			arr = [['raz', 'one'], ['dwa', 'two']];
			map.clear();
			a.deep(result.sort(compare), mapToResults(arr));
			a.deep(it.next(), { done: true, value: undefined }, "End");
		},
		"Emited: Clear #2": function (a) {
			var arr, it, map, result = [];

			arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'],
				['cztery', 'four'], ['pięć', 'five'], ['sześć', 'six']];
			map = new Map(arr);

			it = new T(map);
			result.push(it.next());
			result.push(it.next());
			map.clear();
			map.set('foo', 'bru');
			map.set('bar', 'far');
			arr = [['raz', 'one'], ['dwa', 'two'], ['foo', 'bru'], ['bar', 'far']];
			result.push(it.next());
			result.push(it.next());
			a.deep(result.sort(compare), mapToResults(arr));
			a.deep(it.next(), { done: true, value: undefined }, "End");
		},
		Kinds: function (a) {
			var arr = [['raz', 'one'], ['dwa', 'two']], map = new Map(arr);

			a.deep(toArray(new T(map)).sort(), arr.sort(), "Default");
			a.deep(toArray(new T(map, 'key+value')).sort(), arr.sort(),
				"Key + Value");
			a.deep(toArray(new T(map, 'value')).sort(), ['one', 'two'].sort(),
				"Value");
			a.deep(toArray(new T(map, 'key')).sort(), ['raz', 'dwa'].sort(),
				"Key");
		}
	};
};
<|endoftext|>


<commit_before>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

/*eslint-env mocha*/

const { ipcRenderer } = require('electron');
const assert = require('assert');
const path = require('path');
const glob = require('glob');
const util = require('util');
const bootstrap = require('../../src/bootstrap');
const coverage = require('../coverage');

// Disabled custom inspect. See #38847
if (util.inspect && util.inspect['defaultOptions']) {
	util.inspect['defaultOptions'].customInspect = false;
}

let _tests_glob = '**/test/**/*.test.js';
let loader;
let _out;

function initLoader(opts) {
	let outdir = opts.build ? 'out-build' : 'out';
	_out = path.join(__dirname, `../../${outdir}`);

	// setup loader
	loader = require(`${_out}/vs/loader`);
	const loaderConfig = {
		nodeRequire: require,
		nodeMain: __filename,
		catchError: true,
		baseUrl: bootstrap.uriFromPath(path.join(__dirname, '../../src')),
		paths: {
			'vs': `../${outdir}/vs`,
			'lib': `../${outdir}/lib`,
			'bootstrap-fork': `../${outdir}/bootstrap-fork`
		}
	};

	if (opts.coverage) {
		// initialize coverage if requested
		coverage.initialize(loaderConfig);
	}

	loader.require.config(loaderConfig);
}

function loadTestModules(opts) {

	if (opts.run) {
		const files = Array.isArray(opts.run) ? opts.run : [opts.run];
		const modules = files.map(file => {
			file = file.replace(/^src/, 'out');
			file = file.replace(/\.ts$/, '.js');
			return path.relative(_out, file).replace(/\.js$/, '');
		});
		return new Promise((resolve, reject) => {
			loader.require(modules, resolve, reject);
		});
	}

	const pattern = opts.runGlob || _tests_glob;

	return new Promise((resolve, reject) => {
		glob(pattern, { cwd: _out }, (err, files) => {
			if (err) {
				reject(err);
				return;
			}
			const modules = files.map(file => file.replace(/\.js$/, ''));
			resolve(modules);
		});
	}).then(modules => {
		return new Promise((resolve, reject) => {
			loader.require(modules, resolve, reject);
		});
	});
}

function loadTests(opts) {

	const _unexpectedErrors = [];
	const _loaderErrors = [];

	// collect loader errors
	loader.require.config({
		onError(err) {
			_loaderErrors.push(err);
			console.error(err);
		}
	});

	// collect unexpected errors
	loader.require(['vs/base/common/errors'], function (errors) {
		errors.setUnexpectedErrorHandler(function (err) {
			let stack = (err ? err.stack : null);
			if (!stack) {
				stack = new Error().stack;
			}

			_unexpectedErrors.push((err && err.message ? err.message : err) + '\n' + stack);
		});
	});

	loader.require([opts])

	return loadTestModules(opts).then(() => {
		suite('Unexpected Errors & Loader Errors', function () {
			test('should not have unexpected errors', function () {
				const errors = _unexpectedErrors.concat(_loaderErrors);
				if (errors.length) {
					errors.forEach(function (stack) {
						console.error('');
						console.error(stack);
					});
					assert.ok(false, errors);
				}
			});
		});
	});
}

function serializeSuite(suite) {
	return {
		root: suite.root,
		suites: suite.suites.map(serializeSuite),
		tests: suite.tests.map(serializeRunnable),
		title: suite.title,
		fullTitle: suite.fullTitle(),
		timeout: suite.timeout(),
		retries: suite.retries(),
		enableTimeouts: suite.enableTimeouts(),
		slow: suite.slow(),
		bail: suite.bail()
	};
}

function serializeRunnable(runnable) {
	return {
		title: runnable.title,
		fullTitle: runnable.fullTitle(),
		async: runnable.async,
		slow: runnable.slow(),
		speed: runnable.speed,
		duration: runnable.duration
	};
}

function serializeError(err) {
	return {
		message: err.message,
		stack: err.stack,
		actual: err.actual,
		expected: err.expected,
		uncaught: err.uncaught,
		showDiff: err.showDiff,
		inspect: typeof err.inspect === 'function' ? err.inspect() : ''
	};
}

class IPCReporter {

	constructor(runner) {
		runner.on('start', () => ipcRenderer.send('start'));
		runner.on('end', () => ipcRenderer.send('end'));
		runner.on('suite', suite => ipcRenderer.send('suite', serializeSuite(suite)));
		runner.on('suite end', suite => ipcRenderer.send('suite end', serializeSuite(suite)));
		runner.on('test', test => ipcRenderer.send('test', serializeRunnable(test)));
		runner.on('test end', test => ipcRenderer.send('test end', serializeRunnable(test)));
		runner.on('hook', hook => ipcRenderer.send('hook', serializeRunnable(hook)));
		runner.on('hook end', hook => ipcRenderer.send('hook end', serializeRunnable(hook)));
		runner.on('pass', test => ipcRenderer.send('pass', serializeRunnable(test)));
		runner.on('fail', (test, err) => ipcRenderer.send('fail', serializeRunnable(test), serializeError(err)));
		runner.on('pending', test => ipcRenderer.send('pending', serializeRunnable(test)));
	}
}

function runTests(opts) {

	return loadTests(opts).then(() => {

		if (opts.grep) {
			mocha.grep(opts.grep);
		}

		if (!opts.debug) {
			mocha.reporter(IPCReporter);
		}

		const runner = mocha.run(() => {
			createCoverageReport(opts).then(() => {
				ipcRenderer.send('all done');
			});
		});

		if (opts.debug) {
			runner.on('fail', (test, err) => {

				console.error(test.fullTitle());
				console.error(err.stack);
			});
		}
	});
}

ipcRenderer.on('run', (e, opts) => {
	initLoader(opts);
	runTests(opts).catch(err => {
		if (typeof err !== 'string') {
			err = JSON.stringify(err);
		}

		console.error(err);
		ipcRenderer.send('error', err);
	});
});
<commit_msg>remove unused file<commit_after><|endoftext|>


<commit_before>'use strict';

/* eslint-disable no-inline-comments, max-len, complexity, global-require, require-jsdoc */

const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');
const path = require('path');
const gitconfig = require('git-config');
const glob = require('glob');
const _ = require('lodash');

/* this generator is used as subgenerator nitro:pattern and nitro:component */

module.exports = class extends Generator {

	constructor(args, opts) {
		// Calling the super constructor
		// eslint-disable-next-line prefer-rest-params
		super(args, opts);

		// Pattern name
		this.argument('name', { desc: 'the name of your pattern?', type: String, required: false, defaults: '' });

		// Pattern type
		this.cfg = require(this.destinationPath('config.json'));

		// Compatibility with older config and subgeneartor nitro:component
		const _patternName = this.options.namespace.split(':')[1];
		this._pattern = {
			name: _patternName,
			Name: _.upperFirst(_patternName),
			node: this.cfg.nitro.patterns || this.cfg.nitro.components,
		};

		this.types = _.map(this._pattern.node, (value, key) => {
			return key;
		});

		this.option('type', {
			desc: `your desired type [${this.types.join('|')}]`,
			type: String,
			defaults: this.types[0],
		});

		// Pattern modifier
		this.option('modifier', { desc: 'the name of your modifier', type: String });

		// Pattern decorator
		this.option('decorator', { desc: 'the name of your decorator', type: String });
	}

	initializing() {
		this.pkg = require('../../package.json');
	}

	prompting() {

		this.log(yosay(
			`Let me help you to create your ${this._pattern.name}…`
		));

		return this.prompt([
			{
				name: 'name',
				message: `What's the name of your ${this._pattern.name}?`,
				default: this.name,
				validate: (value) => {
					if (!_.isString(value) || _.isEmpty(value)) {
						return `${this._pattern.Name} name has to be a valid string`;
					}
					if (/^[0-9]/.test(value)) {
						return `${this._pattern.Name} name must not start with a Number`;
					}
					if (/(component|pattern|modifier|decorator)/i.test(value)) {
						return `Avoid 'pattern', 'component', 'modifier' and 'decorator' in ${this._pattern.Name} names. These have a special meaning`;
					}
					return true;
				},
			},
			{
				name: 'type',
				type: 'list',
				message: 'And what\'s your desired type?',
				choices: this.types,
				default: _.indexOf(this.types, this.options.type) || 0,
			},
			{
				name: 'modifier',
				message: 'Would you like to create a CSS modifier? Type your desired name or leave empty.',
				default: this.options.modifier || '',
				validate: (value) => {
					if (/(component|pattern|modifier|decorator)/i.test(value)) {
						return `Avoid 'pattern', 'component', 'modifier' and 'decorator' in ${this._pattern.Name} modifier names. These have a special meaning`;
					}
					return true;
				},
			},
			{
				name: 'decorator',
				message: 'Would you like to create a JS decorator? Type your desired name or leave empty.',
				default: this.options.decorator || '',
				validate: (value) => {
					if (_.isString(value) && (/^[0-9]/).test(value)) {
						return `${this._pattern.Name} decorator must not start with a Number`;
					}
					if (/(component|pattern|modifier|decorator)/i.test(value)) {
						return `Avoid 'pattern', 'component', 'modifier' and 'decorator' in ${this._pattern.Name} decorator names. These have a special meaning`;
					}
					return true;
				},
			},
		]).then((answers) => {
			this.name = answers.name;
			this.options.type = answers.type;
			this.options.modifier = answers.modifier;
			this.options.decorator = answers.decorator;
		});
	}

	writing() {

		const hasModifier = !_.isEmpty(this.options.modifier);
		const hasDecorator = !_.isEmpty(this.options.decorator);
		let msg = `Creating ${chalk.cyan(this.name)} ${this.options.type}`;

		if (hasModifier || hasDecorator) {
			msg += ' with ';
		}

		if (hasModifier) {
			msg += `CSS modifier ${chalk.cyan(this.options.modifier)}`;

			if (hasDecorator) {
				msg += ' and ';
			}
		}

		if (hasDecorator) {
			msg += `JS decorator ${chalk.cyan(this.options.decorator)}`;
		}

		this.log(msg);

		const pattern = this._pattern.node[this.options.type];
		const folder = this.name.replace(/[^A-Za-z0-9-]/g, '');
		const files = glob.sync('**/*', { cwd: this.destinationPath(pattern.template), nodir: true, dot: true });
		const ignores = [
			// files to ignore
			'.DS_Store',
		];
		const user = {
			name: '',
			email: '',
		};
		const gitConfig = gitconfig.sync();

		if (!_.isEmpty(gitConfig) && !_.isEmpty(gitConfig.user)) {
			user.name = gitConfig.user.name;
			user.email = gitConfig.user.email;
		}

		const patternReplacements = {
			name: this.name, // Pattern name, eg. Main Navigation
			folder, // Pattern folder, eg. MainNavigation
			js: _.upperFirst(_.camelCase(this.name.replace(/^[0-9]+/, ''))), // Pattern name for use in JS files, eg. MainNavigation
			css: _.kebabCase(this.name), // Pattern name for use in CSS files, eg. main-navigation
			prefix: pattern.pattern_prefix || pattern.component_prefix || null, // CSS class prefix, eg. m
			type: this.options.type, // Pattern type, eg. atom, molecule etc.
			file: this.name.replace(/[^A-Za-z0-9-]/g, '').toLowerCase(), // Pattern filename, eg. mainnavigation
		};
		const replacements = {
			user,
			pattern: patternReplacements,
			component: patternReplacements,
			modifier: {
				name: this.options.modifier, // Modifier name, eg. Highlight
				css: _.kebabCase(this.options.modifier), // Modifier name for use in CSS files, eg. highlight
				file: this.options.modifier.replace(/[^A-Za-z0-9-]/g, '').toLowerCase(), // Modifier filename, eg.highlight
			},
			decorator: {
				name: this.options.decorator, // Decorator name, eg. Highlight
				js: _.upperFirst(_.camelCase(this.options.decorator.replace(/^[0-9]+/, ''))), // Decorator name for use in JS files, eg. Highlight
				file: this.options.decorator.replace(/[^A-Za-z0-9-]/g, '').toLowerCase(), // Decorator filename, eg.highlight
			},
		};

		files.forEach((file) => {
			if (_.indexOf(ignores, file) !== -1) {
				return;
			}

			// exclude modifier files if modifier is not set
			if (file.indexOf('modifier') !== -1) {
				if (_.isEmpty(this.options.modifier)) {
					return;
				}
			}

			// exclude decorator files if decorator is not set
			if (file.indexOf('decorator') !== -1) {
				if (_.isEmpty(this.options.decorator)) {
					return;
				}
			}

			// filename replacements
			const fileReplacements = {
				pattern: replacements.pattern.file,
				component: replacements.pattern.file,
				modifier: replacements.modifier.file,
				decorator: replacements.decorator.file,
			};

			let filename = file;
			_.forOwn(fileReplacements, (value, key) => {
				filename = path.join(path.dirname(filename), path.basename(filename).split(key).join(value));
			});

			this.fs.copyTpl(
				this.destinationPath(`${pattern.template}/${file}`),
				this.destinationPath(`${pattern.path}/${folder}/${filename}`),
				replacements);
		}, this);
	}
};
<commit_msg>generator pattern - catch options from command line<commit_after>'use strict';

/* eslint-disable no-inline-comments, max-len, complexity, global-require, require-jsdoc */

const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');
const path = require('path');
const gitconfig = require('git-config');
const glob = require('glob');
const _ = require('lodash');

/* this generator is used as subgenerator nitro:pattern and nitro:component */

module.exports = class extends Generator {

	constructor(args, opts) {
		// Calling the super constructor
		// eslint-disable-next-line prefer-rest-params
		super(args, opts);

		// Pattern name
		this.argument('name', { desc: 'the name of your pattern?', type: String, required: false, defaults: '' });

		this.passedInOptions = {
			name: this.options.name,
			type: this.options.type,
			modifier: this.options.modifier,
			decorator: this.options.decorator,
		};

		// Pattern type
		this.cfg = require(this.destinationPath('config.json'));

		// Compatibility with older config and subgeneartor nitro:component
		const _patternName = this.options.namespace.split(':')[1];
		this._pattern = {
			name: _patternName,
			Name: _.upperFirst(_patternName),
			node: this.cfg.nitro.patterns || this.cfg.nitro.components,
		};

		this.types = _.map(this._pattern.node, (value, key) => {
			return key;
		});

		this.option('name', {
			desc: `the name of your ${this._pattern.Name}`,
			type: String,
			defaults: this.passedInOptions.name || '',
		});

		this.option('type', {
			desc: `your desired type [${this.types.join('|')}]`,
			type: String,
			defaults: this.passedInOptions.type || this.types[0],
		});

		// Pattern modifier
		this.option('modifier', {
			desc: 'the name of your modifier',
			type: String,
			defaults: this.passedInOptions.modifier || '',
		});

		// Pattern decorator
		this.option('decorator', {
			desc: 'the name of your decorator',
			type: String,
			defaults: this.passedInOptions.decorator || '',
		});
	}

	initializing() {
		this.pkg = require('../../package.json');
	}

	prompting() {

		this.log(yosay(
			`Let me help you to create your ${this._pattern.name}…`
		));

		return this.prompt([
			{
				name: 'name',
				message: `What's the name of your ${this._pattern.name}?`,
				default: this.options.name,
				validate: (value) => {
					if (!_.isString(value) || _.isEmpty(value)) {
						return `${this._pattern.Name} name has to be a valid string`;
					}
					if (/^[0-9]/.test(value)) {
						return `${this._pattern.Name} name must not start with a Number`;
					}
					if (/(component|pattern|modifier|decorator)/i.test(value)) {
						return `Avoid 'pattern', 'component', 'modifier' and 'decorator' in ${this._pattern.Name} names. These have a special meaning`;
					}
					return true;
				},
			},
			{
				name: 'type',
				type: 'list',
				message: 'And what\'s your desired type?',
				choices: this.types,
				default: _.indexOf(this.types, this.options.type) || 0,
			},
			{
				name: 'modifier',
				message: 'Would you like to create a CSS modifier? Type your desired name or leave empty.',
				default: this.options.modifier || '',
				validate: (value) => {
					if (/(component|pattern|modifier|decorator)/i.test(value)) {
						return `Avoid 'pattern', 'component', 'modifier' and 'decorator' in ${this._pattern.Name} modifier names. These have a special meaning`;
					}
					return true;
				},
			},
			{
				name: 'decorator',
				message: 'Would you like to create a JS decorator? Type your desired name or leave empty.',
				default: this.options.decorator || '',
				validate: (value) => {
					if (_.isString(value) && (/^[0-9]/).test(value)) {
						return `${this._pattern.Name} decorator must not start with a Number`;
					}
					if (/(component|pattern|modifier|decorator)/i.test(value)) {
						return `Avoid 'pattern', 'component', 'modifier' and 'decorator' in ${this._pattern.Name} decorator names. These have a special meaning`;
					}
					return true;
				},
			},
		]).then((answers) => {
			this.name = answers.name;
			this.options.type = answers.type;
			this.options.modifier = answers.modifier;
			this.options.decorator = answers.decorator;
		});
	}

	writing() {

		const hasModifier = !_.isEmpty(this.options.modifier);
		const hasDecorator = !_.isEmpty(this.options.decorator);
		let msg = `Creating ${chalk.cyan(this.name)} ${this.options.type}`;

		if (hasModifier || hasDecorator) {
			msg += ' with ';
		}

		if (hasModifier) {
			msg += `CSS modifier ${chalk.cyan(this.options.modifier)}`;

			if (hasDecorator) {
				msg += ' and ';
			}
		}

		if (hasDecorator) {
			msg += `JS decorator ${chalk.cyan(this.options.decorator)}`;
		}

		this.log(msg);

		const pattern = this._pattern.node[this.options.type];
		const folder = this.name.replace(/[^A-Za-z0-9-]/g, '');
		const files = glob.sync('**/*', { cwd: this.destinationPath(pattern.template), nodir: true, dot: true });
		const ignores = [
			// files to ignore
			'.DS_Store',
		];
		const user = {
			name: '',
			email: '',
		};
		const gitConfig = gitconfig.sync();

		if (!_.isEmpty(gitConfig) && !_.isEmpty(gitConfig.user)) {
			user.name = gitConfig.user.name;
			user.email = gitConfig.user.email;
		}

		const patternReplacements = {
			name: this.name, // Pattern name, eg. Main Navigation
			folder, // Pattern folder, eg. MainNavigation
			js: _.upperFirst(_.camelCase(this.name.replace(/^[0-9]+/, ''))), // Pattern name for use in JS files, eg. MainNavigation
			css: _.kebabCase(this.name), // Pattern name for use in CSS files, eg. main-navigation
			prefix: pattern.pattern_prefix || pattern.component_prefix || null, // CSS class prefix, eg. m
			type: this.options.type, // Pattern type, eg. atom, molecule etc.
			file: this.name.replace(/[^A-Za-z0-9-]/g, '').toLowerCase(), // Pattern filename, eg. mainnavigation
		};
		const replacements = {
			user,
			pattern: patternReplacements,
			component: patternReplacements,
			modifier: {
				name: this.options.modifier, // Modifier name, eg. Highlight
				css: _.kebabCase(this.options.modifier), // Modifier name for use in CSS files, eg. highlight
				file: this.options.modifier.replace(/[^A-Za-z0-9-]/g, '').toLowerCase(), // Modifier filename, eg.highlight
			},
			decorator: {
				name: this.options.decorator, // Decorator name, eg. Highlight
				js: _.upperFirst(_.camelCase(this.options.decorator.replace(/^[0-9]+/, ''))), // Decorator name for use in JS files, eg. Highlight
				file: this.options.decorator.replace(/[^A-Za-z0-9-]/g, '').toLowerCase(), // Decorator filename, eg.highlight
			},
		};

		files.forEach((file) => {
			if (_.indexOf(ignores, file) !== -1) {
				return;
			}

			// exclude modifier files if modifier is not set
			if (file.indexOf('modifier') !== -1) {
				if (_.isEmpty(this.options.modifier)) {
					return;
				}
			}

			// exclude decorator files if decorator is not set
			if (file.indexOf('decorator') !== -1) {
				if (_.isEmpty(this.options.decorator)) {
					return;
				}
			}

			// filename replacements
			const fileReplacements = {
				pattern: replacements.pattern.file,
				component: replacements.pattern.file,
				modifier: replacements.modifier.file,
				decorator: replacements.decorator.file,
			};

			let filename = file;
			_.forOwn(fileReplacements, (value, key) => {
				filename = path.join(path.dirname(filename), path.basename(filename).split(key).join(value));
			});

			this.fs.copyTpl(
				this.destinationPath(`${pattern.template}/${file}`),
				this.destinationPath(`${pattern.path}/${folder}/${filename}`),
				replacements);
		}, this);
	}
};
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';
var fs = require('fs');
var path = require('path');
var process = require('process');
var RemoteConfig = require('../../clients/remote-config.js');
var DebugLogtron = require('debug-logtron');

module.exports = RemoteConfigFile;

function RemoteConfigFile(name) {
    if (!(this instanceof RemoteConfigFile)) {
        return new RemoteConfigFile(name);
    }

    var self = this;
    name = name || 'UNKNOWN[' + process.pid + ']';
    self.filePath = path.join('/tmp',
                              name + 'config.json');
}

RemoteConfigFile.prototype.write =
function write(opts) {
    var self = this;
    var obj = [];
    opts = opts || {};
    var keys = Object.keys(opts);
    for (var i = 0; i < keys.length; i++) {
        obj.push({
            key: keys[i],
            value: opts[keys[i]]
        });
    }
    var json = JSON.stringify(obj);
    self.writeFile(json);
};

RemoteConfigFile.prototype.writeFile = function writeFile(content) {
    var self = this;
    fs.writeFileSync(
        self.filePath,
        content,
        'utf8'
    );
};

RemoteConfigFile.prototype.create = function create(opts) {
    var self = this;
    var logger = DebugLogtron('remoteconfig');
    opts = opts || {};

    logger.whitelist('error', '[remote-config] could not read file');

    return RemoteConfig({
        configFile: self.filePath,
        pollInterval: opts.pollInterval,
        logger: logger
    });
};

RemoteConfigFile.prototype.clear = function clear() {
    var self = this;
    if (fs.existsSync(self.filePath)) {
        fs.unlinkSync(self.filePath);
    }
};
<commit_msg>test/lib/remote-config-file: prettify file output<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';
var fs = require('fs');
var path = require('path');
var process = require('process');
var RemoteConfig = require('../../clients/remote-config.js');
var DebugLogtron = require('debug-logtron');

module.exports = RemoteConfigFile;

function RemoteConfigFile(name) {
    if (!(this instanceof RemoteConfigFile)) {
        return new RemoteConfigFile(name);
    }

    var self = this;
    name = name || 'UNKNOWN[' + process.pid + ']';
    self.filePath = path.join('/tmp',
                              name + 'config.json');
}

RemoteConfigFile.prototype.write =
function write(opts) {
    var self = this;
    var obj = [];
    opts = opts || {};
    var keys = Object.keys(opts);
    for (var i = 0; i < keys.length; i++) {
        obj.push({
            key: keys[i],
            value: opts[keys[i]]
        });
    }
    var json = JSON.stringify(obj, null, 4);
    self.writeFile(json);
};

RemoteConfigFile.prototype.writeFile = function writeFile(content) {
    var self = this;
    fs.writeFileSync(
        self.filePath,
        content,
        'utf8'
    );
};

RemoteConfigFile.prototype.create = function create(opts) {
    var self = this;
    var logger = DebugLogtron('remoteconfig');
    opts = opts || {};

    logger.whitelist('error', '[remote-config] could not read file');

    return RemoteConfig({
        configFile: self.filePath,
        pollInterval: opts.pollInterval,
        logger: logger
    });
};

RemoteConfigFile.prototype.clear = function clear() {
    var self = this;
    if (fs.existsSync(self.filePath)) {
        fs.unlinkSync(self.filePath);
    }
};
<|endoftext|>


<commit_before>/**
 * @summary     ConditionalPaging
 * @description Hide paging controls when the amount of pages is <= 1
 * @version     1.0.0
 * @file        dataTables.conditionalPaging.js
 * @author      Matthew Hasbach (https://github.com/mjhasbach)
 * @contact     hasbach.git@gmail.com
 * @copyright   Copyright 2015 Matthew Hasbach
 *
 * License      MIT - http://datatables.net/license/mit
 *
 * This feature plugin for DataTables hides paging controls when the amount
 * of pages is <= 1. The controls can either appear / disappear or fade in / out
 *
 * @example
 *    $('#myTable').DataTable({
 *        conditionalPaging: true
 *    });
 *
 * @example
 *    $('#myTable').DataTable({
 *        conditionalPaging: {
 *            style: 'fade',
 *            speed: 500 // optional
 *        }
 *    });
 */

(function(window, document, $) {
    $(document).on('init.dt', function(e, dtSettings) {
        if ( e.namespace !== 'dt' ) {
            return;
        }

        var options = dtSettings.oInit.conditionalPaging;

        if ($.isPlainObject(options) || options === true) {
            var config = $.isPlainObject(options) ? options : {},
                api = new $.fn.dataTable.Api(dtSettings),
                speed = 'slow',
                conditionalPaging = function(e) {
                    var $paging = $(api.table().container()).find('div.dataTables_paginate'),
                        pages = api.page.info().pages;

                    if (e instanceof $.Event) {
                        if (pages <= 1) {
                            if (config.style === 'fade') {
                                $paging.stop().fadeTo(speed, 0);
                            }
                            else {
                                $paging.css('visibility', 'hidden');
                            }
                        }
                        else {
                            if (config.style === 'fade') {
                                $paging.stop().fadeTo(speed, 1);
                            }
                            else {
                                $paging.css('visibility', '');
                            }
                        }
                    }
                    else if (pages <= 1) {
                        if (config.style === 'fade') {
                            $paging.css('opacity', 0);
                        }
                        else {
                            $paging.css('visibility', 'hidden');
                        }
                    }
                };

            if ($.isNumeric(config.speed) || $.type(config.speed) === 'string') {
                speed = config.speed;
            }

            conditionalPaging();

            api.on('draw.dt', conditionalPaging);
        }
    });
})(window, document, jQuery);<commit_msg>Fix #1221: Hide row filter dropdown when the search is one page long. (#1265)<commit_after>/**
 * @summary     ConditionalPaging
 * @description Hide paging controls when the amount of pages is <= 1
 * @version     1.0.0
 * @file        dataTables.conditionalPaging.js
 * @author      Matthew Hasbach (https://github.com/mjhasbach)
 * @contact     hasbach.git@gmail.com
 * @copyright   Copyright 2015 Matthew Hasbach
 *
 * License      MIT - http://datatables.net/license/mit
 *
 * This feature plugin for DataTables hides paging controls when the amount
 * of pages is <= 1. The controls can either appear / disappear or fade in / out
 *
 * @example
 *    $('#myTable').DataTable({
 *        conditionalPaging: true
 *    });
 *
 * @example
 *    $('#myTable').DataTable({
 *        conditionalPaging: {
 *            style: 'fade',
 *            speed: 500 // optional
 *        }
 *    });
 */

(function(window, document, $) {
    $(document).on('init.dt', function(e, dtSettings) {
        if ( e.namespace !== 'dt' ) {
            return;
        }

        var options = dtSettings.oInit.conditionalPaging;

        if ($.isPlainObject(options) || options === true) {
            var config = $.isPlainObject(options) ? options : {},
                api = new $.fn.dataTable.Api(dtSettings),
                speed = 'slow',
                conditionalPaging = function(e) {
                    var $paging = $(api.table().container()).find('div.dataTables_paginate'),
                        $dropdown = $(api.table().container()).find('div.dataTables_length'),
                        pages = api.page.info().pages;

                    if (e instanceof $.Event) {
                        if (pages <= 1) {
                            if (config.style === 'fade') {
                                $paging.stop().fadeTo(speed, 0);
                            }
                            else {
                                $paging.css('visibility', 'hidden');
                            }
                            if (api.page.info().recordsDisplay < 10) {
                                $dropdown.css('visibility', 'hidden');
                            }
                        }
                        else {
                            if (config.style === 'fade') {
                                $paging.stop().fadeTo(speed, 1);
                            }
                            else {
                                $paging.css('visibility', '');
                                $dropdown.css('visibility', '');
                            }
                        }
                    }
                    else if (pages <= 1) {
                        if (config.style === 'fade') {
                            $paging.css('opacity', 0);
                            $dropdown.css('opacity', 0);
                        }
                        else {
                            $paging.css('visibility', 'hidden');
                            $dropdown.css('visibility', 'hidden');
                        }
                    }
                };

            if ($.isNumeric(config.speed) || $.type(config.speed) === 'string') {
                speed = config.speed;
            }

            conditionalPaging();

            api.on('draw.dt', conditionalPaging);
        }
    });
})(window, document, jQuery);<|endoftext|>


<commit_before>'use strict';

var ddsApp = angular.module('ddsApp', ['ui.router', 'ngAnimate', 'ddsCommon', 'ngSanitize', 'angulartics', 'angulartics.piwik']);

ddsApp.config(function($locationProvider, $stateProvider, $urlRouterProvider, $uiViewScrollProvider) {
    moment.locale('fr');

    var CURRENT_YEAR_TWO_DIGITS = (new Date()).getFullYear() - 2000;
    moment.parseTwoDigitYear = function(input) {  // see https://github.com/moment/moment/issues/2219
        input = parseInt(input);
        return input + (input <= CURRENT_YEAR_TWO_DIGITS ? 2000 : 1900);
    };

    $locationProvider.html5Mode(true);
    $urlRouterProvider.otherwise('/');
    $uiViewScrollProvider.useAnchorScroll();

    var individuFormView = function(individuRole) {
        return {
            templateUrl: '/partials/foyer/individu-form.html',
            controller: 'FoyerIndividuFormCtrl',
            resolve: {
                individuRole: function() {
                    return individuRole;
                }
            }
        };
    };

    $stateProvider
        .state('home', {
            url: '/',
            templateUrl: '/partials/homepage.html',
            controller: 'HomepageCtrl',
            preventFocus: true
        })
        .state('a-propos', {
            url: '/a-propos',
            templateUrl: '/content-pages/a-propos.html',
            data: {
                pageTitle: 'À propos'
            }
        })
        .state('aah-en-test', {
            url: '/aah-en-test',
            templateUrl: '/content-pages/aah-en-test.html',
            controller: function($scope, droitsDescription, TrampolineService) {
                $scope.aah = droitsDescription.prestationsNationales.caf.prestations.aah;

                var trampoline = TrampolineService.get();
                if (! trampoline) {
                    return;
                }
                $scope.situationId = trampoline.situationId;
                $scope.montant = trampoline.montant;
            },
            data: {
                pageTitle: 'Montant de l’AAH – Mes Aides est en phase de test',
            }
        })
        .state('ameli', {
            url: '/ameli',
            templateUrl: '/content-pages/ameli.html',
            data: {
                pageTitle: 'Bienvenue sur Mes Aides'
            }
        })
        .state('ameliorer', {
            url: '/ameliorer',
            templateUrl: '/content-pages/ameliorer.html',
            data: {
                pageTitle: 'Améliorer'
            }
        })
        .state('cgu', {
            url: '/cgu',
            templateUrl: '/content-pages/cgu.html',
            data: {
                pageTitle: 'Conditions générales d’utilisation'
            },
            controller: function($scope, SituationService) {
                $scope.situationId = SituationService.restoreLocal()._id;
            }
        })
        .state('cgu_donnees', {
            url: '/cgu#donnees',
            templateUrl: '/content-pages/cgu.html',
            data: {
                pageTitle: 'Conditions générales d’utilisation'
            },
            controller: function($scope, SituationService) {
                $scope.situationId = SituationService.restoreLocal()._id;
            }
        })
        .state('communication', {
            url: '/communication',
            templateUrl: '/content-pages/communication.html',
            data: {
                pageTitle: 'Supports de communication'
            }
        })
        .state('contact', {
            url: '/contact',
            templateUrl: '/content-pages/contact.html',
            data: {
                pageTitle: 'Contact'
            },
            controller: function($scope, ABTestingService) {
                var ABTesting = ABTestingService.getABTestingEnvironment();
                $scope.contactABTestingEnv = (ABTesting.contact && ABTesting.contact.value) || 'A';
            }
        })
        .state('hameconnage', {
            url: '/hameconnage',
            templateUrl: '/content-pages/hameconnage.html',
            data: {
                pageTitle: '⚠ Hameçonnage ⚠'
            },
            controller: function($scope) {
                $scope.referrer = document.referrer;
            }
        })
        .state('liens-utiles', {
            url: '/liens-utiles',
            templateUrl: '/content-pages/liens-utiles.html',
            data: {
                pageTitle: 'Liens utiles'
            }
        })
        .state('social', {
            url: '/social',
            templateUrl: '/content-pages/social.html',
            data: {
                pageTitle: 'Réseaux sociaux'
            }
        })
        .state('sos', {
            url: '/sos',
            templateUrl: '/content-pages/sos.html',
            data: {
                pageTitle: 'SOS'
            }
        })
        .state('stats', {
            url: '/stats',
            templateUrl: '/partials/stats.html',
            controller: 'StatsCtrl',
        })
        .state('tests', {
            url: '/tests',
            onEnter: function($window) {
                $window.location.href = '/tests';
            }
        })
        .state('validation', {
            url: '/validation',
            templateUrl: '/partials/validation.html',
            controller: 'ValidationCtrl'
        })
        .state('foyer', {
            abstract: true,
            url: '/foyer',
            views: {
                '': {
                    controller: 'FoyerCtrl',
                    templateUrl: '/partials/foyer/layout.html',
                },
                'recap_situation@foyer': {
                    controller: 'RecapSituationCtrl',
                    templateUrl: '/partials/foyer/recap-situation.html'
                }
            },
            data: {
                pageTitle: 'Simulation'
            }
        })
        .state('foyer.demandeur', {
            url: '/demandeur',
            views: {
                '': {
                    templateUrl: '/partials/foyer/demandeur.html'
                },
                'individuForm@foyer.demandeur': individuFormView('demandeur')
            },
            preventFocus: true
        })
        .state('foyer.conjoint', {
            url: '/conjoint',
            views: {
                '': {
                    templateUrl: '/partials/foyer/conjoint.html',
                    controller: 'FoyerConjointCtrl',
                },
                'individuForm@foyer.conjoint': individuFormView('conjoint')
            }
        })
        .state('foyer.enfants', {
            url: '/enfants',
            views: {
                '': {
                    templateUrl: '/partials/foyer/enfants.html',
                    controller: 'FoyerEnfantsCtrl',
                },
                'validate@foyer.enfants': {
                    templateUrl: '/partials/foyer/enfants/validate.html',
                },
            }
        })
        .state('foyer.enfants.ajouter', {
            url: '/ajouter',
            views: {
                'enfantForm': {
                    controller: 'FoyerNewEnfantCtrl',
                    templateUrl: '/partials/foyer/enfants/form.html',
                },
                'form@foyer.enfants.ajouter': individuFormView('enfant'),
                'validate@foyer.enfants': {
                    templateUrl: '/partials/foyer/enfants/validate.html',
                },
            }
        })
        .state('foyer.enfants.modifier', {
            url: '/:id',
            templateUrl: '/partials/foyer/enfants.html',
            views: {
                'enfantForm': {
                    controller: 'FoyerEnfantCtrl',
                    templateUrl: '/partials/foyer/enfants/form.html',
                },
                'form@foyer.enfants.modifier': individuFormView('enfant'),
                'validate@foyer.enfants': {
                    templateUrl: '/partials/foyer/enfants/validate.html',
                },
            }
        })
        .state('foyer.logement', {
            url: '/logement',
            templateUrl: '/partials/foyer/logement.html',
            controller: 'FoyerLogementCtrl'
        })
        .state('foyer.ressources', {
            url: '/ressources',
            controller: 'FoyerRessourcesCtrl',
            templateUrl: '/partials/foyer/ressources/layout.html'
        })
        .state('foyer.ressources.enfants', {
            templateUrl: '/partials/foyer/ressources/enfants.html',
            controller: 'FoyerRessourcesEnfantsCtrl',
            url: '/enfants/'
        })
        .state('foyer.ressources.individu', {
            controller: 'FoyerRessourcesIndividuCtrl',
            url: '/:individu',
            templateUrl: '/partials/foyer/ressources/layout.html'
        })
        .state('foyer.ressources.individu.types', {
            templateUrl: '/partials/foyer/ressources/types.html',
            controller: 'FoyerRessourceTypesCtrl',
            url: '/types'
        })
        .state('foyer.ressources.individu.montants', {
            templateUrl: '/partials/foyer/ressources/montants.html',
            controller: 'FoyerRessourcesMontantsCtrl',
            url: '/montants'
        })
        .state('foyer.pensionsAlimentaires', {
            templateUrl: '/partials/foyer/pensions-alimentaires.html',
            controller: 'FoyerPensionsAlimentairesCtrl',
            url: '/pensions-alimentaires'
        })
        .state('foyer.resultat', {
            url: '/resultat?situationId',
            templateUrl: '/partials/resultat.html',
            controller: 'ResultatCtrl'
        }).state('foyer.resultat.suggestion', {
            url: '/suggestion',
            templateUrl: '/partials/suggestion.html',
            controller: 'SuggestionCtrl'
        })
        .state('foyer.ressourcesYearMoins2', {
            templateUrl: '/partials/foyer/ressources/year-moins-2.html',
            controller: 'FoyerRessourceYearMoins2Ctrl',
            url: '/revenus-impots'
        })
        .state('foyer.rfr', {
            templateUrl: '/partials/foyer/ressources/rfr.html',
            controller: 'FoyerRessourceRfrCtrl',
            url: '/rfr'
        })
        .state('foyer.patrimoine', {
            url: '/patrimoine',
            templateUrl: '/partials/foyer/patrimoine.html',
            controller: 'FoyerPatrimoineCtrl'
        })
        .state('redirection', {
            url: '/redirection?vers',
            templateUrl: '/partials/redirection.html',
            controller: 'RedirectionCtrl'
        })
        .state('situation', { // Route used by Ludwig
            url: '/situations/:situationId',
            template: '',
            controller: function(SituationService, $state, $stateParams) {
                $state.go('foyer.resultat', { situationId: $stateParams.situationId });
            }
        });
});

ddsApp.run(function($rootScope, $state, $stateParams, $window, $anchorScroll, $timeout) {
    $rootScope.$state = $state;
    $rootScope.$stateParams = $stateParams;

    // Offset de l'anchorscroll à 60px, nécessaire à cause de la navbar en position fixed
    $anchorScroll.yOffset = 60;

    // changement d'url vers /api => débranchement de ui-router
    $rootScope.$on('$locationChangeStart', function(e, location) {
        if (0 === location.indexOf($window.location.origin + '/api')) {
            e.preventDefault();
            $window.location.href = location;
        }
    });

    $rootScope.$on('$stateChangeSuccess', function focusTitleForScreenReaders(event, current) {
        if (current.preventFocus)
            return;

        $timeout(function() {  // add the function to the next angular digest cycle, waiting for the page to load before executing it
            var title = document.querySelector('h1');
            // if anyone wants to set a tabindex manually, do not overwrite it
            if (title && title.tabIndex < 0) {  // default is -1... https://html.spec.whatwg.org/multipage/interaction.html#dom-tabindex
                title.tabIndex = -1;  //...yet it has to be set to -1 to allow `.focus()`
                title.focus();
            }
        });
    });

    $rootScope.$on('$locationChangeSuccess', function(event, current) {
        if ($window._paq) {
            $window._paq.push(['setCustomUrl', current]);
            $window._paq.push(['trackPageView']);
        }
    });
});
<commit_msg>Use require.context to preload templates in cache.<commit_after>'use strict';

// Use Webpack's require.context to manage dynamic requires for templates
// The templates will be cached when the application is booted
// https://webpack.js.org/guides/dependency-management/#require-context
var template = require.context('../views', true, /(partials|content-pages)\/.*\.html$/);

var ddsApp = angular.module('ddsApp', ['ui.router', 'ngAnimate', 'ddsCommon', 'ngSanitize', 'angulartics', 'angulartics.piwik']);

ddsApp.config(function($locationProvider, $stateProvider, $urlRouterProvider, $uiViewScrollProvider) {
    moment.locale('fr');

    var CURRENT_YEAR_TWO_DIGITS = (new Date()).getFullYear() - 2000;
    moment.parseTwoDigitYear = function(input) {  // see https://github.com/moment/moment/issues/2219
        input = parseInt(input);
        return input + (input <= CURRENT_YEAR_TWO_DIGITS ? 2000 : 1900);
    };

    $locationProvider.html5Mode(true);
    $urlRouterProvider.otherwise('/');
    $uiViewScrollProvider.useAnchorScroll();

    var individuFormView = function(individuRole) {
        return {
            templateUrl: '/partials/foyer/individu-form.html',
            controller: 'FoyerIndividuFormCtrl',
            resolve: {
                individuRole: function() {
                    return individuRole;
                }
            }
        };
    };

    $stateProvider
        .state('home', {
            url: '/',
            templateUrl: '/partials/homepage.html',
            controller: 'HomepageCtrl',
            preventFocus: true
        })
        .state('a-propos', {
            url: '/a-propos',
            templateUrl: '/content-pages/a-propos.html',
            data: {
                pageTitle: 'À propos'
            }
        })
        .state('aah-en-test', {
            url: '/aah-en-test',
            templateUrl: '/content-pages/aah-en-test.html',
            controller: function($scope, droitsDescription, TrampolineService) {
                $scope.aah = droitsDescription.prestationsNationales.caf.prestations.aah;

                var trampoline = TrampolineService.get();
                if (! trampoline) {
                    return;
                }
                $scope.situationId = trampoline.situationId;
                $scope.montant = trampoline.montant;
            },
            data: {
                pageTitle: 'Montant de l’AAH – Mes Aides est en phase de test',
            }
        })
        .state('ameli', {
            url: '/ameli',
            templateUrl: '/content-pages/ameli.html',
            data: {
                pageTitle: 'Bienvenue sur Mes Aides'
            }
        })
        .state('ameliorer', {
            url: '/ameliorer',
            templateUrl: '/content-pages/ameliorer.html',
            data: {
                pageTitle: 'Améliorer'
            }
        })
        .state('cgu', {
            url: '/cgu',
            templateUrl: '/content-pages/cgu.html',
            data: {
                pageTitle: 'Conditions générales d’utilisation'
            },
            controller: function($scope, SituationService) {
                $scope.situationId = SituationService.restoreLocal()._id;
            }
        })
        .state('cgu_donnees', {
            url: '/cgu#donnees',
            templateUrl: '/content-pages/cgu.html',
            data: {
                pageTitle: 'Conditions générales d’utilisation'
            },
            controller: function($scope, SituationService) {
                $scope.situationId = SituationService.restoreLocal()._id;
            }
        })
        .state('communication', {
            url: '/communication',
            templateUrl: '/content-pages/communication.html',
            data: {
                pageTitle: 'Supports de communication'
            }
        })
        .state('contact', {
            url: '/contact',
            templateUrl: '/content-pages/contact.html',
            data: {
                pageTitle: 'Contact'
            },
            controller: function($scope, ABTestingService) {
                var ABTesting = ABTestingService.getABTestingEnvironment();
                $scope.contactABTestingEnv = (ABTesting.contact && ABTesting.contact.value) || 'A';
            }
        })
        .state('hameconnage', {
            url: '/hameconnage',
            templateUrl: '/content-pages/hameconnage.html',
            data: {
                pageTitle: '⚠ Hameçonnage ⚠'
            },
            controller: function($scope) {
                $scope.referrer = document.referrer;
            }
        })
        .state('liens-utiles', {
            url: '/liens-utiles',
            templateUrl: '/content-pages/liens-utiles.html',
            data: {
                pageTitle: 'Liens utiles'
            }
        })
        .state('social', {
            url: '/social',
            templateUrl: '/content-pages/social.html',
            data: {
                pageTitle: 'Réseaux sociaux'
            }
        })
        .state('sos', {
            url: '/sos',
            templateUrl: '/content-pages/sos.html',
            data: {
                pageTitle: 'SOS'
            }
        })
        .state('stats', {
            url: '/stats',
            templateUrl: '/partials/stats.html',
            controller: 'StatsCtrl',
        })
        .state('tests', {
            url: '/tests',
            onEnter: function($window) {
                $window.location.href = '/tests';
            }
        })
        .state('validation', {
            url: '/validation',
            templateUrl: '/partials/validation.html',
            controller: 'ValidationCtrl'
        })
        .state('foyer', {
            abstract: true,
            url: '/foyer',
            views: {
                '': {
                    controller: 'FoyerCtrl',
                    templateUrl: '/partials/foyer/layout.html',
                },
                'recap_situation@foyer': {
                    controller: 'RecapSituationCtrl',
                    templateUrl: '/partials/foyer/recap-situation.html'
                }
            },
            data: {
                pageTitle: 'Simulation'
            }
        })
        .state('foyer.demandeur', {
            url: '/demandeur',
            views: {
                '': {
                    templateUrl: '/partials/foyer/demandeur.html'
                },
                'individuForm@foyer.demandeur': individuFormView('demandeur')
            },
            preventFocus: true
        })
        .state('foyer.conjoint', {
            url: '/conjoint',
            views: {
                '': {
                    templateUrl: '/partials/foyer/conjoint.html',
                    controller: 'FoyerConjointCtrl',
                },
                'individuForm@foyer.conjoint': individuFormView('conjoint')
            }
        })
        .state('foyer.enfants', {
            url: '/enfants',
            views: {
                '': {
                    templateUrl: '/partials/foyer/enfants.html',
                    controller: 'FoyerEnfantsCtrl',
                },
                'validate@foyer.enfants': {
                    templateUrl: '/partials/foyer/enfants/validate.html',
                },
            }
        })
        .state('foyer.enfants.ajouter', {
            url: '/ajouter',
            views: {
                'enfantForm': {
                    controller: 'FoyerNewEnfantCtrl',
                    templateUrl: '/partials/foyer/enfants/form.html',
                },
                'form@foyer.enfants.ajouter': individuFormView('enfant'),
                'validate@foyer.enfants': {
                    templateUrl: '/partials/foyer/enfants/validate.html',
                },
            }
        })
        .state('foyer.enfants.modifier', {
            url: '/:id',
            templateUrl: '/partials/foyer/enfants.html',
            views: {
                'enfantForm': {
                    controller: 'FoyerEnfantCtrl',
                    templateUrl: '/partials/foyer/enfants/form.html',
                },
                'form@foyer.enfants.modifier': individuFormView('enfant'),
                'validate@foyer.enfants': {
                    templateUrl: '/partials/foyer/enfants/validate.html',
                },
            }
        })
        .state('foyer.logement', {
            url: '/logement',
            templateUrl: '/partials/foyer/logement.html',
            controller: 'FoyerLogementCtrl'
        })
        .state('foyer.ressources', {
            url: '/ressources',
            controller: 'FoyerRessourcesCtrl',
            templateUrl: '/partials/foyer/ressources/layout.html'
        })
        .state('foyer.ressources.enfants', {
            templateUrl: '/partials/foyer/ressources/enfants.html',
            controller: 'FoyerRessourcesEnfantsCtrl',
            url: '/enfants/'
        })
        .state('foyer.ressources.individu', {
            controller: 'FoyerRessourcesIndividuCtrl',
            url: '/:individu',
            templateUrl: '/partials/foyer/ressources/layout.html'
        })
        .state('foyer.ressources.individu.types', {
            templateUrl: '/partials/foyer/ressources/types.html',
            controller: 'FoyerRessourceTypesCtrl',
            url: '/types'
        })
        .state('foyer.ressources.individu.montants', {
            templateUrl: '/partials/foyer/ressources/montants.html',
            controller: 'FoyerRessourcesMontantsCtrl',
            url: '/montants'
        })
        .state('foyer.pensionsAlimentaires', {
            templateUrl: '/partials/foyer/pensions-alimentaires.html',
            controller: 'FoyerPensionsAlimentairesCtrl',
            url: '/pensions-alimentaires'
        })
        .state('foyer.resultat', {
            url: '/resultat?situationId',
            templateUrl: '/partials/resultat.html',
            controller: 'ResultatCtrl'
        }).state('foyer.resultat.suggestion', {
            url: '/suggestion',
            templateUrl: '/partials/suggestion.html',
            controller: 'SuggestionCtrl'
        })
        .state('foyer.ressourcesYearMoins2', {
            templateUrl: '/partials/foyer/ressources/year-moins-2.html',
            controller: 'FoyerRessourceYearMoins2Ctrl',
            url: '/revenus-impots'
        })
        .state('foyer.rfr', {
            templateUrl: '/partials/foyer/ressources/rfr.html',
            controller: 'FoyerRessourceRfrCtrl',
            url: '/rfr'
        })
        .state('foyer.patrimoine', {
            url: '/patrimoine',
            templateUrl: '/partials/foyer/patrimoine.html',
            controller: 'FoyerPatrimoineCtrl'
        })
        .state('redirection', {
            url: '/redirection?vers',
            templateUrl: '/partials/redirection.html',
            controller: 'RedirectionCtrl'
        })
        .state('situation', { // Route used by Ludwig
            url: '/situations/:situationId',
            template: '',
            controller: function(SituationService, $state, $stateParams) {
                $state.go('foyer.resultat', { situationId: $stateParams.situationId });
            }
        });
});

ddsApp.run(function($rootScope, $state, $stateParams, $window, $anchorScroll, $templateCache, $timeout) {
    $rootScope.$state = $state;
    $rootScope.$stateParams = $stateParams;

    // Offset de l'anchorscroll à 60px, nécessaire à cause de la navbar en position fixed
    $anchorScroll.yOffset = 60;

    // changement d'url vers /api => débranchement de ui-router
    $rootScope.$on('$locationChangeStart', function(e, location) {
        if (0 === location.indexOf($window.location.origin + '/api')) {
            e.preventDefault();
            $window.location.href = location;
        }
    });

    $rootScope.$on('$stateChangeSuccess', function focusTitleForScreenReaders(event, current) {
        if (current.preventFocus)
            return;

        $timeout(function() {  // add the function to the next angular digest cycle, waiting for the page to load before executing it
            var title = document.querySelector('h1');
            // if anyone wants to set a tabindex manually, do not overwrite it
            if (title && title.tabIndex < 0) {  // default is -1... https://html.spec.whatwg.org/multipage/interaction.html#dom-tabindex
                title.tabIndex = -1;  //...yet it has to be set to -1 to allow `.focus()`
                title.focus();
            }
        });
    });

    // Preload templates in cache
    // We use the keys() function of the context module API
    // to iterate over the templates, and we store them in Angular's template cache.
    // This means Angular won't try to load the template via AJAX
    _.forEach(template.keys(), function(path) {
        var cacheKey = path.replace('./', '/');
        $templateCache.put(cacheKey, template(path));
    });

    $rootScope.$on('$locationChangeSuccess', function(event, current) {
        if ($window._paq) {
            $window._paq.push(['setCustomUrl', current]);
            $window._paq.push(['trackPageView']);
        }
    });
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.servlet',
  name: 'VirtualHostRoutingServlet',

  implements: [
    'foam.nanos.servlet.Servlet'
  ],

  javaImports: [
    'foam.core.X',
    'foam.dao.DAO',
    'foam.nanos.jetty.HttpServer',
    'foam.nanos.logger.Logger',
    'foam.nanos.theme.Theme',
    'foam.nanos.theme.ThemeDomain',
    'java.io.IOException',
    'java.io.PrintWriter',
    'java.util.HashMap',
    'javax.servlet.ServletConfig',
    'javax.servlet.ServletException',
    'javax.servlet.ServletRequest',
    'javax.servlet.ServletResponse'
  ],

  properties: [
    {
      class: 'Map',
      name: 'customHostMapping',
      documentation: `Custom host mapping that will directly serve the index file for the specified virtual host.`
    },
    {
      class: 'Boolean',
      name: 'liveScriptBundlerDisabled',
      documentation: `If set to true, generate index file with live script bundler disabled.`,
      value: false
    },
    {
      class: 'Boolean',
      name: 'isResourceStorage',
      documentation: `If set to true, generate index file from jar file resources.`,
      value: false
    },
    {
      class: 'String',
      name: 'defaultHost'
    },
    {
      class: 'Object',
      transient: true,
      javaType: 'ServletConfig',
      name: 'servletConfig'
    }
  ],
  methods: [
    {
      name: 'destroy',
      type: 'Void',
      javaCode: '//noop'
    },
    {
      name: 'getServletInfo',
      type: 'String',
      javaCode: 'return "VirtualHostRoutingServlet";'
    },
    {
      name: 'init',
      type: 'Void',
      args: [ { name: 'config', javaType: 'ServletConfig' } ],
      javaCode: 'setServletConfig(config);',
      code: function() { }
    },
    {
      name: 'populateHead',
      type: 'Void',
      documentation: `Generates the index file's head content based on theme and prints it to the response writer.`,
      args: [
        { name: 'theme', javaType: 'Theme'},
        { name: 'out', javaType: 'PrintWriter'},
        { name: 'logger', javaType: 'Logger'}
      ],
      javaCode: `
      HashMap headConfig = (HashMap) theme.getHeadConfig();
      Boolean customFavIconFailed = false;
      Boolean customScriptsFailed = false;
      Boolean customFontsFailed = false;

      out.println("<meta charset=\\"utf-8\\"/>");
      out.print("<title>");
      out.print(theme.getAppName());
      out.println("</title>");

      // custom favicon
      if ( headConfig != null && headConfig.containsKey("customFavIcon") ) {
        try {
          String[] favIconTags = (String[]) headConfig.get("customFavIcon");
          for ( String tag : favIconTags ) {
            out.println(tag);
          }
        }
        catch ( Exception e ) {
          logger.error(e);
          customFavIconFailed = true;
        }
      }
      // default favicon
      if ( headConfig == null || ! headConfig.containsKey("customFavIcon") || customFavIconFailed ) {
        out.println("<link rel=\\"apple-touch-icon\\" sizes=\\"180x180\\" href=\\"/favicon/apple-touch-icon.png\\">");
        out.println("<link rel=\\"icon\\" type=\\"image/png\\" sizes=\\"32x32\\" href=\\"/favicon/favicon-32x32.png\\">");
        out.println("<link rel=\\"icon\\" type=\\"image/png\\" sizes=\\"16x16\\" href=\\"/favicon/favicon-16x16.png\\">");
        out.println("<link rel=\\"manifest\\" href=\\"/favicon/manifest.json\\">");
        out.println("<link rel=\\"mask-icon\\" href=\\"/favicon/safari-pinned-tab.svg\\" color=\\"#5bbad5\\">");
        out.println("<link rel=\\"shortcut icon\\" href=\\"/favicon/favicon.ico\\">");
        out.println("<meta name=\\"msapplication-config\\" content=\\"/favicon/browserconfig.xml\\">");
        out.println("<meta name=\\"theme-color\\" content=\\"#ffffff\\">");
      }

      // custom scripts
      if ( headConfig != null && headConfig.containsKey("customScripts") ) {
        try {
          String[] scriptTags = (String[]) headConfig.get("customScripts");
          for ( String tag : scriptTags ) {
            out.println(tag);
          }
        }
        catch ( Exception e ) {
          logger.error(e);
          customScriptsFailed = true;
        }
      }
      // default scripts
      if ( headConfig == null || ! headConfig.containsKey("customScripts") || customScriptsFailed ) {
        // jar file deployment
        if ( this.getIsResourceStorage() ) {
          out.println("");
          out.println("");
          out.println("");
          out.println("");
          out.println("");
        }
        // development
        else {
          if ( this.getLiveScriptBundlerDisabled() ) {
            out.println("");
            out.println("");
            out.println("");
            out.println("");
            out.println("");
            out.println("");
            out.println("");
          }
          else {
            out.println("");
          }
          out.println("");
          out.println("");
          out.println("");
          out.println("");
        }
      }

      // custom fonts
      if ( headConfig != null && headConfig.containsKey("customFonts") ) {
        try {
          String[] fontTags = (String[]) headConfig.get("customFonts");
          for ( String tag : fontTags ) {
            out.println(tag);
          }
        }
        catch ( Exception e ) {
          logger.error(e);
          customFontsFailed = true;
        }
      }
      // default fonts
      if ( headConfig == null || ! headConfig.containsKey("customFonts") || customFontsFailed ) {
        out.println("<link href=\\"https://fonts.googleapis.com/css?family=Roboto:100,300,400,500\\" rel=\\"stylesheet\\">");
        out.println("<link href=\\"https://fonts.googleapis.com/css?family=Lato:400,400i,700,700i,900,900i\\" rel=\\"stylesheet\\">");
        out.println("<link href=\\"https://fonts.googleapis.com/css?family=IBM+Plex+Sans&display=swap\\" rel=\\"stylesheet\\">");
      }
      `
    },
    {
      name: 'service',
      type: 'Void',
      args: [ { name: 'request', javaType: 'ServletRequest' },
              { name: 'response', javaType: 'ServletResponse' } ],
      javaThrows: [ 'ServletException', 'IOException' ],
      javaCode: `
        String vhost = request.getServerName();

        if ( getCustomHostMapping().containsKey(vhost) ) {
          request.getRequestDispatcher((String) getCustomHostMapping().get(vhost)).forward(request, response);
          return;
        }

        HttpServer server         = (HttpServer) this.getServletConfig().getServletContext().getAttribute("httpServer");
        X          x              = (X)          this.getServletConfig().getServletContext().getAttribute("X");
        DAO        themeDomainDAO = (DAO)        x.get("themeDomainDAO");
        DAO        themeDAO       = (DAO)        x.get("themeDAO");
        Logger     logger         = (Logger)     x.get("logger");

        if ( ! server.containsHostDomain(vhost) ) {
          vhost = getDefaultHost();
        }

        ThemeDomain themeDomain = (ThemeDomain) themeDomainDAO.find(vhost);
        if ( themeDomain == null ) {
          themeDomain = (ThemeDomain) themeDomainDAO.find(getDefaultHost());
        }
        if ( themeDomain == null ) {
          throw new RuntimeException("No theme domain found for default host " + getDefaultHost());
        }

        Theme theme = (Theme) themeDAO.find(themeDomain.getTheme());
        if ( theme == null ) {
          throw new RuntimeException("No theme found for theme domain " + themeDomain.getId());
        }

        response.setContentType("text/html; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");

        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE>");

        out.println("");
        out.println("");

        this.populateHead(theme, out, logger);

        out.println("");
        out.println("");

        out.println("");
        out.println("");
        out.print("<foam\\nclass=\\"net.nanopay.ui.Controller\\"\\nid=\\"ctrl\\"\\nwebApp=\\"");
        out.print(theme.getAppName());
        out.println("\\">\\n</foam>");

        out.println("");
        out.println("");
      `
    }
  ]
});
<commit_msg>fix foam version production bug<commit_after>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.servlet',
  name: 'VirtualHostRoutingServlet',

  implements: [
    'foam.nanos.servlet.Servlet'
  ],

  javaImports: [
    'foam.core.X',
    'foam.dao.DAO',
    'foam.nanos.app.AppConfig',
    'foam.nanos.jetty.HttpServer',
    'foam.nanos.logger.Logger',
    'foam.nanos.theme.Theme',
    'foam.nanos.theme.ThemeDomain',
    'java.io.IOException',
    'java.io.PrintWriter',
    'java.util.HashMap',
    'javax.servlet.ServletConfig',
    'javax.servlet.ServletException',
    'javax.servlet.ServletRequest',
    'javax.servlet.ServletResponse'
  ],

  properties: [
    {
      class: 'Map',
      name: 'customHostMapping',
      documentation: `Custom host mapping that will directly serve the index file for the specified virtual host.`
    },
    {
      class: 'Boolean',
      name: 'liveScriptBundlerDisabled',
      documentation: `If set to true, generate index file with live script bundler disabled.`,
      value: false
    },
    {
      class: 'Boolean',
      name: 'isResourceStorage',
      documentation: `If set to true, generate index file from jar file resources.`,
      value: false
    },
    {
      class: 'String',
      name: 'defaultHost'
    },
    {
      class: 'Object',
      transient: true,
      javaType: 'ServletConfig',
      name: 'servletConfig'
    }
  ],
  methods: [
    {
      name: 'destroy',
      type: 'Void',
      javaCode: '//noop'
    },
    {
      name: 'getServletInfo',
      type: 'String',
      javaCode: 'return "VirtualHostRoutingServlet";'
    },
    {
      name: 'init',
      type: 'Void',
      args: [ { name: 'config', javaType: 'ServletConfig' } ],
      javaCode: 'setServletConfig(config);',
      code: function() { }
    },
    {
      name: 'populateHead',
      type: 'Void',
      documentation: `Generates the index file's head content based on theme and prints it to the response writer.`,
      args: [
        { name: 'x', javaType: 'X'},
        { name: 'theme', javaType: 'Theme'},
        { name: 'logger', javaType: 'Logger'},
        { name: 'out', javaType: 'PrintWriter'}
      ],
      javaCode: `
      HashMap    headConfig          = (HashMap)   theme.getHeadConfig();
      AppConfig  appConfig           = (AppConfig) x.get("appConfig");
      Boolean    customFavIconFailed = false;
      Boolean    customScriptsFailed = false;
      Boolean    customFontsFailed   = false;

      out.println("<meta charset=\\"utf-8\\"/>");
      out.print("<title>");
      out.print(theme.getAppName());
      out.println("</title>");

      // custom favicon
      if ( headConfig != null && headConfig.containsKey("customFavIcon") ) {
        try {
          String[] favIconTags = (String[]) headConfig.get("customFavIcon");
          for ( String tag : favIconTags ) {
            out.println(tag);
          }
        }
        catch ( Exception e ) {
          logger.error(e);
          customFavIconFailed = true;
        }
      }
      // default favicon
      if ( headConfig == null || ! headConfig.containsKey("customFavIcon") || customFavIconFailed ) {
        out.println("<link rel=\\"apple-touch-icon\\" sizes=\\"180x180\\" href=\\"/favicon/apple-touch-icon.png\\">");
        out.println("<link rel=\\"icon\\" type=\\"image/png\\" sizes=\\"32x32\\" href=\\"/favicon/favicon-32x32.png\\">");
        out.println("<link rel=\\"icon\\" type=\\"image/png\\" sizes=\\"16x16\\" href=\\"/favicon/favicon-16x16.png\\">");
        out.println("<link rel=\\"manifest\\" href=\\"/favicon/manifest.json\\">");
        out.println("<link rel=\\"mask-icon\\" href=\\"/favicon/safari-pinned-tab.svg\\" color=\\"#5bbad5\\">");
        out.println("<link rel=\\"shortcut icon\\" href=\\"/favicon/favicon.ico\\">");
        out.println("<meta name=\\"msapplication-config\\" content=\\"/favicon/browserconfig.xml\\">");
        out.println("<meta name=\\"theme-color\\" content=\\"#ffffff\\">");
      }

      // custom scripts
      if ( headConfig != null && headConfig.containsKey("customScripts") ) {
        try {
          String[] scriptTags = (String[]) headConfig.get("customScripts");
          for ( String tag : scriptTags ) {
            out.println(tag);
          }
        }
        catch ( Exception e ) {
          logger.error(e);
          customScriptsFailed = true;
        }
      }
      // default scripts
      if ( headConfig == null || ! headConfig.containsKey("customScripts") || customScriptsFailed ) {
        // jar file deployment
        if ( this.getIsResourceStorage() ) {
          out.print("");
          out.println("");
          out.println("");
          out.println("");
          out.println("");
        }
        // development
        else {
          if ( this.getLiveScriptBundlerDisabled() ) {
            out.println("");
            out.println("");
            out.println("");
            out.println("");
            out.println("");
            out.println("");
            out.println("");
          }
          else {
            out.println("");
          }
          out.println("");
          out.println("");
          out.println("");
          out.println("");
        }
      }

      // custom fonts
      if ( headConfig != null && headConfig.containsKey("customFonts") ) {
        try {
          String[] fontTags = (String[]) headConfig.get("customFonts");
          for ( String tag : fontTags ) {
            out.println(tag);
          }
        }
        catch ( Exception e ) {
          logger.error(e);
          customFontsFailed = true;
        }
      }
      // default fonts
      if ( headConfig == null || ! headConfig.containsKey("customFonts") || customFontsFailed ) {
        out.println("<link href=\\"https://fonts.googleapis.com/css?family=Roboto:100,300,400,500\\" rel=\\"stylesheet\\">");
        out.println("<link href=\\"https://fonts.googleapis.com/css?family=Lato:400,400i,700,700i,900,900i\\" rel=\\"stylesheet\\">");
        out.println("<link href=\\"https://fonts.googleapis.com/css?family=IBM+Plex+Sans&display=swap\\" rel=\\"stylesheet\\">");
      }
      `
    },
    {
      name: 'service',
      type: 'Void',
      args: [ { name: 'request', javaType: 'ServletRequest' },
              { name: 'response', javaType: 'ServletResponse' } ],
      javaThrows: [ 'ServletException', 'IOException' ],
      javaCode: `
        String vhost = request.getServerName();

        if ( getCustomHostMapping().containsKey(vhost) ) {
          request.getRequestDispatcher((String) getCustomHostMapping().get(vhost)).forward(request, response);
          return;
        }

        HttpServer server         = (HttpServer) this.getServletConfig().getServletContext().getAttribute("httpServer");
        X          x              = (X)          this.getServletConfig().getServletContext().getAttribute("X");
        DAO        themeDomainDAO = (DAO)        x.get("themeDomainDAO");
        DAO        themeDAO       = (DAO)        x.get("themeDAO");
        Logger     logger         = (Logger)     x.get("logger");

        if ( ! server.containsHostDomain(vhost) ) {
          vhost = getDefaultHost();
        }

        ThemeDomain themeDomain = (ThemeDomain) themeDomainDAO.find(vhost);
        if ( themeDomain == null ) {
          themeDomain = (ThemeDomain) themeDomainDAO.find(getDefaultHost());
          if ( themeDomain == null ) {
            themeDomain = (ThemeDomain) themeDomainDAO.find("localhost");
            logger.warning("No theme domain found for default host " + getDefaultHost()+". Falling back to localhost");
          }
        }

        Theme theme = (Theme) themeDAO.find(themeDomain.getTheme());
        if ( theme == null ) {
          throw new RuntimeException("No theme found for theme domain " + themeDomain.getId());
        }

        response.setContentType("text/html; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");

        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE>");

        out.println("");
        out.println("");

        this.populateHead(x, theme, logger, out);

        out.println("");
        out.println("");

        out.println("");
        out.println("");
        out.print("<foam\\nclass=\\"net.nanopay.ui.Controller\\"\\nid=\\"ctrl\\"\\nwebApp=\\"");
        out.print(theme.getAppName());
        out.println("\\">\\n</foam>");

        out.println("");
        out.println("");
      `
    }
  ]
});
<|endoftext|>


<commit_before>/*
 * remote-dependencies.js: Common utility functions for working with remoteDependencies.
 *
 * (C) 2010, Nodejitsu Inc.
 *
 */

var path = require('path'),
    semver = require('semver'),
    cycle = require('cycle'),
    utile = require('utile'),
    wtfos = require('wtfos'),
    async = utile.async,
    validate = require('./validate');

//
// ### @private {RegExp} refPattern
// Regular expression for extracting circular
// remoteDependency names.
//
var refPattern = /\[\"([\w|\_|\-|\.]+)\"\]$/;

//
// ### function runlist (options, callback)
// #### @options {Object} Options for calculating the remote runlist.
// ####   @options.os       {string} OS for the runlist.
// ####   @options.list     {Array}  Current runlist found.
// ####   @options.depth    {number} Depth in the current runlist.
// ####   @options.maxDepth {number} Max depth of the runlist.
// ####   @options.systems  {object} Systems to add to the runlist.
// ####   @options.all      {object}  Set of all dependencies resolved.
// #### @callback {function} Continuation to respond to when complete.
//
// Creates a runlist for the specified `systems` filtering only `remoteDependencies`.
//
// 1. (in-order) `unshift` each system with version onto the list.
//   * If the system exists in the `list` validate the version.
//     * If there is a conflict, respond with error.
// 2. Recursively add the runlist of each of the `remoteDependencies` to the list.
//
exports.runlist = function (options) {
  var os       = options.os,
      all      = options.all   || {},
      list     = options.list  || [],
      depth    = options.depth || 0,
      maxDepth = options.maxDepth,
      systems  = options.systems;

  function trimRunlist(record) {
    for (var i = 0; i < list.length; i++) {
      if (list[i].name === record.name) {
        //
        // TODO: Check semver equality here.
        //
        list.splice(i, 1);
      }
    }
  }

  //
  // Helper function which builds the sublist for
  // `name` and unshifts it into the parent `list`.
  //
  function updateList(system, next) {
    var names    = list.map(function (d) { return d.name }),
        exists   = !!~names.indexOf(system.name),
        previous = 0,
        remoteDependencies,
        dependencies,
        invalid,
        record,
        deps;

    record = {
      name:    system.name,
      semver:  system.required,
      scripts: system.scripts,
      config:  system.config,
      version: system.version
    };

    if (system.remoteDependencies) {
      remoteDependencies = Object.keys(system.remoteDependencies);
      remoteDependencies.forEach(function (name) {
        var index = names.indexOf(name);
        if (index > previous) {
          previous = index;
        }
      });
    }

    if (list.length) {
      //
      // Remark: Could be an error case here if versions mismatch...
      //
      trimRunlist(record);
    }

    if (options.parent) {
      if (!previous) {
        list.unshift(record);
      }
      else if (previous) {
        list.splice(previous, 0, record);
      }

      all[record.name] = all[record.name]
        ? all[record.name] + 1
        : 1;
    }

    if (!system.remoteDependencies && !system.runlist) {
      return;
    }

    if (remoteDependencies) {
      system.runlist = remoteDependencies.concat(
        (system.runlist || []).filter(function (name) {
          return remoteDependencies.indexOf(name) === -1;
        })
      );
    }

    invalid = validate(system, os);
    if (invalid) {
      throw invalid;
    }

    //
    // Remove any remoteDependencies from the
    // system runlist
    //
    if (system.dependencies && system.runlist) {
      dependencies = Object.keys(system.dependencies);
      system.runlist = system.runlist.filter(function (name) {
        return dependencies.indexOf(name) === -1;
      });
    }

    deps = (deps || [])
      .concat((system.runlist || []).map(function (name) {
        return system.remoteDependencies[name];
      }))
      .reverse()
      .filter(function (dep) {
        return dep && (!all[dep.name]
          || all[dep.name] < 3);
      });

    //
    // Add the remoteDependencies for any of this systems
    // remoteDependencies
    //
    exports.runlist({
      os: os,
      all: utile.clone(all),
      list: list,
      systems: deps,
      parent: record,
      depth: depth++,
      maxDepth: maxDepth
    });

    //
    // Add the remoteDependencies for any of this systems
    // dependencies
    //
    dependencies = dependencies.filter(function (name) {
      all[name] = all[name] ? all[name] + 1 : 1;
      return all[name] < 3;
    }).map(function (name) {
      return system.dependencies[name]
    });

    exports.runlist({
      os: os,
      all: utile.clone(all),
      list: list,
      systems: dependencies,
      depth: depth++,
      maxDepth: maxDepth
    });
  }

  //
  // If we've exceeded the maximum depth then
  // respond immediately.
  //
  if (maxDepth && depth > maxDepth) {
    return list;
  }

  if (!Array.isArray(systems)) {
    systems = Object.keys(systems).map(function (name) {
      return systems[name];
    });
  }

  systems.forEach(updateList);
  return list;
};

//
// ### function verifyRunlist (options, callback)
// #### @options {Object} Options to verify the remote runlist.
// ####   @options.runlist {Array} Set of ordered remote dependencies
// ####   @options.client  {Client}       API Client for fetching config.
// #### @callback {function} Continuation to respond to.
// Verifies that the necessary servers exist to satisfy the
// remote `runlist`.
//
exports.verifyRunlist = function (options, callback) {
  var runlist = options.runlist,
      client  = options.client;

  if (!runlist || !runlist.length || !client || !client.servers) {
    return callback();
  }

  client.servers(function (err, config) {
    if (err) {
      return callback(err);
    }

    var satisfying,
        missing;

    //
    // Calculate the satisfying addresses for the specified
    // remoteDependencies in the `runlist`.
    //
    satisfying = runlist.reduce(function (all, system) {
      all[system.name] = config[system.name];
      return all;
    }, {});

    //
    // Check if there are any missing remoteDependencies
    // in the `runlist`.
    //
    missing = runlist.map(function (system) {
      return system.name;
    }).filter(function (name) {
      return !config[name];
    });

    if (missing.length) {
      err = new Error('Missing remoteDependencies: ' + missing.join(', '));
      err.missing = missing;
      return callback(err);
    }

    callback(null, satisfying);
  });
};

//
// ### function cycles (systems)
// #### @systems {Object} Systems to detect cycles in
// Returns an object literal containing any cycles found in the `systems`.
//
exports.cycles = function (systems) {
  var decycle  = cycle.decycle(systems),
      circular = {};

  //
  // Helper function which adds the circular
  // dependency between `lval` and `rval`.
  //
  function addCycle(lval, rval) {
    circular[lval] = circular[lval] || [];
    circular[rval] = circular[rval] || [];
    circular[lval].push(rval);
    circular[rval].push(lval);
  }

  //
  // Helper function that adds any "$ref"
  // cycles to the set of `circular`
  // remoteDependencies.
  //
  function addCircular(system, parents) {
    var deps = system.remoteDependencies
      && Object.keys(system.remoteDependencies);

    if (!deps || !deps.length) {
      return;
    }

    deps.forEach(function (name) {
      var ref = system.remoteDependencies[name]['$ref'],
          refName,
          match;

      if (!ref) {
        //
        // Create a copy of parents for this part of the
        // path iteration.
        //
        parents = parents ? parents.slice() : [];
        return addCircular(
          system.remoteDependencies[name],
          parents.concat(system.name)
        );
      }

      if ((match = refPattern.exec(ref))) {
        refName = match[1];
        if (~parents.indexOf(refName)) {
          addCycle(refName, system.name);
        }
      }
    });
  }

  //
  // Build all references in the decycled object which may
  // (potentially) be cycles in `remoteDependencies`.
  //
  Object.keys(decycle).forEach(function (name) {
    addCircular(decycle[name]);
  });

  return circular;
};<commit_msg>[fix] Dont add multiple instances of circular remoteDependencies.<commit_after>/*
 * remote-dependencies.js: Common utility functions for working with remoteDependencies.
 *
 * (C) 2010, Nodejitsu Inc.
 *
 */

var path = require('path'),
    semver = require('semver'),
    cycle = require('cycle'),
    utile = require('utile'),
    wtfos = require('wtfos'),
    async = utile.async,
    validate = require('./validate');

//
// ### @private {RegExp} refPattern
// Regular expression for extracting circular
// remoteDependency names.
//
var refPattern = /\[\"([\w|\_|\-|\.]+)\"\]$/;

//
// ### function runlist (options, callback)
// #### @options {Object} Options for calculating the remote runlist.
// ####   @options.os       {string} OS for the runlist.
// ####   @options.list     {Array}  Current runlist found.
// ####   @options.depth    {number} Depth in the current runlist.
// ####   @options.maxDepth {number} Max depth of the runlist.
// ####   @options.systems  {object} Systems to add to the runlist.
// ####   @options.all      {object}  Set of all dependencies resolved.
// #### @callback {function} Continuation to respond to when complete.
//
// Creates a runlist for the specified `systems` filtering only `remoteDependencies`.
//
// 1. (in-order) `unshift` each system with version onto the list.
//   * If the system exists in the `list` validate the version.
//     * If there is a conflict, respond with error.
// 2. Recursively add the runlist of each of the `remoteDependencies` to the list.
//
exports.runlist = function (options) {
  var os       = options.os,
      all      = options.all   || {},
      list     = options.list  || [],
      depth    = options.depth || 0,
      maxDepth = options.maxDepth,
      systems  = options.systems;

  function trimRunlist(record) {
    for (var i = 0; i < list.length; i++) {
      if (list[i].name === record.name) {
        //
        // TODO: Check semver equality here.
        //
        list.splice(i, 1);
      }
    }
  }

  //
  // Helper function which builds the sublist for
  // `name` and unshifts it into the parent `list`.
  //
  function updateList(system, next) {
    var names    = list.map(function (d) { return d.name }),
        exists   = !!~names.indexOf(system.name),
        previous = 0,
        remoteDependencies,
        dependencies,
        invalid,
        record,
        deps;

    record = {
      name:    system.name,
      semver:  system.required,
      scripts: system.scripts,
      config:  system.config,
      version: system.version
    };

    if (system.remoteDependencies) {
      remoteDependencies = Object.keys(system.remoteDependencies);
      remoteDependencies.forEach(function (name) {
        var index = names.indexOf(name);
        if (index > previous) {
          previous = index;
        }
      });
    }

    if (list.length) {
      //
      // Remark: Could be an error case here if versions mismatch...
      //
      trimRunlist(record);
    }

    if (options.parent) {
      if (!previous) {
        list.unshift(record);
      }
      else if (previous) {
        list.splice(previous, 0, record);
      }

      all[record.name] = all[record.name]
        ? all[record.name] + 1
        : 1;
    }

    if (!system.remoteDependencies && !system.runlist) {
      return;
    }

    if (remoteDependencies) {
      system.runlist = remoteDependencies.concat(
        (system.runlist || []).filter(function (name) {
          return remoteDependencies.indexOf(name) === -1;
        })
      );
    }

    invalid = validate(system, os);
    if (invalid) {
      throw invalid;
    }

    //
    // Remove any remoteDependencies from the
    // system runlist
    //
    if (system.dependencies && system.runlist) {
      dependencies = Object.keys(system.dependencies);
      system.runlist = system.runlist.filter(function (name) {
        return dependencies.indexOf(name) === -1;
      });
    }

    deps = (deps || [])
      .concat((system.runlist || []).map(function (name) {
        return system.remoteDependencies[name];
      }))
      .reverse()
      .filter(function (dep) {
        return dep && (!all[dep.name]
          || all[dep.name] < 3);
      });

    //
    // Add the remoteDependencies for any of this systems
    // remoteDependencies
    //
    exports.runlist({
      os: os,
      all: utile.clone(all),
      list: list,
      systems: deps,
      parent: record,
      depth: depth++,
      maxDepth: maxDepth
    });

    //
    // Add the remoteDependencies for any of this systems
    // dependencies
    //
    dependencies = dependencies.filter(function (name) {
      all[name] = all[name] ? all[name] + 1 : 1;
      return all[name] < 3;
    }).map(function (name) {
      return system.dependencies[name]
    });

    exports.runlist({
      os: os,
      all: utile.clone(all),
      list: list,
      systems: dependencies,
      depth: depth++,
      maxDepth: maxDepth
    });
  }

  //
  // If we've exceeded the maximum depth then
  // respond immediately.
  //
  if (maxDepth && depth > maxDepth) {
    return list;
  }

  if (!Array.isArray(systems)) {
    systems = Object.keys(systems).map(function (name) {
      return systems[name];
    });
  }

  systems.forEach(updateList);
  return list;
};

//
// ### function verifyRunlist (options, callback)
// #### @options {Object} Options to verify the remote runlist.
// ####   @options.runlist {Array} Set of ordered remote dependencies
// ####   @options.client  {Client}       API Client for fetching config.
// #### @callback {function} Continuation to respond to.
// Verifies that the necessary servers exist to satisfy the
// remote `runlist`.
//
exports.verifyRunlist = function (options, callback) {
  var runlist = options.runlist,
      client  = options.client;

  if (!runlist || !runlist.length || !client || !client.servers) {
    return callback();
  }

  client.servers(function (err, config) {
    if (err) {
      return callback(err);
    }

    var satisfying,
        missing;

    //
    // Calculate the satisfying addresses for the specified
    // remoteDependencies in the `runlist`.
    //
    satisfying = runlist.reduce(function (all, system) {
      all[system.name] = config[system.name];
      return all;
    }, {});

    //
    // Check if there are any missing remoteDependencies
    // in the `runlist`.
    //
    missing = runlist.map(function (system) {
      return system.name;
    }).filter(function (name) {
      return !config[name];
    });

    if (missing.length) {
      err = new Error('Missing remoteDependencies: ' + missing.join(', '));
      err.missing = missing;
      return callback(err);
    }

    callback(null, satisfying);
  });
};

//
// ### function cycles (systems)
// #### @systems {Object} Systems to detect cycles in
// Returns an object literal containing any cycles found in the `systems`.
//
exports.cycles = function (systems) {
  var decycle  = cycle.decycle(systems),
      circular = {};

  //
  // Helper function which adds the circular
  // dependency between `lval` and `rval`.
  //
  function addCycle(lval, rval) {
    circular[lval] = circular[lval] || [];
    circular[rval] = circular[rval] || [];

    if (!~circular[lval].indexOf(rval)) {
      circular[lval].push(rval);
    }

    if (!~circular[rval].indexOf(lval)) {
      circular[rval].push(lval);
    }
  }

  //
  // Helper function that adds any "$ref"
  // cycles to the set of `circular`
  // remoteDependencies.
  //
  function addCircular(system, parents) {
    var deps = system.remoteDependencies
      && Object.keys(system.remoteDependencies);

    if (!deps || !deps.length) {
      return;
    }

    deps.forEach(function (name) {
      var ref = system.remoteDependencies[name]['$ref'],
          refName,
          match;

      if (!ref) {
        //
        // Create a copy of parents for this part of the
        // path iteration.
        //
        parents = parents ? parents.slice() : [];
        return addCircular(
          system.remoteDependencies[name],
          parents.concat(system.name)
        );
      }

      if ((match = refPattern.exec(ref))) {
        refName = match[1];
        if (~parents.indexOf(refName)) {
          addCycle(refName, system.name);
        }
      }
    });
  }

  //
  // Build all references in the decycled object which may
  // (potentially) be cycles in `remoteDependencies`.
  //
  Object.keys(decycle).forEach(function (name) {
    addCircular(decycle[name]);
  });

  return circular;
};<|endoftext|>