<commit_before>const rollup = require("rollup");
const babel = require("rollup-plugin-babel");
const eslint = require("rollup-plugin-eslint").eslint;
const terser = require("terser");
const gzipSize = require("gzip-size");
const fs = require("fs");
const path = require("path");
const version = require("../package.json").version;
const spacesRE = /  /g;
const versionRE = /process\.env\.MOON_VERSION/g;
const envRE = /process\.env\.MOON_ENV/g;

const resolver = {
	resolveId(id, origin) {
		return path.extname(id) === "" ? path.join("./packages", id) + ".js" : id;
	}
};

async function build(package) {
	const options = require(`../packages/${package}/config.js`);
	const name = options.name;
	const nameExport = options.nameExport;
	const type = options.type;

	const comment = `${type === "executable" ? "#!/usr/bin/env node\n" : ""}/**
 * ${name} v${version}
 * Copyright 2016-2019 Kabir Shah
 * Released under the MIT License
 * https://kbrsh.github.io/moon
 */\r\n`;

	try {
		const bundle = await rollup.rollup({
			input: `./packages/${package}/src/index.js`,
			plugins: [
				resolver,
				eslint(),
				babel()
			],
			onwarn: warning => {
				if (warning.code !== "CIRCULAR_DEPENDENCY") {
					console.warn(`Rollup [Warn]: ${warning}`);
				}
			}
		});

		let { output } = await bundle.generate({
			name: nameExport,
			format: "iife"
		});

		output = output[0].code;

		if (type === "module") {
			output = fs.readFileSync("./build/wrapper.js", "utf8").replace("MODULE_NAME", nameExport).replace("MODULE_CONTENT", output.split("\n").slice(1, -3).join("\n"));
		}

		output = output.replace(spacesRE, "\t");
		output = output.replace("'use strict'", "\"use strict\"");
		output = output.replace(versionRE, `"${version}"`);

		const developmentCode = comment + output.replace(envRE, "\"development\"");
		const productionCode = comment + terser.minify(output.replace(envRE, "\"production\""), {
			output: {
				ascii_only: true
			}
		}).code;

		fs.writeFileSync(`./packages/${package}/dist/${package}.js`, developmentCode);
		fs.writeFileSync(`./packages/${package}/dist/${package}.min.js`, productionCode);

		console.log(`${name} development -> ${developmentCode.length / 1000}kb / ${gzipSize.sync(developmentCode) / 1000}kb (gzip)`);
		console.log(`${name} production -> ${productionCode.length / 1000}kb / ${gzipSize.sync(productionCode) / 1000}kb (gzip)\n`);
	} catch (error) {
		console.error(error);
	}
}

const packages = fs.readdirSync("./packages");

for (let i = 0; i < packages.length; i++) {
	const package = packages[i];

	if (package.slice(0, 4) === "moon" && fs.lstatSync(`./packages/${package}`).isDirectory()) {
		build(packages[i]);
	}
}
<commit_msg>use stat over lstat<commit_after>const rollup = require("rollup");
const babel = require("rollup-plugin-babel");
const eslint = require("rollup-plugin-eslint").eslint;
const terser = require("terser");
const gzipSize = require("gzip-size");
const fs = require("fs");
const path = require("path");
const version = require("../package.json").version;
const spacesRE = /  /g;
const versionRE = /process\.env\.MOON_VERSION/g;
const envRE = /process\.env\.MOON_ENV/g;

const resolver = {
	resolveId(id, origin) {
		return path.extname(id) === "" ? path.join("./packages", id) + ".js" : id;
	}
};

async function build(package) {
	const options = require(`../packages/${package}/config.js`);
	const name = options.name;
	const nameExport = options.nameExport;
	const type = options.type;

	const comment = `${type === "executable" ? "#!/usr/bin/env node\n" : ""}/**
 * ${name} v${version}
 * Copyright 2016-2019 Kabir Shah
 * Released under the MIT License
 * https://kbrsh.github.io/moon
 */\r\n`;

	try {
		const bundle = await rollup.rollup({
			input: `./packages/${package}/src/index.js`,
			plugins: [
				resolver,
				eslint(),
				babel()
			],
			onwarn: warning => {
				if (warning.code !== "CIRCULAR_DEPENDENCY") {
					console.warn(`Rollup [Warn]: ${warning}`);
				}
			}
		});

		let { output } = await bundle.generate({
			name: nameExport,
			format: "iife"
		});

		output = output[0].code;

		if (type === "module") {
			output = fs.readFileSync("./build/wrapper.js", "utf8").replace("MODULE_NAME", nameExport).replace("MODULE_CONTENT", output.split("\n").slice(1, -3).join("\n"));
		}

		output = output.replace(spacesRE, "\t");
		output = output.replace("'use strict'", "\"use strict\"");
		output = output.replace(versionRE, `"${version}"`);

		const developmentCode = comment + output.replace(envRE, "\"development\"");
		const productionCode = comment + terser.minify(output.replace(envRE, "\"production\""), {
			output: {
				ascii_only: true
			}
		}).code;

		fs.writeFileSync(`./packages/${package}/dist/${package}.js`, developmentCode);
		fs.writeFileSync(`./packages/${package}/dist/${package}.min.js`, productionCode);

		console.log(`${name} development -> ${developmentCode.length / 1000}kb / ${gzipSize.sync(developmentCode) / 1000}kb (gzip)`);
		console.log(`${name} production -> ${productionCode.length / 1000}kb / ${gzipSize.sync(productionCode) / 1000}kb (gzip)\n`);
	} catch (error) {
		console.error(error);
	}
}

const packages = fs.readdirSync("./packages");

for (let i = 0; i < packages.length; i++) {
	const package = packages[i];

	if (package.slice(0, 4) === "moon" && fs.statSync(`./packages/${package}`).isDirectory()) {
		build(packages[i]);
	}
}
<|endoftext|>


<commit_before>import * as d3 from 'd3';
import _ from 'lodash';
import { d3keybinding } from '../lib/d3.keybinding.js';
import { t } from '../util/locale';

import { actionAddMidpoint } from '../actions/index';

import {
    behaviorBreathe,
    behaviorCopy,
    behaviorHover,
    behaviorLasso,
    behaviorPaste,
    behaviorSelect
} from '../behavior/index';

import {
    geoExtent,
    geoChooseEdge,
    geoPointInPolygon
} from '../geo/index';

import {
    osmNode,
    osmWay
} from '../osm/index';

import { modeBrowse } from './browse';
import { modeDragNode } from './drag_node';
import * as Operations from '../operations/index';
import { uiEditMenu, uiSelectionList } from '../ui';
import { uiCmd } from '../ui/cmd';
import { utilEntityOrMemberSelector, utilEntitySelector } from '../util';

// deprecation warning - Radial Menu to be removed in iD v3
import { uiRadialMenu } from '../ui';

var relatedParent;

export function modeSelect(context, selectedIDs) {
    var mode = {
        id: 'select',
        button: 'browse'
    };

    var keybinding = d3keybinding('select'),
        timeout = null,
        behaviors = [
            behaviorCopy(context),
            behaviorPaste(context),
            behaviorBreathe(context),
            behaviorHover(context),
            behaviorSelect(context),
            behaviorLasso(context),
            modeDragNode(context).selectedIDs(selectedIDs).behavior
        ],
        inspector,
        editMenu,
        newFeature = false,
        suppressMenu = true,
        follow = false;

    var wrap = context.container()
        .select('.inspector-wrap');

    function singular() {
        if (selectedIDs.length === 1) {
            return context.hasEntity(selectedIDs[0]);
        }
    }

    function checkSelectedIDs() {
        var ids = [];
        if (Array.isArray(selectedIDs)) {
            ids = selectedIDs.filter(function(id) {
                return context.hasEntity(id);
            });
        }

        if (ids.length) {
            selectedIDs = ids;
        } else {
            context.enter(modeBrowse(context));
        }
        return !!ids.length;
    }

    // find the common parent ways for nextVertex, previousVertex
    function commonParents() {
        var graph = context.graph(),
            commonParents = [];

        for (var i = 0; i < selectedIDs.length; i++) {
            var entity = context.hasEntity(selectedIDs[i]);
            if (!entity || entity.geometry(graph) !== 'vertex') {
                return [];  // selection includes some not vertexes
            }

            var currParents = _.map(graph.parentWays(entity), 'id');
            if (!commonParents.length) {
                commonParents = currParents;
                continue;
            }

            commonParents = _.intersection(commonParents, currParents);
            if (!commonParents.length) {
                return [];
            }
        }

        return commonParents;
    }

    function singularParent() {
        var parents = commonParents();
        if (!parents || parents.length === 0) {
            relatedParent = null;
            return null;
        }

        // relatedParent is used when we visit a vertex with multiple
        // parents, and we want to remember which parent line we started on.

        if (parents.length === 1) {
            relatedParent = parents[0];  // remember this parent for later
            return relatedParent;
        }

        if (parents.indexOf(relatedParent) !== -1) {
            return relatedParent;   // prefer the previously seen parent
        }

        return parents[0];
    }

    function closeMenu() {
        if (editMenu) {
            context.surface().call(editMenu.close);
        }
    }

    function positionMenu() {
        if (!editMenu) { return; }

        var entity = singular();
        if (entity && context.geometry(entity.id) === 'relation') {
            suppressMenu = true;
        } else {
            var point = context.mouse(),
                viewport = geoExtent(context.projection.clipExtent()).polygon();

            if (geoPointInPolygon(point, viewport)) {
                editMenu.center(point);
            }
        }
    }

    function showMenu() {
        closeMenu();
        if (editMenu) {
            context.surface().call(editMenu);
        }
    }

    function toggleMenu() {
        // deprecation warning - Radial Menu to be removed in iD v3
        if (d3.select('.edit-menu, .radial-menu').empty()) {
            positionMenu();
            showMenu();
        } else {
            closeMenu();
        }
    }

    mode.selectedIDs = function() {
        return selectedIDs;
    };

    mode.reselect = function() {
        if (!checkSelectedIDs()) return;

        var surfaceNode = context.surface().node();
        if (surfaceNode.focus) {   // FF doesn't support it
            surfaceNode.focus();
        }

        positionMenu();
        if (!suppressMenu) {
            showMenu();
        }
    };

    mode.newFeature = function(_) {
        if (!arguments.length) return newFeature;
        newFeature = _;
        return mode;
    };

    mode.suppressMenu = function(_) {
        if (!arguments.length) return suppressMenu;
        suppressMenu = _;
        return mode;
    };

    mode.follow = function(_) {
        if (!arguments.length) return follow;
        follow = _;
        return mode;
    };

    mode.enter = function() {

        function update() {
            closeMenu();
            checkSelectedIDs();
        }

        function dblclick() {
            var target = d3.select(d3.event.target),
                datum = target.datum();

            if (datum instanceof osmWay && !target.classed('fill')) {
                var choice = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection),
                    prev = datum.nodes[choice.index - 1],
                    next = datum.nodes[choice.index];

                context.perform(
                    actionAddMidpoint({loc: choice.loc, edge: [prev, next]}, osmNode()),
                    t('operations.add.annotation.vertex')
                );

                d3.event.preventDefault();
                d3.event.stopPropagation();

            } else if (datum.type === 'midpoint') {
                context.perform(
                    actionAddMidpoint({loc: datum.loc, edge: datum.edge}, osmNode()),
                    t('operations.add.annotation.vertex'));

                d3.event.preventDefault();
                d3.event.stopPropagation();
            }
        }

        function selectElements(drawn) {
            if (!checkSelectedIDs()) return;

            var surface = context.surface(),
                entity = singular();

            if (entity && context.geometry(entity.id) === 'relation') {
                suppressMenu = true;
                return;
            }

            surface.selectAll('.related')
                .classed('related', false);

            singularParent();
            if (relatedParent) {
                surface.selectAll(utilEntitySelector([relatedParent]))
                    .classed('related', true);
            }

            var selection = context.surface()
                .selectAll(utilEntityOrMemberSelector(selectedIDs, context.graph()));

            if (selection.empty()) {
                // Return to browse mode if selected DOM elements have
                // disappeared because the user moved them out of view..
                var source = d3.event && d3.event.type === 'zoom' && d3.event.sourceEvent;
                if (drawn && source && (source.type === 'mousemove' || source.type === 'touchmove')) {
                    context.enter(modeBrowse(context));
                }
            } else {
                selection
                    .classed('selected', true);
            }
        }

        function esc() {
            if (!context.inIntro()) {
                context.enter(modeBrowse(context));
            }
        }

        function firstVertex() {
            d3.event.preventDefault();
            var parent = singularParent();
            if (parent) {
                var way = context.entity(parent);
                context.enter(
                    modeSelect(context, [way.first()]).follow(true)
                );
            }
        }

        function lastVertex() {
            d3.event.preventDefault();
            var parent = singularParent();
            if (parent) {
                var way = context.entity(parent);
                context.enter(
                    modeSelect(context, [way.last()]).follow(true)
                );
            }
        }

        function previousVertex() {
            d3.event.preventDefault();
            var parent = singularParent();
            if (!parent) return;

            var way = context.entity(parent),
                length = way.nodes.length,
                curr = way.nodes.indexOf(selectedIDs[0]),
                index = -1;

            if (curr > 0) {
                index = curr - 1;
            } else if (way.isClosed()) {
                index = length - 2;
            }

            if (index !== -1) {
                context.enter(
                    modeSelect(context, [way.nodes[index]]).follow(true)
                );
            }
        }

        function nextVertex() {
            d3.event.preventDefault();
            var parent = singularParent();
            if (!parent) return;

            var way = context.entity(parent),
                length = way.nodes.length,
                curr = way.nodes.indexOf(selectedIDs[0]),
                index = -1;

            if (curr < length - 1) {
                index = curr + 1;
            } else if (way.isClosed()) {
                index = 0;
            }

            if (index !== -1) {
                context.enter(
                    modeSelect(context, [way.nodes[index]]).follow(true)
                );
            }
        }

        function nextParent() {
            d3.event.preventDefault();
            var parents = _.uniq(commonParents());
            if (!parents || parents.length < 2) return;

            var index = parents.indexOf(relatedParent);
            if (index < 0 || index > parents.length - 2) {
                relatedParent = parents[0];
            } else {
                relatedParent = parents[index + 1];
            }

            var surface = context.surface();
            surface.selectAll('.related')
                .classed('related', false);

            if (relatedParent) {
                surface.selectAll(utilEntitySelector([relatedParent]))
                    .classed('related', true);
            }
        }

        if (!checkSelectedIDs()) return;

        var operations = _.without(d3.values(Operations), Operations.operationDelete)
                .map(function(o) { return o(selectedIDs, context); })
                .filter(function(o) { return o.available(); });

        // deprecation warning - Radial Menu to be removed in iD v3
        var isRadialMenu = context.storage('edit-menu-style') === 'radial';
        if (isRadialMenu) {
            operations = operations.slice(0,7);
            operations.unshift(Operations.operationDelete(selectedIDs, context));
        } else {
            operations.push(Operations.operationDelete(selectedIDs, context));
        }

        operations.forEach(function(operation) {
            if (operation.behavior) {
                behaviors.push(operation.behavior);
            }
        });

        behaviors.forEach(function(behavior) {
            context.install(behavior);
        });

        keybinding
            .on(['[','pgup'], previousVertex)
            .on([']', 'pgdown'], nextVertex)
            .on([uiCmd('⌘['), 'home'], firstVertex)
            .on([uiCmd('⌘]'), 'end'], lastVertex)
            .on(['\\', 'pause'], nextParent)
            .on('⎋', esc, true)
            .on('space', toggleMenu);

        d3.select(document)
            .call(keybinding);

        // deprecation warning - Radial Menu to be removed in iD v3
        editMenu = isRadialMenu
            ? uiRadialMenu(context, operations)
            : uiEditMenu(context, operations);

        context.ui().sidebar
            .select(singular() ? singular().id : null, newFeature);

        context.history()
            .on('undone.select', update)
            .on('redone.select', update);

        context.map()
            .on('move.select', closeMenu)
            .on('drawn.select', selectElements);

        context.surface()
            .on('dblclick.select', dblclick);

        selectElements();

        if (selectedIDs.length > 1) {
            var entities = uiSelectionList(context, selectedIDs);
            context.ui().sidebar.show(entities);
        }

        if (follow) {
            var extent = geoExtent(),
                graph = context.graph();
            selectedIDs.forEach(function(id) {
                var entity = context.entity(id);
                extent._extend(entity.extent(graph));
            });

            var loc = extent.center();
            context.map().centerEase(loc);
        }

        timeout = window.setTimeout(function() {
            positionMenu();
            if (!suppressMenu) {
                showMenu();
            }
        }, 270);  /* after any centerEase completes */

    };

    mode.exit = function() {
        if (timeout) window.clearTimeout(timeout);

        if (inspector) wrap.call(inspector.close);

        behaviors.forEach(function(behavior) {
            context.uninstall(behavior);
        });

        keybinding.off();
        closeMenu();
        editMenu = undefined;

        context.history()
            .on('undone.select', null)
            .on('redone.select', null);

        var surface = context.surface();

        surface
            .on('dblclick.select', null);

        surface
            .selectAll('.selected')
            .classed('selected', false);

        surface
            .selectAll('.related')
            .classed('related', false);

        context.map().on('drawn.select', null);
        context.ui().sidebar.hide();
    };

    return mode;
}
<commit_msg>Guard code around geoPointInPolygon (closes #3876)<commit_after>import * as d3 from 'd3';
import _ from 'lodash';
import { d3keybinding } from '../lib/d3.keybinding.js';
import { t } from '../util/locale';

import { actionAddMidpoint } from '../actions/index';

import {
    behaviorBreathe,
    behaviorCopy,
    behaviorHover,
    behaviorLasso,
    behaviorPaste,
    behaviorSelect
} from '../behavior/index';

import {
    geoExtent,
    geoChooseEdge,
    geoPointInPolygon
} from '../geo/index';

import {
    osmNode,
    osmWay
} from '../osm/index';

import { modeBrowse } from './browse';
import { modeDragNode } from './drag_node';
import * as Operations from '../operations/index';
import { uiEditMenu, uiSelectionList } from '../ui';
import { uiCmd } from '../ui/cmd';
import { utilEntityOrMemberSelector, utilEntitySelector } from '../util';

// deprecation warning - Radial Menu to be removed in iD v3
import { uiRadialMenu } from '../ui';

var relatedParent;

export function modeSelect(context, selectedIDs) {
    var mode = {
        id: 'select',
        button: 'browse'
    };

    var keybinding = d3keybinding('select'),
        timeout = null,
        behaviors = [
            behaviorCopy(context),
            behaviorPaste(context),
            behaviorBreathe(context),
            behaviorHover(context),
            behaviorSelect(context),
            behaviorLasso(context),
            modeDragNode(context).selectedIDs(selectedIDs).behavior
        ],
        inspector,
        editMenu,
        newFeature = false,
        suppressMenu = true,
        follow = false;

    var wrap = context.container()
        .select('.inspector-wrap');

    function singular() {
        if (selectedIDs.length === 1) {
            return context.hasEntity(selectedIDs[0]);
        }
    }

    function checkSelectedIDs() {
        var ids = [];
        if (Array.isArray(selectedIDs)) {
            ids = selectedIDs.filter(function(id) {
                return context.hasEntity(id);
            });
        }

        if (ids.length) {
            selectedIDs = ids;
        } else {
            context.enter(modeBrowse(context));
        }
        return !!ids.length;
    }

    // find the common parent ways for nextVertex, previousVertex
    function commonParents() {
        var graph = context.graph(),
            commonParents = [];

        for (var i = 0; i < selectedIDs.length; i++) {
            var entity = context.hasEntity(selectedIDs[i]);
            if (!entity || entity.geometry(graph) !== 'vertex') {
                return [];  // selection includes some not vertexes
            }

            var currParents = _.map(graph.parentWays(entity), 'id');
            if (!commonParents.length) {
                commonParents = currParents;
                continue;
            }

            commonParents = _.intersection(commonParents, currParents);
            if (!commonParents.length) {
                return [];
            }
        }

        return commonParents;
    }

    function singularParent() {
        var parents = commonParents();
        if (!parents || parents.length === 0) {
            relatedParent = null;
            return null;
        }

        // relatedParent is used when we visit a vertex with multiple
        // parents, and we want to remember which parent line we started on.

        if (parents.length === 1) {
            relatedParent = parents[0];  // remember this parent for later
            return relatedParent;
        }

        if (parents.indexOf(relatedParent) !== -1) {
            return relatedParent;   // prefer the previously seen parent
        }

        return parents[0];
    }

    function closeMenu() {
        if (editMenu) {
            context.surface().call(editMenu.close);
        }
    }

    function positionMenu() {
        if (!editMenu) { return; }

        var entity = singular();
        if (entity && context.geometry(entity.id) === 'relation') {
            suppressMenu = true;
        } else {
            var point = context.mouse(),
                viewport = geoExtent(context.projection.clipExtent()).polygon();

            if (point && geoPointInPolygon(point, viewport)) {
                editMenu.center(point);
            } else {
                suppressMenu = true;
            }
        }
    }

    function showMenu() {
        closeMenu();
        if (editMenu) {
            context.surface().call(editMenu);
        }
    }

    function toggleMenu() {
        // deprecation warning - Radial Menu to be removed in iD v3
        if (d3.select('.edit-menu, .radial-menu').empty()) {
            positionMenu();
            showMenu();
        } else {
            closeMenu();
        }
    }

    mode.selectedIDs = function() {
        return selectedIDs;
    };

    mode.reselect = function() {
        if (!checkSelectedIDs()) return;

        var surfaceNode = context.surface().node();
        if (surfaceNode.focus) {   // FF doesn't support it
            surfaceNode.focus();
        }

        positionMenu();
        if (!suppressMenu) {
            showMenu();
        }
    };

    mode.newFeature = function(_) {
        if (!arguments.length) return newFeature;
        newFeature = _;
        return mode;
    };

    mode.suppressMenu = function(_) {
        if (!arguments.length) return suppressMenu;
        suppressMenu = _;
        return mode;
    };

    mode.follow = function(_) {
        if (!arguments.length) return follow;
        follow = _;
        return mode;
    };

    mode.enter = function() {

        function update() {
            closeMenu();
            checkSelectedIDs();
        }

        function dblclick() {
            var target = d3.select(d3.event.target),
                datum = target.datum();

            if (datum instanceof osmWay && !target.classed('fill')) {
                var choice = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection),
                    prev = datum.nodes[choice.index - 1],
                    next = datum.nodes[choice.index];

                context.perform(
                    actionAddMidpoint({loc: choice.loc, edge: [prev, next]}, osmNode()),
                    t('operations.add.annotation.vertex')
                );

                d3.event.preventDefault();
                d3.event.stopPropagation();

            } else if (datum.type === 'midpoint') {
                context.perform(
                    actionAddMidpoint({loc: datum.loc, edge: datum.edge}, osmNode()),
                    t('operations.add.annotation.vertex'));

                d3.event.preventDefault();
                d3.event.stopPropagation();
            }
        }

        function selectElements(drawn) {
            if (!checkSelectedIDs()) return;

            var surface = context.surface(),
                entity = singular();

            if (entity && context.geometry(entity.id) === 'relation') {
                suppressMenu = true;
                return;
            }

            surface.selectAll('.related')
                .classed('related', false);

            singularParent();
            if (relatedParent) {
                surface.selectAll(utilEntitySelector([relatedParent]))
                    .classed('related', true);
            }

            var selection = context.surface()
                .selectAll(utilEntityOrMemberSelector(selectedIDs, context.graph()));

            if (selection.empty()) {
                // Return to browse mode if selected DOM elements have
                // disappeared because the user moved them out of view..
                var source = d3.event && d3.event.type === 'zoom' && d3.event.sourceEvent;
                if (drawn && source && (source.type === 'mousemove' || source.type === 'touchmove')) {
                    context.enter(modeBrowse(context));
                }
            } else {
                selection
                    .classed('selected', true);
            }
        }

        function esc() {
            if (!context.inIntro()) {
                context.enter(modeBrowse(context));
            }
        }

        function firstVertex() {
            d3.event.preventDefault();
            var parent = singularParent();
            if (parent) {
                var way = context.entity(parent);
                context.enter(
                    modeSelect(context, [way.first()]).follow(true)
                );
            }
        }

        function lastVertex() {
            d3.event.preventDefault();
            var parent = singularParent();
            if (parent) {
                var way = context.entity(parent);
                context.enter(
                    modeSelect(context, [way.last()]).follow(true)
                );
            }
        }

        function previousVertex() {
            d3.event.preventDefault();
            var parent = singularParent();
            if (!parent) return;

            var way = context.entity(parent),
                length = way.nodes.length,
                curr = way.nodes.indexOf(selectedIDs[0]),
                index = -1;

            if (curr > 0) {
                index = curr - 1;
            } else if (way.isClosed()) {
                index = length - 2;
            }

            if (index !== -1) {
                context.enter(
                    modeSelect(context, [way.nodes[index]]).follow(true)
                );
            }
        }

        function nextVertex() {
            d3.event.preventDefault();
            var parent = singularParent();
            if (!parent) return;

            var way = context.entity(parent),
                length = way.nodes.length,
                curr = way.nodes.indexOf(selectedIDs[0]),
                index = -1;

            if (curr < length - 1) {
                index = curr + 1;
            } else if (way.isClosed()) {
                index = 0;
            }

            if (index !== -1) {
                context.enter(
                    modeSelect(context, [way.nodes[index]]).follow(true)
                );
            }
        }

        function nextParent() {
            d3.event.preventDefault();
            var parents = _.uniq(commonParents());
            if (!parents || parents.length < 2) return;

            var index = parents.indexOf(relatedParent);
            if (index < 0 || index > parents.length - 2) {
                relatedParent = parents[0];
            } else {
                relatedParent = parents[index + 1];
            }

            var surface = context.surface();
            surface.selectAll('.related')
                .classed('related', false);

            if (relatedParent) {
                surface.selectAll(utilEntitySelector([relatedParent]))
                    .classed('related', true);
            }
        }

        if (!checkSelectedIDs()) return;

        var operations = _.without(d3.values(Operations), Operations.operationDelete)
                .map(function(o) { return o(selectedIDs, context); })
                .filter(function(o) { return o.available(); });

        // deprecation warning - Radial Menu to be removed in iD v3
        var isRadialMenu = context.storage('edit-menu-style') === 'radial';
        if (isRadialMenu) {
            operations = operations.slice(0,7);
            operations.unshift(Operations.operationDelete(selectedIDs, context));
        } else {
            operations.push(Operations.operationDelete(selectedIDs, context));
        }

        operations.forEach(function(operation) {
            if (operation.behavior) {
                behaviors.push(operation.behavior);
            }
        });

        behaviors.forEach(function(behavior) {
            context.install(behavior);
        });

        keybinding
            .on(['[','pgup'], previousVertex)
            .on([']', 'pgdown'], nextVertex)
            .on([uiCmd('⌘['), 'home'], firstVertex)
            .on([uiCmd('⌘]'), 'end'], lastVertex)
            .on(['\\', 'pause'], nextParent)
            .on('⎋', esc, true)
            .on('space', toggleMenu);

        d3.select(document)
            .call(keybinding);

        // deprecation warning - Radial Menu to be removed in iD v3
        editMenu = isRadialMenu
            ? uiRadialMenu(context, operations)
            : uiEditMenu(context, operations);

        context.ui().sidebar
            .select(singular() ? singular().id : null, newFeature);

        context.history()
            .on('undone.select', update)
            .on('redone.select', update);

        context.map()
            .on('move.select', closeMenu)
            .on('drawn.select', selectElements);

        context.surface()
            .on('dblclick.select', dblclick);

        selectElements();

        if (selectedIDs.length > 1) {
            var entities = uiSelectionList(context, selectedIDs);
            context.ui().sidebar.show(entities);
        }

        if (follow) {
            var extent = geoExtent(),
                graph = context.graph();
            selectedIDs.forEach(function(id) {
                var entity = context.entity(id);
                extent._extend(entity.extent(graph));
            });

            var loc = extent.center();
            context.map().centerEase(loc);
        }

        timeout = window.setTimeout(function() {
            positionMenu();
            if (!suppressMenu) {
                showMenu();
            }
        }, 270);  /* after any centerEase completes */

    };

    mode.exit = function() {
        if (timeout) window.clearTimeout(timeout);

        if (inspector) wrap.call(inspector.close);

        behaviors.forEach(function(behavior) {
            context.uninstall(behavior);
        });

        keybinding.off();
        closeMenu();
        editMenu = undefined;

        context.history()
            .on('undone.select', null)
            .on('redone.select', null);

        var surface = context.surface();

        surface
            .on('dblclick.select', null);

        surface
            .selectAll('.selected')
            .classed('selected', false);

        surface
            .selectAll('.related')
            .classed('related', false);

        context.map().on('drawn.select', null);
        context.ui().sidebar.hide();
    };

    return mode;
}
<|endoftext|>


<commit_before>/**

  compiler.js

  Powerful compiler for script transpilation, templating and CSS preprocessing.

  As a note: we differentiate between "extensions" and "types". The extension
  is the actual file extension, whereas the type is the extension a file will
  be after processing.

  • extractMetadata
  - createCompiler (!!! TODO: NEEDS CACHING)
  • aggregateData
  • createRenderer (!!! TODO: UPDATE WITH SOURCE)
  • createQueryFn
  • addPipeline

**/

/**

  Dependencies and exports

**/

var Bundler     = require("./bundler");
var Metadata    = require("./metadata");
var Utils       = require("./utils");

var Pipelines   = global.shipp.pipelines;

module.exports = {
  extractMetadata: extractMetadata,
  createCompiler: createCompiler,
  aggregateData: aggregateData,
  createRenderer: createRenderer,
  createQueryFn: createQueryFn,
  addPipeline: addPipeline
};

/**

  Extracts metadata from a file if appropriate (HTML-like)

  @param {String} id Source identifier
  @param {String} template String template
  @param {String} type type of file (this may be different than the extension)
  @returns {Object} Metadata object

**/

function extractMetadata(id, template, type) {

  var metadata,
      directives;

  if (Utils.isHTML(type)) {
    // Currently leaving out the PARAM directive (until better planned)
    directives = {
      "DATA"    : "query",
      "QUERY"   : "query",
      "COOKIE"  : "object",
      "SESSION" : "object",
      "CACHE"   : "boolean"
    };
    metadata = Metadata.extract(template.slice(0, 500), directives);
  } else {
    // For non-HTML files default to caching
    metadata = { cache: true };
  }

  return metadata;

}

/**

  Creates a compiler for a file. For bundles, this means webpacking. Otherwise,
  uses the Pipelines engine.

  @param {Object} source object containing file or template
  @returns {Function} Function that compiles a file

**/

function createCompiler(source, type) {
  if (source.file && source.file.bundle)
    return Bundler.fromFile(file, type).get;
  else  {
    var fn
    if (source.template)
      fn = Pipelines.compile.bind(Pipelines, source.ext, source.template);
    else if (source.file)
      fn = Pipelines.compileFile.bind(Pipelines, source.file);
    else
      throw new Error("Cannot create compiler due to invalid source");

    return function(data) {
      return new Promise(function(resolve, reject) {
        fn(data, function(err, compiled) {
          if (err) return reject(err);
          resolve(compiled);
        });
      })
    }
  }
}

/**

  Pulls data from cookies, session, params, query, slug and metadata into
  single data object.

  @param {Object} metadata Metadata object as returns by metadata.js
  @param {Object} params Params object as provided by handler.js
  @returns {Object} The data object

**/

function aggregateData(metadata, params) {

  // Data object will include locals, cookies, session, params, query, slug
  // and if applicable, database query results
  var data = Object.assign({}, global.shipp.locals, params.locals);

  // Attach special variables
  data.$assets  = Object.assign({}, global.shipp.assets);
  data.$body    = params.body;
  data.$cookies = params.cookies;
  data.$params  = params.params;
  data.$query   = params.query;
  data.$session = params.session;

  // Special slug
  if (params.slug)
    data.$slug = params.slug

  // Set cookies
  for (var key in metadata.cookies || {})
    data.$cookies[key] = metadata.cookies[key];

  // Set session
  for (key in metadata.session || {})
    data.$session[key] = metadata.session[key];

  return data;

}

// !!! TODO: compiler must be file as well (accept template or file)
// !!! TODO: refactor aggregateData

/**

  Creates a renderer for a blueprint

  @param {String} id Source identifier
  @param {Object} source Object of form { template, file } with either "template" or "file"
  @param {String} type The type of file
  @param {String} pipeline Pipeline to use for compiler
  @return {Function} Handler of form (params = {}, compressionMethod = "identity", maxCompression = false)

  results {
    compression,
    metadata,
    sourceId,
    type,
    contents
  }

**/

function createRenderer(id, source, type, pipeline) {

  // !!! TODO: Handle HTML here, how to map type
  // !!! TODO: add generic source handler
  var metadata = extractMetadata(source, type) || {};
  var compiler = createCompiler(source, pipeline);

  var tasks = [compiler];
  var isHTML = Utils.isHTML(type);

  // Add data query if necessary
  if (metadata.data)
    tasks.unshift(createQueryFn(metadata.data));

  return function(params, compressionMethod, maxCompression) {

    // params should include relevant information normally on a req or res object
    var data = isHTML ? aggregateData(metadata, params) : {};

    // Default compression to identity to maintain compatibility with BrowserSync and other tools
    compressionMethod = compressionMethod || "identity";
    maxCompression = maxCompression || false;

    return Utils.sequence(tasks, data).then(function(rendered) {

      var results = {
        compression: compressionMethod,
        metadata: metadata,
        sourceId: id,
        type: type
      };

      // Uncompressed
      if ("identity" === compressionMethod) {
        results.contents = rendered;
        return results;

      // Compressed
      } else {
        return new Promise(function(resolve, reject) {
          // Note that we are not defaulting to
          Utils.compress(compressionMethod, rendered, maxCompression, function(err, compressed) {
            if (err) return reject(err)
            results.contents = compressed;
            resolve(results);
          });
        })

      }

    })
  }

}

/**

  Creates a function that runs Universql-style data queries.

  @param {Array} queries The queries to be run
  @returns {Function} Function that performs query and returns promise

**/

function createQueryFn(queries) {
  return function(context) {
    if (!queries)
      return Promise.resolve(Object.assign({}, context));
    else
      return Utils.makeQueries(queries, context).then(function(data) {
        return Promise.resolve(Object.assign(data, context));
      });
  };
}

/**

  Add a pipeline if it does not exist.

  @param {String} ext The file extension for the pipeline

**/

function addPipeline(ext) {

  if (Pipelines.hasPipeline(ext)) return;

  try {
    Pipelines.addPipeline(ext);
  } catch (err) {
    global.shipp.logger.warn("");
    global.shipp.logger.warn("WARNING! There is no pipeline available for *." + ext + " files.");
    global.shipp.logger.warn("If this is not fixed, these files will not be served nor compiled.");
    global.shipp.logger.warn("You should add an appropriate pipeline to your shipp.json file.\n");
    return;
  }

}

<commit_msg>Compiler#addPipeline: adds debugging information<commit_after>/**

  compiler.js

  Powerful compiler for script transpilation, templating and CSS preprocessing.

  As a note: we differentiate between "extensions" and "types". The extension
  is the actual file extension, whereas the type is the extension a file will
  be after processing.

  • extractMetadata
  - createCompiler (!!! TODO: NEEDS CACHING)
  • aggregateData
  • createRenderer (!!! TODO: UPDATE WITH SOURCE)
  • createQueryFn
  • addPipeline

**/

/**

  Dependencies and exports

**/

var Bundler     = require("./bundler");
var Metadata    = require("./metadata");
var Utils       = require("./utils");

var Pipelines   = global.shipp.pipelines;

module.exports = {
  extractMetadata: extractMetadata,
  createCompiler: createCompiler,
  aggregateData: aggregateData,
  createRenderer: createRenderer,
  createQueryFn: createQueryFn,
  addPipeline: addPipeline
};

/**

  Extracts metadata from a file if appropriate (HTML-like)

  @param {String} id Source identifier
  @param {String} template String template
  @param {String} type type of file (this may be different than the extension)
  @returns {Object} Metadata object

**/

function extractMetadata(id, template, type) {

  var metadata,
      directives;

  if (Utils.isHTML(type)) {
    // Currently leaving out the PARAM directive (until better planned)
    directives = {
      "DATA"    : "query",
      "QUERY"   : "query",
      "COOKIE"  : "object",
      "SESSION" : "object",
      "CACHE"   : "boolean"
    };
    metadata = Metadata.extract(template.slice(0, 500), directives);
  } else {
    // For non-HTML files default to caching
    metadata = { cache: true };
  }

  return metadata;

}

/**

  Creates a compiler for a file. For bundles, this means webpacking. Otherwise,
  uses the Pipelines engine.

  @param {Object} source object containing file or template
  @returns {Function} Function that compiles a file

**/

function createCompiler(source, type) {
  if (source.file && source.file.bundle)
    return Bundler.fromFile(file, type).get;
  else  {
    var fn
    if (source.template)
      fn = Pipelines.compile.bind(Pipelines, source.ext, source.template);
    else if (source.file)
      fn = Pipelines.compileFile.bind(Pipelines, source.file);
    else
      throw new Error("Cannot create compiler due to invalid source");

    return function(data) {
      return new Promise(function(resolve, reject) {
        fn(data, function(err, compiled) {
          if (err) return reject(err);
          resolve(compiled);
        });
      })
    }
  }
}

/**

  Pulls data from cookies, session, params, query, slug and metadata into
  single data object.

  @param {Object} metadata Metadata object as returns by metadata.js
  @param {Object} params Params object as provided by handler.js
  @returns {Object} The data object

**/

function aggregateData(metadata, params) {

  // Data object will include locals, cookies, session, params, query, slug
  // and if applicable, database query results
  var data = Object.assign({}, global.shipp.locals, params.locals);

  // Attach special variables
  data.$assets  = Object.assign({}, global.shipp.assets);
  data.$body    = params.body;
  data.$cookies = params.cookies;
  data.$params  = params.params;
  data.$query   = params.query;
  data.$session = params.session;

  // Special slug
  if (params.slug)
    data.$slug = params.slug

  // Set cookies
  for (var key in metadata.cookies || {})
    data.$cookies[key] = metadata.cookies[key];

  // Set session
  for (key in metadata.session || {})
    data.$session[key] = metadata.session[key];

  return data;

}

// !!! TODO: compiler must be file as well (accept template or file)
// !!! TODO: refactor aggregateData

/**

  Creates a renderer for a blueprint

  @param {String} id Source identifier
  @param {Object} source Object of form { template, file } with either "template" or "file"
  @param {String} type The type of file
  @param {String} pipeline Pipeline to use for compiler
  @return {Function} Handler of form (params = {}, compressionMethod = "identity", maxCompression = false)

  results {
    compression,
    metadata,
    sourceId,
    type,
    contents
  }

**/

function createRenderer(id, source, type, pipeline) {

  // !!! TODO: Handle HTML here, how to map type
  // !!! TODO: add generic source handler
  var metadata = extractMetadata(source, type) || {};
  var compiler = createCompiler(source, pipeline);

  var tasks = [compiler];
  var isHTML = Utils.isHTML(type);

  // Add data query if necessary
  if (metadata.data)
    tasks.unshift(createQueryFn(metadata.data));

  return function(params, compressionMethod, maxCompression) {

    // params should include relevant information normally on a req or res object
    var data = isHTML ? aggregateData(metadata, params) : {};

    // Default compression to identity to maintain compatibility with BrowserSync and other tools
    compressionMethod = compressionMethod || "identity";
    maxCompression = maxCompression || false;

    return Utils.sequence(tasks, data).then(function(rendered) {

      var results = {
        compression: compressionMethod,
        metadata: metadata,
        sourceId: id,
        type: type
      };

      // Uncompressed
      if ("identity" === compressionMethod) {
        results.contents = rendered;
        return results;

      // Compressed
      } else {
        return new Promise(function(resolve, reject) {
          // Note that we are not defaulting to
          Utils.compress(compressionMethod, rendered, maxCompression, function(err, compressed) {
            if (err) return reject(err)
            results.contents = compressed;
            resolve(results);
          });
        })

      }

    })
  }

}

/**

  Creates a function that runs Universql-style data queries.

  @param {Array} queries The queries to be run
  @returns {Function} Function that performs query and returns promise

**/

function createQueryFn(queries) {
  return function(context) {
    if (!queries)
      return Promise.resolve(Object.assign({}, context));
    else
      return Utils.makeQueries(queries, context).then(function(data) {
        return Promise.resolve(Object.assign(data, context));
      });
  };
}

/**

  Add a pipeline if it does not exist.

  @param {String} ext The file extension for the pipeline

**/

function addPipeline(ext) {

  if (Pipelines.hasPipeline(ext)) return;

  global.shipp.debug("Adding pipeline for ext: " + ext);

  try {
    Pipelines.addPipeline(ext);
  } catch (err) {
    global.shipp.logger.warn("");
    global.shipp.logger.warn("WARNING! There is no pipeline available for *." + ext + " files.");
    global.shipp.logger.warn("If this is not fixed, these files will not be served nor compiled.");
    global.shipp.logger.warn("You should add an appropriate pipeline to your shipp.json file.\n");
    return;
  }

}

<|endoftext|>


<commit_before>$(document).ready(function () {

 // function checknetwork() {
    //alert ('ja');
    //var state = $("#netzwerkanschluss_eth0").val();
    //if ( $('#net_eth').checked ) {
    //  alert ('Eth');
    //  //$('#btnlistnetworks').addClass('ui-disabled');
    //}
    //else {
    //  //$('#btnlistnetworks').removeClass('ui-disabled');
    //  alert ('WLAN');
    // }
  //}

  // Set language
  var lang = $('#lang').html();

  // Show loading animation while ajax events
  $(this).ajaxStart(function() {
    $("#overlay").show();
  });

  $(this).ajaxStop(function() {
    $("#overlay").hide();
  });

  // Submit Language Selection
  $('#btnlang').click( function() {
    $("#overlay").show();
    lang_form.submit();
  });

  // Setup Assistent Step 02: Scan-Button for Miniserver IP
  $('#btnnetscan').click( function(e) {
    $('#testurl').html('Scanning...');
    e.preventDefault();
    $.ajax({
      contentType: "application/x-www-form-urlencoded; charset=iso-8859-15",
      type: "GET",
      url: "/admin/system/tools/netscan.cgi",
      data: "data",
      success: function(data){
        data.replace(/\r|\n/g, "");
        $('#miniserverip1').empty();
        if (data == "") {
          if (lang == "de"){
            var url = 'Keinen Miniserver gefunden';
          } else {
            var url = 'No Miniserver found';
          }
        } else {

        $("#miniserveriprow1").attr( "ipaddr" , data );
        $("#miniserverportrow1").attr( "portaddr" , "80");
        $("#useclouddns1").prop("checked", false);
        $("#useclouddns1").trigger( "change" );
        //$("#miniserverport1").value = "80";

          if (lang == "de"){
            var url = 'Gefundene IP-Adresse testen';
          } else {
            var url = 'Test found IP-Address';
          }
        }
        $('#testurl').html(url);
      }
    });
  });

  // Step 02: Search-Button for Address
  $('#btnaddressscan').click( function(e) {
    e.preventDefault();
    var data = 'query='+$("#address").val()+'&lang='+lang;
    $.ajax({
      contentType: "application/x-www-form-urlencoded; charset=iso-8859-15",
      type: "POST",
      url: "/admin/tools/geolocation.cgi",
      data: data,
      success: function(data){
        $('#addressresults').empty();
        $('#addressresults').html(data);
      }
    });
  });

  // Step 03: Test Mailserver
  $('#btntestsmtp').click( function(e) {
    e.preventDefault();
    var data = 'email='+$("#email").val()+'&smtpserver='+$("#smtpserver").val()+'&smtpauth='+$("#smtpauth").val()+'&smtpcrypt='+$("#smtpcrypt").val()+'&smtpuser='+$("#smtpuser").val()+'&smtppass='+$("#smtppass").val()+'&smtpport='+$("#smtpport").val()+'&lang='+lang;
    $.ajax({
      contentType: "application/x-www-form-urlencoded; charset=iso-8859-15",
      type: "POST",
      url: "/admin/tools/smtptest.cgi",
      data: data,
      success: function(data){
        $('#smtpresults').empty();
        $('#smtpresults').html(data);
      }
    });
  });

  return false;

});

<commit_msg>Error if no Miniserver was found<commit_after>$(document).ready(function () {

 // function checknetwork() {
    //alert ('ja');
    //var state = $("#netzwerkanschluss_eth0").val();
    //if ( $('#net_eth').checked ) {
    //  alert ('Eth');
    //  //$('#btnlistnetworks').addClass('ui-disabled');
    //}
    //else {
    //  //$('#btnlistnetworks').removeClass('ui-disabled');
    //  alert ('WLAN');
    // }
  //}

  // Set language
  var lang = $('#lang').html();

  // Show loading animation while ajax events
  $(this).ajaxStart(function() {
    $("#overlay").show();
  });

  $(this).ajaxStop(function() {
    $("#overlay").hide();
  });

  // Submit Language Selection
  $('#btnlang').click( function() {
    $("#overlay").show();
    lang_form.submit();
  });

  // Setup Assistent Step 02: Scan-Button for Miniserver IP
  $('#btnnetscan').click( function(e) {
    $('#testurl').html('Scanning...');
    e.preventDefault();
    $.ajax({
      contentType: "application/x-www-form-urlencoded; charset=iso-8859-15",
      type: "GET",
      url: "/admin/system/tools/netscan.cgi",
      data: "data",
      success: function(data){
        data.replace(/\r|\n/g, "");
        $('#miniserverip1').empty();
        if (data.length < 3) {
          if (lang == "de"){
            var url = 'Keinen Miniserver gefunden';
          } else {
            var url = 'No Miniserver found';
          }
        } else {

        $("#miniserveriprow1").attr( "ipaddr" , data );
        $("#miniserverportrow1").attr( "portaddr" , "80");
        $("#useclouddns1").prop("checked", false);
        $("#useclouddns1").trigger( "change" );
        //$("#miniserverport1").value = "80";

          if (lang == "de"){
            var url = 'Gefundene IP-Adresse testen';
          } else {
            var url = 'Test found IP-Address';
          }
        }
        $('#testurl').html(url);
      }
    });
  });

  // Step 02: Search-Button for Address
  $('#btnaddressscan').click( function(e) {
    e.preventDefault();
    var data = 'query='+$("#address").val()+'&lang='+lang;
    $.ajax({
      contentType: "application/x-www-form-urlencoded; charset=iso-8859-15",
      type: "POST",
      url: "/admin/tools/geolocation.cgi",
      data: data,
      success: function(data){
        $('#addressresults').empty();
        $('#addressresults').html(data);
      }
    });
  });

  // Step 03: Test Mailserver
  $('#btntestsmtp').click( function(e) {
    e.preventDefault();
    var data = 'email='+$("#email").val()+'&smtpserver='+$("#smtpserver").val()+'&smtpauth='+$("#smtpauth").val()+'&smtpcrypt='+$("#smtpcrypt").val()+'&smtpuser='+$("#smtpuser").val()+'&smtppass='+$("#smtppass").val()+'&smtpport='+$("#smtpport").val()+'&lang='+lang;
    $.ajax({
      contentType: "application/x-www-form-urlencoded; charset=iso-8859-15",
      type: "POST",
      url: "/admin/tools/smtptest.cgi",
      data: data,
      success: function(data){
        $('#smtpresults').empty();
        $('#smtpresults').html(data);
      }
    });
  });

  return false;

});

<|endoftext|>


<commit_before>'use strict';

var tsc = require('./tsc');
var fs = require('fs');
var path = require('path');
var util = require('util');
var async = require('async');
var xtend = require('xtend');
var byline = require('byline');
var EventEmitter = require('events').EventEmitter;

module.exports = Compiler;

function Compiler(options) {
  EventEmitter.call(this);
  this.options = xtend({
    tscPath:           null,
    tscSearch:         null,
    module:            'commonjs',
    target:            'ES3',
    out:               null,
    mapRoot:           null,
    allowbool:         false,
    allowimportmodule: false,
    declaration:       false,
    noImplicitAny:     false,
    noResolve:         false,
    removeComments:    false,
    sourcemap:         false
  }, options);

  this.tscOptions = {
    path:   this.options.tscPath,
    search: this.options.tscSearch
  };

  this.sourceFiles = [];
  this.outputFiles = [];
}
util.inherits(Compiler, EventEmitter);

Compiler.prototype.buildTscArguments = function () {
  var args = [];
  if (this.options.module)            args.push('--module',  this.options.module.toLowerCase());
  if (this.options.target)            args.push('--target',  this.options.target.toUpperCase());
  if (this.options.out)               args.push('--out',     this.options.out);
  if (this.options.mapRoot)           args.push('--mapRoot', this.options.mapRoot);
  if (this.options.allowbool)         args.push('--allowbool');
  if (this.options.allowimportmodule) args.push('--allowimportmodule');
  if (this.options.declaration)       args.push('--declaration');
  if (this.options.noImplicitAny)     args.push('--noImplicitAny');
  if (this.options.noResolve)         args.push('--noResolve');
  if (this.options.removeComments)    args.push('--removeComments');
  if (this.options.sourcemap)         args.push('--sourcemap');
  this.sourceFiles.forEach(function (f) { args.push(f.path); });
  return args;
};

Compiler.prototype.clear = function () {
  this.sourceFiles = [];
  this.outputFiles = [];
};

Compiler.prototype.getVersion = function (callback) {
  return tsc.version(this.tscOptions, callback);
};

Compiler.prototype.addSourceFile = function (file, encoding) {
  this.sourceFiles.push(file);

  if (this.options.out) {
    if (this.outputFiles.length === 0) {
      var outFile = file.clone();
      outFile.base = file.cwd;
      outFile.path = path.resolve(file.cwd, this.options.out);
      this.addOutputFile(outFile, encoding);
    }
  } else {
    var outFile = file.clone();
    outFile.path = outFile.path.replace(/(\.[^.]+)?$/, '.js');
    this.addOutputFile(outFile, encoding);
  }
};

Compiler.prototype.addOutputFile = function (file, encoding) {
  var paths = [file.path];
  if (this.options.declaration) {
    paths.push(file.path.replace(/(\.js)?$/, '.d.ts'));
  }
  if (this.options.sourcemap) {
    paths.push(file.path + '.map');
  }

  var _this = this;
  paths.forEach(function (p) {
    var newFile = file.clone();
    newFile.path = p;
    newFile.contents = null;
    newFile._encoding = encoding;
    _this.outputFiles.push(newFile);
  });
};

Compiler.prototype.compile = function (callback) {
  var _this = this;
  this.emit('start');
  async.waterfall([
    this.markNonexistFiles.bind(this),
    this.runTsc.bind(this)
  ], function (err) {
    _this.processOutputFiles(function (err2) {
      _this.emit('end');
      callback(err || err2);
    });
  });
};

Compiler.prototype.markNonexistFiles = function (callback) {
  async.each(this.outputFiles, function (file, next) {
    fs.exists(file.path, function (exists) {
      file._toRemove = !exists;
      next();
    });
  }, callback);
};

Compiler.prototype.runTsc = function (callback) {
  var _this = this;
  var proc = tsc.exec(this.buildTscArguments(), this.tscOptions);
  var stdout = byline(proc.stdout);
  var stderr = byline(proc.stderr);

  proc.on('exit', function (code) {
    if (code !== 0) {
      callback(new Error('tsc command has exited with code:' + code));
    } else {
      callback(null);
    }
  })
  proc.on('error', function (err) {
    _this.emit('error', err);
  });
  stdout.on('data', function (chunk) {
    _this.emit('stdout', chunk);
  });
  stderr.on('data', function (chunk) {
    _this.emit('stderr', chunk);
  });

  return proc;
};

Compiler.prototype.processOutputFiles = function (callback) {
  var _this = this;
  var newOutputFiles = [];
  async.each(this.outputFiles, function (file, next) {
    var options = file._encoding ? { encoding: file._encoding } : {};
    fs.readFile(file.path, options, function (err, contents) {
      if (err) return next(err);
      file.contents = new Buffer(contents, file._encoding);
      newOutputFiles.push(file);

      if (file._toRemove) {
        fs.unlink(file.path, next);
      } else {
        next();
      }
    });
  }, function (err) {
    _this.outputFiles = newOutputFiles;
    callback(err);
  });
};
<commit_msg>Fix #1: Fails on compiling .d.ts files<commit_after>'use strict';

var tsc = require('./tsc');
var fs = require('fs');
var path = require('path');
var util = require('util');
var async = require('async');
var xtend = require('xtend');
var byline = require('byline');
var EventEmitter = require('events').EventEmitter;

module.exports = Compiler;

function Compiler(options) {
  EventEmitter.call(this);
  this.options = xtend({
    tscPath:           null,
    tscSearch:         null,
    module:            'commonjs',
    target:            'ES3',
    out:               null,
    mapRoot:           null,
    allowbool:         false,
    allowimportmodule: false,
    declaration:       false,
    noImplicitAny:     false,
    noResolve:         false,
    removeComments:    false,
    sourcemap:         false
  }, options);

  this.tscOptions = {
    path:   this.options.tscPath,
    search: this.options.tscSearch
  };

  this.sourceFiles = [];
  this.outputFiles = [];
}
util.inherits(Compiler, EventEmitter);

Compiler.prototype.buildTscArguments = function () {
  var args = [];
  if (this.options.module)            args.push('--module',  this.options.module.toLowerCase());
  if (this.options.target)            args.push('--target',  this.options.target.toUpperCase());
  if (this.options.out)               args.push('--out',     this.options.out);
  if (this.options.mapRoot)           args.push('--mapRoot', this.options.mapRoot);
  if (this.options.allowbool)         args.push('--allowbool');
  if (this.options.allowimportmodule) args.push('--allowimportmodule');
  if (this.options.declaration)       args.push('--declaration');
  if (this.options.noImplicitAny)     args.push('--noImplicitAny');
  if (this.options.noResolve)         args.push('--noResolve');
  if (this.options.removeComments)    args.push('--removeComments');
  if (this.options.sourcemap)         args.push('--sourcemap');
  this.sourceFiles.forEach(function (f) { args.push(f.path); });
  return args;
};

Compiler.prototype.clear = function () {
  this.sourceFiles = [];
  this.outputFiles = [];
};

Compiler.prototype.getVersion = function (callback) {
  return tsc.version(this.tscOptions, callback);
};

Compiler.prototype.addSourceFile = function (file, encoding) {
  this.sourceFiles.push(file);

  if (file.path.match(/\.d\.ts$/)) {
    return;
  }

  if (this.options.out) {
    if (this.outputFiles.length === 0) {
      var outFile = file.clone();
      outFile.base = file.cwd;
      outFile.path = path.resolve(file.cwd, this.options.out);
      this.addOutputFile(outFile, encoding);
    }
  } else {
    var outFile = file.clone();
    outFile.path = outFile.path.replace(/(\.[^.]+)?$/, '.js');
    this.addOutputFile(outFile, encoding);
  }
};

Compiler.prototype.addOutputFile = function (file, encoding) {
  var paths = [file.path];
  if (this.options.declaration) {
    paths.push(file.path.replace(/(\.js)?$/, '.d.ts'));
  }
  if (this.options.sourcemap) {
    paths.push(file.path + '.map');
  }

  var _this = this;
  paths.forEach(function (p) {
    var newFile = file.clone();
    newFile.path = p;
    newFile.contents = null;
    newFile._encoding = encoding;
    _this.outputFiles.push(newFile);
  });
};

Compiler.prototype.compile = function (callback) {
  var _this = this;
  this.emit('start');
  async.waterfall([
    this.markNonexistFiles.bind(this),
    this.runTsc.bind(this)
  ], function (err) {
    _this.processOutputFiles(function (err2) {
      _this.emit('end');
      callback(err || err2);
    });
  });
};

Compiler.prototype.markNonexistFiles = function (callback) {
  async.each(this.outputFiles, function (file, next) {
    fs.exists(file.path, function (exists) {
      file._toRemove = !exists;
      next();
    });
  }, callback);
};

Compiler.prototype.runTsc = function (callback) {
  var _this = this;
  var proc = tsc.exec(this.buildTscArguments(), this.tscOptions);
  var stdout = byline(proc.stdout);
  var stderr = byline(proc.stderr);

  proc.on('exit', function (code) {
    if (code !== 0) {
      callback(new Error('tsc command has exited with code:' + code));
    } else {
      callback(null);
    }
  })
  proc.on('error', function (err) {
    _this.emit('error', err);
  });
  stdout.on('data', function (chunk) {
    _this.emit('stdout', chunk);
  });
  stderr.on('data', function (chunk) {
    _this.emit('stderr', chunk);
  });

  return proc;
};

Compiler.prototype.processOutputFiles = function (callback) {
  var _this = this;
  var newOutputFiles = [];
  async.each(this.outputFiles, function (file, next) {
    var options = file._encoding ? { encoding: file._encoding } : {};
    fs.readFile(file.path, options, function (err, contents) {
      if (err) return next(err);
      file.contents = new Buffer(contents, file._encoding);
      newOutputFiles.push(file);

      if (file._toRemove) {
        fs.unlink(file.path, next);
      } else {
        next();
      }
    });
  }, function (err) {
    _this.outputFiles = newOutputFiles;
    callback(err);
  });
};
<|endoftext|>


<commit_before>var log = require('../../utils/logger').logger,
    shaValidator = require('../../utils/sha-validator');

function issueCommentHandler(payload, config, repoClient, validators, callback) {
    var prNumber = payload.issue.number;

    // Ignore comments on issues, we only want to take action on pull requests.
    if (! payload.issue.pull_request) {
        return callback();
    }

    repoClient.getLastCommitOnPullRequest(prNumber, function(err, commit) {
        var login;
        if (commit.committer) {
            login = commit.committer.login;
        } else if (commit.author) {
            login = commit.author.login;
        }
        if (! login) {
            log.warn('Cannot fine login for last PR commit!');
            log.warn(JSON.stringify(commit, null, 2));
            return;
        }
        shaValidator.performCompleteValidation(
            commit.sha
          , login
          , repoClient
          , validators
          , true
          , callback
        );
    });
}

module.exports = issueCommentHandler;
<commit_msg>Fixing more github api calls<commit_after>var log = require('../../utils/logger').logger,
    shaValidator = require('../../utils/sha-validator');

function issueCommentHandler(payload, config, repoClient, validators, callback) {
    var prNumber = payload.issue.number;

    // Ignore comments on issues, we only want to take action on pull requests.
    if (! payload.issue.pull_request) {
        return callback();
    }

    repoClient.getLastCommitOnPullRequest(prNumber, function(err, payload) {
        var commit = payload.data;
        var login;
        if (commit.committer) {
            login = commit.committer.name;
        } else if (commit.author) {
            login = commit.author.name;
        }
        if (! login) {
            log.warn('Cannot fine login for last PR commit!');
            log.warn(JSON.stringify(commit, null, 2));
            return;
        }
        shaValidator.performCompleteValidation(
            commit.sha
          , login
          , repoClient
          , validators
          , true
          , callback
        );
    });
}

module.exports = issueCommentHandler;
<|endoftext|>


<commit_before>/**
 * @fileoverview A Worker API based on the [W3C Web Workers](http://www.w3.org/TR/workers/).
 * Ringo offers "shared-nothing" workers for parallel execution and abstract JVM threads.
 * A worker has its own private set of modules and an isolated scope, tied together in a single JVM thread.
 * Each worker gets its own single-threaded event loop that behaves just like the event loop in a browser or in Node.
 * Communication between workers uses the postMessage() method and the onmessage event handler.
 * To improve performance Ringo keeps free workers in a queue and only allocates a new one if all existing workers are busy.
 * Workers help to keep multi-threaded JavaScript free from any common threading pitfalls, like synchronization or locking.
 *
 * @see RingoJS: Workers and Multithreading
 */
var engine = require("ringo/engine");
var Deferred = require("ringo/promise").Deferred;

exports.Worker = Worker;
exports.WorkerPromise = WorkerPromise;

/**
 * A Worker thread loosely modeled after the
 * [W3C Web Worker API](http://www.w3.org/TR/workers/).
 *
 * The `moduleId` argument must be the fully resolved id of the module
 * to load in the worker. In order to be able to send messages to the worker
 * using the [postMessage](#Worker.prototype.postMessage) method the module must
 * define (though not necessarily export) a `onmessage` function.
 *
 * Workers operate on their own set of modules, so a new instance of the
 * module will be created even if the module is already loaded in the current
 * thread or is the same as the currently executing module. Thus,
 * each worker operates in its private module environment, making concurrent
 * programming much more predictable than with shared state multithreading.
 *
 * Event listeners for callbacks from the worker can be registered by
 * assigning them to the `onmessage` and `onerror` properties of the worker.
 *
 * To free the worker's thread and other resources once the worker is no longer
 * needed its [terminate](#Worker.prototype.terminate) method should be called.
 *
 * @param {String} moduleId the id of the module to load in the worker.
 * @constructor
 * @see RingoJS: Workers and Multithreading
 */
function Worker(moduleId) {
    if (!(this instanceof Worker)) {
        return new Worker(moduleId);
    }

    var self = this;
    var worker = engine.getWorker();

    // Load module immediately and wait till done. This will
    // throw an error if module can't be loaded.
    worker.loadModuleInWorkerThread(moduleId).get();

    function onmessage(e) {
        if (typeof self.onmessage === "function") {
            self.onmessage(e);
        }
    }

    function onerror(e) {
        if (typeof self.onerror === "function") {
            self.onerror(e);
        }
    }

    worker.setErrorListener(function(t) {
        onerror({data: t});
    });

    /**
     * Post a message to the worker. This enqueues the message
     * in the worker's input queue and returns immediately. The worker thread
     * will then pick up the message and pass it to its `onmessage` function.
     *
     * The argument passed to `onmessage` is an object with a `data`
     * property containing the message and a `source` property containing an
     * object with `postMessage` and `postError` methods allowing  the worker
     * to post messages or report errors back to the original caller.
     *
     * If `syncCallbacks` is `true`, callbacks from the worker will run on the
     * worker's own thread instead of our local event loop thread. This
     * allows callbacks to be delivered concurrently while the local thread is
     * busy doing something else.
     *
     * Note that in contrast to the
     * [Web Workers specification](http://www.w3.org/TR/workers/) this worker
     * implementation does not require JSON serialization of messages.
     *
     * @param {Object} data the data to pass to the worker
     * @param {Boolean} [syncCallbacks] flag that indicates whether
     * callbacks from the worker should be called synchronously in the worker's
     * own thread rather than in our own local event loop thread.
     */
    this.postMessage = function(data, syncCallbacks) {
        if (!worker) {
            throw new Error("Worker has been terminated");
        }
        var invokeCallback = function(callback, arg) {
            if (syncCallbacks) callback(arg);
            else currentWorker.submit(self, callback, arg);
        };
        var source = {
            postMessage: function(data) {
                invokeCallback(onmessage, {data: data, source: self});
            },
            postError: function(error) {
                invokeCallback(onerror, {data: error, source: self})
            }
        };
        var currentWorker = engine.getCurrentWorker();
        var event = {data: data, source: source};
        worker.submit(self, function() {
            try {
                worker.invoke(moduleId, "onmessage", event);
            } catch (error) {
                invokeCallback(onerror, {data: error, source: self});
            }
        });
    };

    /**
     * Release the worker, returning it to the engine's worker pool.
     * Note that this does not terminate the worker thread, or remove any
     * current or future scheduled tasks from its event loop.
     */
    this.terminate = function() {
        if (worker) {
            worker.release();
            worker = null;
        }
    };

}

/**
 * A [Promise](../ringo/promise) backed by a [Worker](#Worker).
 *
 * This creates a new Worker with the given `moduleId` and calls its `postMessage`
 * function with the `message` argument. The first message or error received
 * back from the worker will be used to resolve the promise.
 *
 * The worker is terminated immediately after it resolves the promise.
 *
 * @param {String} moduleId the id of the module to load in the worker.
 * @param {Object} message the message to post to the worker.
 * @param {Boolean} [syncCallbacks] flag that indicates whether
 * callbacks from the worker should be called synchronously in the worker's
 * own thread rather than in our own local event loop thread.
 * @constructor
 * @see ringo/promise#Promise
 */
function WorkerPromise(moduleId, message, syncCallbacks) {
    var deferred = new Deferred();
    var worker = new Worker(moduleId);
    var resolved = false;

    worker.onmessage = function(e) {
        resolve(e.data, false);
    };

    worker.onerror = function(e) {
        resolve(e.data, true);
    };

    function resolve(message, isError) {
        if (!resolved) {
            resolved = true;
            deferred.resolve(message, isError);
            worker.terminate();
        }
    }

    worker.postMessage(message, syncCallbacks);
    return deferred.promise;

    /**
     * Registers callback and errback functions that will be invoked when
     * the promise is resolved by the worker. See documentation for
     * [Promise.then()](../ringo/promise#Promise.prototype.then).
     * @name WorkerPromise.prototype.then
     * @param {Function} callback called if the promise is resolved as fulfilled
     * @param {Function} errback called if the promise is resolved as failed
     * @return {Object} a new promise that resolves to the return value of the
     *     callback or errback when it is called.
     */

    /**
     * Wait for the worker to resolve the promise. See documentation for
     * [Promise.wait()](../ringo/promise#Promise.prototype.wait).
     * @name WorkerPromise.prototype.wait
     * @param {Number} timeout optional time in milliseconds to wait for.
     *                 If timeout is undefined wait() blocks forever.
     * @return {Object} the value if the promise is resolved as fulfilled
     * @throws Object the error value if the promise is resolved as failed
     */
}<commit_msg>Better worker.toString()<commit_after>/**
 * @fileoverview A Worker API based on the [W3C Web Workers](http://www.w3.org/TR/workers/).
 * Ringo offers "shared-nothing" workers for parallel execution and abstract JVM threads.
 * A worker has its own private set of modules and an isolated scope, tied together in a single JVM thread.
 * Each worker gets its own single-threaded event loop that behaves just like the event loop in a browser or in Node.
 * Communication between workers uses the postMessage() method and the onmessage event handler.
 * To improve performance Ringo keeps free workers in a queue and only allocates a new one if all existing workers are busy.
 * Workers help to keep multi-threaded JavaScript free from any common threading pitfalls, like synchronization or locking.
 *
 * @see RingoJS: Workers and Multithreading
 */
var engine = require("ringo/engine");
var Deferred = require("ringo/promise").Deferred;

exports.Worker = Worker;
exports.WorkerPromise = WorkerPromise;

/**
 * A Worker thread loosely modeled after the
 * [W3C Web Worker API](http://www.w3.org/TR/workers/).
 *
 * The `moduleId` argument must be the fully resolved id of the module
 * to load in the worker. In order to be able to send messages to the worker
 * using the [postMessage](#Worker.prototype.postMessage) method the module must
 * define (though not necessarily export) a `onmessage` function.
 *
 * Workers operate on their own set of modules, so a new instance of the
 * module will be created even if the module is already loaded in the current
 * thread or is the same as the currently executing module. Thus,
 * each worker operates in its private module environment, making concurrent
 * programming much more predictable than with shared state multithreading.
 *
 * Event listeners for callbacks from the worker can be registered by
 * assigning them to the `onmessage` and `onerror` properties of the worker.
 *
 * To free the worker's thread and other resources once the worker is no longer
 * needed its [terminate](#Worker.prototype.terminate) method should be called.
 *
 * @param {String} moduleId the id of the module to load in the worker.
 * @constructor
 * @see RingoJS: Workers and Multithreading
 */
function Worker(moduleId) {
    if (!(this instanceof Worker)) {
        return new Worker(moduleId);
    }

    var self = this;
    var worker = engine.getWorker();

    // Load module immediately and wait till done. This will
    // throw an error if module can't be loaded.
    worker.loadModuleInWorkerThread(moduleId).get();

    function onmessage(e) {
        if (typeof self.onmessage === "function") {
            self.onmessage(e);
        }
    }

    function onerror(e) {
        if (typeof self.onerror === "function") {
            self.onerror(e);
        }
    }

    worker.setErrorListener(function(t) {
        onerror({data: t});
    });

    /**
     * Post a message to the worker. This enqueues the message
     * in the worker's input queue and returns immediately. The worker thread
     * will then pick up the message and pass it to its `onmessage` function.
     *
     * The argument passed to `onmessage` is an object with a `data`
     * property containing the message and a `source` property containing an
     * object with `postMessage` and `postError` methods allowing  the worker
     * to post messages or report errors back to the original caller.
     *
     * If `syncCallbacks` is `true`, callbacks from the worker will run on the
     * worker's own thread instead of our local event loop thread. This
     * allows callbacks to be delivered concurrently while the local thread is
     * busy doing something else.
     *
     * Note that in contrast to the
     * [Web Workers specification](http://www.w3.org/TR/workers/) this worker
     * implementation does not require JSON serialization of messages.
     *
     * @param {Object} data the data to pass to the worker
     * @param {Boolean} [syncCallbacks] flag that indicates whether
     * callbacks from the worker should be called synchronously in the worker's
     * own thread rather than in our own local event loop thread.
     */
    this.postMessage = function(data, syncCallbacks) {
        if (!worker) {
            throw new Error("Worker has been terminated");
        }
        var invokeCallback = function(callback, arg) {
            if (syncCallbacks) callback(arg);
            else currentWorker.submit(self, callback, arg);
        };
        var source = {
            postMessage: function(data) {
                invokeCallback(onmessage, {data: data, source: self});
            },
            postError: function(error) {
                invokeCallback(onerror, {data: error, source: self})
            }
        };
        var currentWorker = engine.getCurrentWorker();
        var event = {data: data, source: source};
        worker.submit(self, function() {
            try {
                worker.invoke(moduleId, "onmessage", event);
            } catch (error) {
                invokeCallback(onerror, {data: error, source: self});
            }
        });
    };

    /**
     * Release the worker, returning it to the engine's worker pool.
     * Note that this does not terminate the worker thread, or remove any
     * current or future scheduled tasks from its event loop.
     */
    this.terminate = function() {
        if (worker) {
            worker.release();
            worker = null;
        }
    };

    /**
     * @ignore
     */
    this.toString = function () {
        if (worker) {
            return "[Worker " + worker.toString() + "]";
        }
        return "[Worker empty]";
    }
}

/**
 * A [Promise](../ringo/promise) backed by a [Worker](#Worker).
 *
 * This creates a new Worker with the given `moduleId` and calls its `postMessage`
 * function with the `message` argument. The first message or error received
 * back from the worker will be used to resolve the promise.
 *
 * The worker is terminated immediately after it resolves the promise.
 *
 * @param {String} moduleId the id of the module to load in the worker.
 * @param {Object} message the message to post to the worker.
 * @param {Boolean} [syncCallbacks] flag that indicates whether
 * callbacks from the worker should be called synchronously in the worker's
 * own thread rather than in our own local event loop thread.
 * @constructor
 * @see ringo/promise#Promise
 */
function WorkerPromise(moduleId, message, syncCallbacks) {
    var deferred = new Deferred();
    var worker = new Worker(moduleId);
    var resolved = false;

    worker.onmessage = function(e) {
        resolve(e.data, false);
    };

    worker.onerror = function(e) {
        resolve(e.data, true);
    };

    function resolve(message, isError) {
        if (!resolved) {
            resolved = true;
            deferred.resolve(message, isError);
            worker.terminate();
        }
    }

    worker.postMessage(message, syncCallbacks);
    return deferred.promise;

    /**
     * Registers callback and errback functions that will be invoked when
     * the promise is resolved by the worker. See documentation for
     * [Promise.then()](../ringo/promise#Promise.prototype.then).
     * @name WorkerPromise.prototype.then
     * @param {Function} callback called if the promise is resolved as fulfilled
     * @param {Function} errback called if the promise is resolved as failed
     * @return {Object} a new promise that resolves to the return value of the
     *     callback or errback when it is called.
     */

    /**
     * Wait for the worker to resolve the promise. See documentation for
     * [Promise.wait()](../ringo/promise#Promise.prototype.wait).
     * @name WorkerPromise.prototype.wait
     * @param {Number} timeout optional time in milliseconds to wait for.
     *                 If timeout is undefined wait() blocks forever.
     * @return {Object} the value if the promise is resolved as fulfilled
     * @throws Object the error value if the promise is resolved as failed
     */
}<|endoftext|>


<commit_before>const fs = require('fs-extra')
const path = require('path')

module.exports = function nuxtAxios(options) {
  if (!this.options.vendor) {
    return
  }

  const vendorDir = path.resolve(this.options.rootDir, 'static', 'vendor')
  const nodeModulesDir = path.resolve(this.options.rootDir, 'node_modules')

  // Ensure static/vendor directory exists
  fs.ensureDirSync(vendorDir)

  // Link vendors
  this.options.vendor.forEach(vendor => {
    const src = path.resolve(nodeModulesDir, vendor)
    const dst = path.resolve(vendorDir, vendor)

    /* eslint-disable no-console */
    console.log('[vendor]', src, '->', dst)
    fs.ensureSymlinkSync(src, dst, 'junction')
  })
}

module.exports.meta = require('./package.json')
<commit_msg>vendor: update for nuxt 1.x<commit_after>const fs = require('fs-extra')
const path = require('path')

module.exports = function nuxtVendor (moduleOptions) {
  if (Array.isArray(moduleOptions)) {
    moduleOptions = {
      vendor: moduleOptions
    }
  }

  const vendorDir = path.resolve(this.options.srcDir, 'static', 'vendor')

  const vendor = [].concat(this.options.vendor, moduleOptions.vendor)
    .filter(v => v)
    .map(v => ({
      src: v.src || path.resolve(this.options.modulesDir, v),
      dst: v.dst || path.resolve(vendorDir, v)
    }))
    .filter(v => fs.existsSync(v.src))

  if (!vendor.length) {
    return
  }

  // Ensure static/vendor directory exists
  fs.ensureDirSync(vendorDir)

  // Link vendors
  vendor.forEach(({src, dst}) => {
    fs.removeSync(dst)
    fs.ensureSymlinkSync(src, dst, 'junction')
  })
}

module.exports.meta = require('./package.json')
<|endoftext|>