<commit_before>const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const Config = require("./config");
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
const fs = require("fs-extra");
const KabaScss = require("kaba-scss");
const path = require("path");
const program = require("commander");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const webpack = require("webpack");

/**
 * Main Kaba class
 */
class Kaba
{
    /**
     *
     */
    constructor ()
    {
        /**
         * @private
         * @type {string}
         */
        this.cwd = process.cwd();

        /**
         * @private
         * @†ype {string}
         */
        this.libRoot = path.dirname(__dirname);

        /**
         * @private
         * @type {Config}
         */
        this.config = new Config(program);

        /**
         * @private
         * @type {Object<string,string>}
         */
        this.entries = {};

        /**
         * @private
         * @type {Object<string,string>}
         */
        this.sassEntries = {};

        /**
         * @private
         * @type {string}
         */
        this.outputPath = "";

        /**
         * @private
         * @type {string}
         */
        this.publicPath = "";

        /**
         * @private
         * @type {Object<string,string>}
         */
        this.externals = {};

        /**
         * @private
         * @type {string[]}
         */
        this.browserList = [];

        /**
         * @private
         * @type {boolean}
         * @deprecated
         */
        this.moduleConcatenationEnabled = true;

        /**
         * @private
         * @type {string[]}
         */
        this.removeOutputSubDirectories = [];

        /**
         * @private
         * @type {string[]}
         */
        this.sassIncludePaths = [];

        /**
         * @private
         * @type {?{names: string[], minChunks: number}}
         */
        this.sharedEntryConfig = null;

        /**
         * The webpack plugins
         *
         * @private
         * @type {Array}
         */
        this.plugins = [
            new webpack.DefinePlugin({
                "process.env.NODE_ENV": this.config.isDebug() ? '"development"' : '"production"',
            }),
            new FriendlyErrorsWebpackPlugin({
                clearConsole: this.config.isWatch(),
            }),
        ];

        // set defaults
        this
            .setOutputPath("build")
            .setPublicPath("/assets/")
            .cleanOutputDir(["js"])
            .setBrowserList(["last 2 versions", "IE 11"])
        ;
    }

    /**
     * Adds an entry
     *
     * @param {Object<string,string>} mapping
     * @return {Kaba}
     */
    addEntries (mapping)
    {
        for (const name in mapping)
        {
            if (!mapping.hasOwnProperty(name))
            {
                continue;
            }

            const source = mapping[name];

            // special handling for SCSS files
            if (/\.scss$/.test(source))
            {
                if (this.sassEntries[name] !== undefined)
                {
                    throw new Error(`Can't add scss entry named ${name}: an entry with this name already exists.`);
                }

                this.sassEntries[name] = source;
            }
            else
            {
                if (this.entries[name] !== undefined)
                {
                    throw new Error(`Can't add js entry named ${name}: an entry with this name already exists.`);
                }

                if (null !== this.sharedEntryConfig && -1 !== this.sharedEntryConfig.names.indexOf(name))
                {
                    throw new Error(`Can't add entry named ${name}: it is named like the extracted shared entries.`);
                }

                this.entries[name] = source;
            }
        }

        return this;
    }

    /**
     * Sets the output path
     *
     * @param {string} outputPath
     * @return {Kaba}
     */
    setOutputPath (outputPath)
    {
        this.outputPath = path.join(this.cwd, outputPath);
        return this;
    }

    /**
     * Sets the relative public path (for automatic imports)
     *
     * @param {string} publicPath relative to the cwd
     * @return {Kaba}
     */
    setPublicPath (publicPath)
    {
        this.publicPath = publicPath;
        return this;
    }

    /**
     *
     * @param {Object<string,string>} externals
     * @return {Kaba}
     */
    setExternals (externals)
    {
        this.externals = externals;
        return this;
    }

    /**
     * Sets the browser list
     *
     * @param {string[]} list
     * @return {Kaba}
     */
    setBrowserList (list)
    {
        this.browserList = list;
        return this;
    }

    /**
     * Disabled module concatenation
     *
     * @deprecated will be removed, as soon as webpack is updated to v4
     * @return {Kaba}
     */
    disableModuleConcatenation ()
    {
        this.moduleConcatenationEnabled = false;
        return this;
    }

    /**
     * Creates a shared vendor entry name
     *
     * @param {string[]} vendorFiles
     * @param {string} vendorName
     * @param {string|null} runtimeName
     * @return {Kaba}
     */
    extractSharedEntry (vendorFiles = [], vendorName = "vendor", runtimeName = "runtime")
    {
        if (null === vendorName)
        {
            throw new Error("extractSharedLibraries() failed: vendorName can not be null.");
        }

        if (this.sharedEntryConfig !== null)
        {
            throw new Error("extractSharedLibraries() can only be called once: only one vendor entry can be created.");
        }

        if (this.entries[vendorName] !== undefined)
        {
            throw new Error("Cannot extract shared entry: there already is a regular entry with the same name as the vendor name.");
        }

        if (runtimeName !== null && this.entries[runtimeName] !== undefined)
        {
            throw new Error("Cannot extract shared entry: there already is a regular entry with the same name as the runtime name.");
        }

        const names = [vendorName];

        if (null !== runtimeName)
        {
            names.push(runtimeName);
        }

        // first add entry, as it checks the name for conflicts with the shared entry config name
        if (vendorFiles.length > 0)
        {
            this.addEntries({
                [vendorName]: vendorFiles,
            });
        }

        this.sharedEntryConfig = {
            names: names,
            minChunks: 3,
        };

        this.plugins.push(
            new webpack.optimize.CommonsChunkPlugin(this.sharedEntryConfig),
        );

        return this;
    }

    /**
     * Enables cleaning the output dir before the build
     *
     * @param {string[]} subDirectories
     * @return {Kaba}
     */
    cleanOutputDir (subDirectories)
    {
        this.removeOutputSubDirectories = subDirectories;
        return this;
    }

    /**
     * Adds `node_modules` to the include dir of sass.
     *
     * @return {Kaba}
     */
    enableSassNodeModulesIncludePaths ()
    {
        this.sassIncludePaths = [
            path.join(this.cwd, "node_modules"),
        ];
        return this;
    }

    /**
     * Returns the built webpack config
     *
     * @return {Object}
     */
    getWebpackConfig ()
    {
        // clean output sub directories
        this.removeOutputSubDirectories.map(
            (dir) => fs.removeSync(path.join(this.outputPath, dir))
        );

        // build SCSS
        this.buildScss();

        /** @type {webpack.options} config */
        const config = {
            // entry
            entry: this.entries,

            // output
            output: {
                path: this.outputPath,
                filename: '[name].js',
                chunkFilename: 'chunk.[name].js',
                publicPath: this.publicPath,
                pathinfo: !this.config.isDebug(),
            },

            // module
            module: {
                rules: [
                    // Babel
                    {
                        test: /\.jsx?$/,
                        loader: "babel-loader?cacheDirectory",
                        options: {
                            babelrc: false,
                            presets: [
                                require("kaba-babel-preset"),
                            ],
                        },
                    },
                    // TypeScript
                    {
                        test: /\.tsx?$/,
                        use: [
                            // run TypeScript through Babel, so that ES5 compatibility is ensured
                            {
                                loader: "babel-loader?cacheDirectory",
                                options: {
                                    babelrc: false,
                                    presets: [
                                        require("kaba-babel-preset"),
                                    ],
                                },
                            },
                            {
                                loader: "awesome-typescript-loader",
                                query: {
                                    configFileName: path.join(this.libRoot, "tsconfig.json"),
                                },
                            },
                        ],
                    },
                ],
            },

            // resolve
            resolve: {
                extensions: [".ts", ".tsx", ".js", ".jsx", ".json"],
                modules: [
                    path.join(this.cwd, "node_modules"),
                    path.join(this.libRoot, "node_modules"),
                ],
            },

            // performance

            // context
            context: this.cwd,

            // target
            target: "web",

            // externals
            externals: this.externals,

            // stats
            stats: {
                // hide children information (like from the ExtractTextPlugin)
                children: false,
                // errors are shown through the FriendlyErrorsWebpackPlugin instead
                errors: false,
            },

            // devServer

            // plugins
            plugins: this.plugins,

            // watch
            watch: this.config.isWatch(),

            // node
            // don't automatically polyfill certain node libraries
            // as we don't care about these implementations and they just add weight
            node: false,
        };

        // @deprecated
        // in webpack 4 this will always be enabled
        if (this.moduleConcatenationEnabled)
        {
            config.plugins.push(
                new webpack.optimize.ModuleConcatenationPlugin(),
            );
        }

        if (this.config.includeSourceMaps())
        {
            config.devtool = this.config.isDebug()
                ? "cheap-module-eval-source-map"
                : "hidden-source-map";
        }
        else
        {
            config.plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        warnings: false,
                        //eslint-disable-next-line camelcase
                        drop_console: false,
                    },
                    parallel: true,
                    extractComments: true,
                    sourceMap: true,
                }),
            );
        }

        if (this.config.isLint())
        {
            config.module.rules.push({
                enforce: "pre",
                test: /\.jsx?$/,
                exclude: /node_modules|vendor/,
                loader: "eslint-loader",
                options: {
                    cache: true,
                    configFile: path.join(this.libRoot, ".eslintrc.yml"),
                    parser: "babel-eslint",
                },
            });
        }

        if (this.config.isBundleAnalyzerEnabled())
        {
            config.plugins.push(new BundleAnalyzerPlugin());
        }

        return config;
    }

    /**
     * Builds the SCSS code
     *
     * @private
     * @return {boolean}
     */
    async buildScss ()
    {
        const compiler = new KabaScss({
            isDebug: this.config.isDebug(),
            includeSourceMaps: this.config.includeSourceMaps(),
            isWatch: this.config.isWatch(),
            lint: this.config.isLint(),
            analyze: false,
            cwd: this.cwd,
            browserlist: this.browserList,
        });

        Object.keys(this.scssEntries).forEach(
            name =>
            {
                const src = this.scssEntries[name];
                const outputPath = `${this.outputPath}/${name}.css`;

                compiler.addEntry(src, path.dirname(outputPath), path.basename(outputPath));
            }
        );

        return compiler.run();
    }
}

module.exports = Kaba;
<commit_msg>Remove inlined scss build<commit_after>const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const Config = require("./config");
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
const fs = require("fs-extra");
const path = require("path");
const program = require("commander");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const webpack = require("webpack");

/**
 * Main Kaba class
 */
class Kaba
{
    /**
     *
     */
    constructor ()
    {
        /**
         * @private
         * @type {string}
         */
        this.cwd = process.cwd();

        /**
         * @private
         * @†ype {string}
         */
        this.libRoot = path.dirname(__dirname);

        /**
         * @private
         * @type {Config}
         */
        this.config = new Config(program);

        /**
         * @private
         * @type {Object<string,string>}
         */
        this.entries = {};

        /**
         * @private
         * @type {Object<string,string>}
         */
        this.sassEntries = {};

        /**
         * @private
         * @type {string}
         */
        this.outputPath = "";

        /**
         * @private
         * @type {string}
         */
        this.publicPath = "";

        /**
         * @private
         * @type {Object<string,string>}
         */
        this.externals = {};

        /**
         * @private
         * @type {string[]}
         */
        this.browserList = [];

        /**
         * @private
         * @type {boolean}
         * @deprecated
         */
        this.moduleConcatenationEnabled = true;

        /**
         * @private
         * @type {string[]}
         */
        this.removeOutputSubDirectories = [];

        /**
         * @private
         * @type {string[]}
         */
        this.sassIncludePaths = [];

        /**
         * @private
         * @type {?{names: string[], minChunks: number}}
         */
        this.sharedEntryConfig = null;

        /**
         * The webpack plugins
         *
         * @private
         * @type {Array}
         */
        this.plugins = [
            new webpack.DefinePlugin({
                "process.env.NODE_ENV": this.config.isDebug() ? '"development"' : '"production"',
            }),
            new FriendlyErrorsWebpackPlugin({
                clearConsole: this.config.isWatch(),
            }),
        ];

        // set defaults
        this
            .setOutputPath("build")
            .setPublicPath("/assets/")
            .cleanOutputDir(["js"])
            .setBrowserList(["last 2 versions", "IE 11"])
        ;
    }

    /**
     * Adds an entry
     *
     * @param {Object<string,string>} mapping
     * @return {Kaba}
     */
    addEntries (mapping)
    {
        for (const name in mapping)
        {
            if (!mapping.hasOwnProperty(name))
            {
                continue;
            }

            const source = mapping[name];

            // special handling for SCSS files
            if (/\.scss$/.test(source))
            {
                if (this.sassEntries[name] !== undefined)
                {
                    throw new Error(`Can't add scss entry named ${name}: an entry with this name already exists.`);
                }

                this.sassEntries[name] = source;
            }
            else
            {
                if (this.entries[name] !== undefined)
                {
                    throw new Error(`Can't add js entry named ${name}: an entry with this name already exists.`);
                }

                if (null !== this.sharedEntryConfig && -1 !== this.sharedEntryConfig.names.indexOf(name))
                {
                    throw new Error(`Can't add entry named ${name}: it is named like the extracted shared entries.`);
                }

                this.entries[name] = source;
            }
        }

        return this;
    }

    /**
     * Sets the output path
     *
     * @param {string} outputPath
     * @return {Kaba}
     */
    setOutputPath (outputPath)
    {
        this.outputPath = path.join(this.cwd, outputPath);
        return this;
    }

    /**
     * Sets the relative public path (for automatic imports)
     *
     * @param {string} publicPath relative to the cwd
     * @return {Kaba}
     */
    setPublicPath (publicPath)
    {
        this.publicPath = publicPath;
        return this;
    }

    /**
     *
     * @param {Object<string,string>} externals
     * @return {Kaba}
     */
    setExternals (externals)
    {
        this.externals = externals;
        return this;
    }

    /**
     * Sets the browser list
     *
     * @param {string[]} list
     * @return {Kaba}
     */
    setBrowserList (list)
    {
        this.browserList = list;
        return this;
    }

    /**
     * Disabled module concatenation
     *
     * @deprecated will be removed, as soon as webpack is updated to v4
     * @return {Kaba}
     */
    disableModuleConcatenation ()
    {
        this.moduleConcatenationEnabled = false;
        return this;
    }

    /**
     * Creates a shared vendor entry name
     *
     * @param {string[]} vendorFiles
     * @param {string} vendorName
     * @param {string|null} runtimeName
     * @return {Kaba}
     */
    extractSharedEntry (vendorFiles = [], vendorName = "vendor", runtimeName = "runtime")
    {
        if (null === vendorName)
        {
            throw new Error("extractSharedLibraries() failed: vendorName can not be null.");
        }

        if (this.sharedEntryConfig !== null)
        {
            throw new Error("extractSharedLibraries() can only be called once: only one vendor entry can be created.");
        }

        if (this.entries[vendorName] !== undefined)
        {
            throw new Error("Cannot extract shared entry: there already is a regular entry with the same name as the vendor name.");
        }

        if (runtimeName !== null && this.entries[runtimeName] !== undefined)
        {
            throw new Error("Cannot extract shared entry: there already is a regular entry with the same name as the runtime name.");
        }

        const names = [vendorName];

        if (null !== runtimeName)
        {
            names.push(runtimeName);
        }

        // first add entry, as it checks the name for conflicts with the shared entry config name
        if (vendorFiles.length > 0)
        {
            this.addEntries({
                [vendorName]: vendorFiles,
            });
        }

        this.sharedEntryConfig = {
            names: names,
            minChunks: 3,
        };

        this.plugins.push(
            new webpack.optimize.CommonsChunkPlugin(this.sharedEntryConfig),
        );

        return this;
    }

    /**
     * Enables cleaning the output dir before the build
     *
     * @param {string[]} subDirectories
     * @return {Kaba}
     */
    cleanOutputDir (subDirectories)
    {
        this.removeOutputSubDirectories = subDirectories;
        return this;
    }

    /**
     * Adds `node_modules` to the include dir of sass.
     *
     * @return {Kaba}
     */
    enableSassNodeModulesIncludePaths ()
    {
        this.sassIncludePaths = [
            path.join(this.cwd, "node_modules"),
        ];
        return this;
    }

    /**
     * Returns the built webpack config
     *
     * @return {Object}
     */
    getWebpackConfig ()
    {
        // clean output sub directories
        this.removeOutputSubDirectories.map(
            (dir) => fs.removeSync(path.join(this.outputPath, dir))
        );

        /** @type {webpack.options} config */
        const config = {
            // entry
            entry: this.entries,

            // output
            output: {
                path: this.outputPath,
                filename: '[name].js',
                chunkFilename: 'chunk.[name].js',
                publicPath: this.publicPath,
                pathinfo: !this.config.isDebug(),
            },

            // module
            module: {
                rules: [
                    // Babel
                    {
                        test: /\.jsx?$/,
                        loader: "babel-loader?cacheDirectory",
                        options: {
                            babelrc: false,
                            presets: [
                                require("kaba-babel-preset"),
                            ],
                        },
                    },
                    // TypeScript
                    {
                        test: /\.tsx?$/,
                        use: [
                            // run TypeScript through Babel, so that ES5 compatibility is ensured
                            {
                                loader: "babel-loader?cacheDirectory",
                                options: {
                                    babelrc: false,
                                    presets: [
                                        require("kaba-babel-preset"),
                                    ],
                                },
                            },
                            {
                                loader: "awesome-typescript-loader",
                                query: {
                                    configFileName: path.join(this.libRoot, "tsconfig.json"),
                                },
                            },
                        ],
                    },
                ],
            },

            // resolve
            resolve: {
                extensions: [".ts", ".tsx", ".js", ".jsx", ".json"],
                modules: [
                    path.join(this.cwd, "node_modules"),
                    path.join(this.libRoot, "node_modules"),
                ],
            },

            // performance

            // context
            context: this.cwd,

            // target
            target: "web",

            // externals
            externals: this.externals,

            // stats
            stats: {
                // hide children information (like from the ExtractTextPlugin)
                children: false,
                // errors are shown through the FriendlyErrorsWebpackPlugin instead
                errors: false,
            },

            // devServer

            // plugins
            plugins: this.plugins,

            // watch
            watch: this.config.isWatch(),

            // node
            // don't automatically polyfill certain node libraries
            // as we don't care about these implementations and they just add weight
            node: false,
        };

        // @deprecated
        // in webpack 4 this will always be enabled
        if (this.moduleConcatenationEnabled)
        {
            config.plugins.push(
                new webpack.optimize.ModuleConcatenationPlugin(),
            );
        }

        if (this.config.includeSourceMaps())
        {
            config.devtool = this.config.isDebug()
                ? "cheap-module-eval-source-map"
                : "hidden-source-map";
        }
        else
        {
            config.plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        warnings: false,
                        //eslint-disable-next-line camelcase
                        drop_console: false,
                    },
                    parallel: true,
                    extractComments: true,
                    sourceMap: true,
                }),
            );
        }

        if (this.config.isLint())
        {
            config.module.rules.push({
                enforce: "pre",
                test: /\.jsx?$/,
                exclude: /node_modules|vendor/,
                loader: "eslint-loader",
                options: {
                    cache: true,
                    configFile: path.join(this.libRoot, ".eslintrc.yml"),
                    parser: "babel-eslint",
                },
            });
        }

        if (this.config.isBundleAnalyzerEnabled())
        {
            config.plugins.push(new BundleAnalyzerPlugin());
        }

        return config;
    }
}

module.exports = Kaba;
<|endoftext|>


<commit_before>
/****************************************************************************
 LICENSE: CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
 This is an original driver by Elijah Parker <mail@timelapseplus.com>
 It is free to use in other projects for non-commercial purposes.  For a
 commercial license and consulting, please contact mail@timelapseplus.com
*****************************************************************************/

var util = require('util');
var async = require('async');
var EventEmitter = require('events').EventEmitter;
var ptp = require('../common/ptp-functions.js');
var fs = require('fs');

var driver = new EventEmitter();

driver.name = "Fujifilm";

function _logD() {
    if(arguments.length > 0) {
        arguments[0] = "PTP-FUJI: " + arguments[0];
    }
    console.log.apply(console, arguments);
}

driver.supportedCameras = {
    '04cb:02cb': {
            name: "Fuji X-Pro2",
            supports: {
                shutter: true,
                aperture: true,
                iso: true,
                liveview: true,
                target: true,
                focus: true,
            }
        },
    '04cb:02cd': {
            name: "Fuji X-T2",
            supports: {
                shutter: true,
                aperture: true,
                iso: true,
                liveview: true,
                target: true,
                focus: true,
            }
        },
    '04cb:02d7': {
            name: "Fuji X-H1",
            supports: {
                shutter: true,
                aperture: true,
                iso: true,
                liveview: true,
                target: true,
                focus: true,
            }
        },
    '04cb:02dd': {
            name: "Fuji X-T3",
            supports: {
                shutter: true,
                aperture: true,
                iso: true,
                liveview: true,
                target: true,
                focus: true,
            }
        },
}

var properties = {
    'shutter': {
        name: 'shutter',
        function: ptp.setPropU16,
        code: 0xD219,
        ev: true,
        values: [
            {name: '1s', ev: -6, code: 0},
        ]
    }
}

driver._error = function(camera, error) { // events received
    _logD("ERROR:", error);
};

driver._event = function(camera, data) { // events received
    _logD("EVENT:", data);
    ptp.parseEvent(data, function(type, event, param1, param2, param3) {
        if(event == ptp.PTP_EC_ObjectAdded) {
            _logD("object added:", param1);
            var objectId = param1;
            ptp.getObjectInfo(camera._dev, objectId, function(err, oi) {
                console.log(oi);
                var image = null;
                if(camera.thumbnail) {
                    ptp.getThumb(camera._dev, objectId, function(err, jpeg) {
                        //fs.writeFileSync("thumb.jpg", jpeg);
                        ptp.deleteObject(camera._dev, objectId, function() {
                            if(camera._captureCallback) {
                                camera._captureCallback(err, jpeg, oi.filename, null);
                                camera._captureCallback = null;
                            }
                        });
                    })
                } else {
                    ptp.getObject(camera._dev, objectId, function(err, image) {
                        //fs.writeFileSync("embedded.jpg", ptp.extractJpeg(image));
                        //fs.writeFileSync("image.raf", image);
                        ptp.deleteObject(camera._dev, objectId, function() {
                            if(camera._captureCallback) {
                                camera._captureCallback(err, ptp.extractJpeg(image), oi.filename, image);
                                camera._captureCallback = null;
                            }
                        });
                    })
                }
            });
        }
    });
};

driver.init = function(camera, callback) {
    ptp.init(camera._dev, function(err, di) {
        async.series([
            function(cb){ptp.setPropU16(camera._dev, 0xd38c, 1, cb);},
            function(cb){ptp.setPropU16(camera._dev, 0xd207, 2, cb);}
        ], function(err) {
            var capture = function() {
                driver.capture(camera, "", {}, function(err, thumb, filename, rawImage){
                    _logD("capture err result:", ptp.hex(err), "filename", filename);
                    var delay = 1000;
                    if(err == 0x2019) delay = 50;
                    setTimeout(function() {
                        capture();
                    }, delay);
                });
            }
            capture();
            callback && callback(err);
        });
    });
}

driver.set = function(camera, param, value, callback) {

}

driver.capture = function(camera, target, options, callback, tries) {
    var targetValue = (!target || target == "camera") ? 2 : 4;
    camera.thumbnail = true;
    async.series([
        function(cb){ptp.setPropU16(camera._dev, 0xd20c, targetValue, cb);}, // set target
        function(cb){ptp.setPropU16(camera._dev, 0xd208, 0x0200, cb);},
        function(cb){ptp.ptpCapture(camera._dev, [0x0, 0x0], cb);},
        function(cb){
            var check = function() {
                ptp.getPropU16(camera._dev, 0xd209, function(err, data) { // wait if busy
                    if(data == 0x0001) {
                        check();
                    } else {
                        cb(err);
                    }
                });
            }
            check();
        },
        function(cb){ptp.setPropU16(camera._dev, 0xd208, 0x0304, cb);},
        function(cb){ptp.ptpCapture(camera._dev, [0x0, 0x0], cb);},
        function(cb){
            var check = function() {
                ptp.getPropData(camera._dev, 0xd212, function(err, data) { // wait if busy
                    console.log("data:", data);
                    //if(data == 0x0001) {
                        check();
                    //} else {
                    //    cb(err);
                    //}
                });
            }
            check();
        },
    ], function(err) {
        if(err) {
            callback && callback(err);
        } else {
            console.log("delaying callback for capture...");
            camera._captureCallback = function(err, thumb, filename, rawImage) {
                callback && callback(err, thumb, filename, rawImage);
            }
        }
    });
}

driver.captureHDR = function(camera, target, options, frames, stops, darkerOnly, callback) {

}

driver.liveviewMode = function(camera, enable, callback) {

}

driver.liveviewImage = function(camera, nable, callback) {

}

driver.moveFocus = function(camera, steps, resolution, callback) {

}

driver.get = function(camera, param, value, callback) {

}

module.exports = driver;
<commit_msg>usb testing<commit_after>
/****************************************************************************
 LICENSE: CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
 This is an original driver by Elijah Parker <mail@timelapseplus.com>
 It is free to use in other projects for non-commercial purposes.  For a
 commercial license and consulting, please contact mail@timelapseplus.com
*****************************************************************************/

var util = require('util');
var async = require('async');
var EventEmitter = require('events').EventEmitter;
var ptp = require('../common/ptp-functions.js');
var fs = require('fs');

var driver = new EventEmitter();

driver.name = "Fujifilm";

function _logD() {
    if(arguments.length > 0) {
        arguments[0] = "PTP-FUJI: " + arguments[0];
    }
    console.log.apply(console, arguments);
}

driver.supportedCameras = {
    '04cb:02cb': {
            name: "Fuji X-Pro2",
            supports: {
                shutter: true,
                aperture: true,
                iso: true,
                liveview: true,
                target: true,
                focus: true,
            }
        },
    '04cb:02cd': {
            name: "Fuji X-T2",
            supports: {
                shutter: true,
                aperture: true,
                iso: true,
                liveview: true,
                target: true,
                focus: true,
            }
        },
    '04cb:02d7': {
            name: "Fuji X-H1",
            supports: {
                shutter: true,
                aperture: true,
                iso: true,
                liveview: true,
                target: true,
                focus: true,
            }
        },
    '04cb:02dd': {
            name: "Fuji X-T3",
            supports: {
                shutter: true,
                aperture: true,
                iso: true,
                liveview: true,
                target: true,
                focus: true,
            }
        },
}

var properties = {
    'shutter': {
        name: 'shutter',
        function: ptp.setPropU16,
        code: 0xD219,
        ev: true,
        values: [
            {name: '1s', ev: -6, code: 0},
        ]
    }
}

driver._error = function(camera, error) { // events received
    _logD("ERROR:", error);
};

driver._event = function(camera, data) { // events received
    _logD("EVENT:", data);
    ptp.parseEvent(data, function(type, event, param1, param2, param3) {
        if(event == ptp.PTP_EC_ObjectAdded) {
            _logD("object added:", param1);
        }
    });
};

driver.init = function(camera, callback) {
    ptp.init(camera._dev, function(err, di) {
        async.series([
            function(cb){ptp.setPropU16(camera._dev, 0xd38c, 1, cb);},
            function(cb){ptp.setPropU16(camera._dev, 0xd207, 2, cb);}
        ], function(err) {
            var capture = function() {
                driver.capture(camera, "", {}, function(err, thumb, filename, rawImage){
                    _logD("capture err result:", ptp.hex(err), "filename", filename);
                    var delay = 1000;
                    if(err == 0x2019) delay = 50;
                    setTimeout(function() {
                        capture();
                    }, delay);
                });
            }
            capture();
            callback && callback(err);
        });
    });
}

driver.set = function(camera, param, value, callback) {

}

driver.capture = function(camera, target, options, callback, tries) {
    var targetValue = (!target || target == "camera") ? 2 : 4;
    camera.thumbnail = true;

    var results = {
        thumb: null,
        filename: null,
        rawImage: null
    }

    async.series([
        function(cb){ptp.setPropU16(camera._dev, 0xd20c, targetValue, cb);}, // set target
        function(cb){ptp.setPropU16(camera._dev, 0xd208, 0x0200, cb);},
        function(cb){ptp.ptpCapture(camera._dev, [0x0, 0x0], cb);},
        function(cb){
            var check = function() {
                ptp.getPropU16(camera._dev, 0xd209, function(err, data) { // wait if busy
                    if(data == 0x0001) {
                        check();
                    } else {
                        cb(err);
                    }
                });
            }
            check();
        },
        function(cb){ptp.setPropU16(camera._dev, 0xd208, 0x0304, cb);},
        function(cb){ptp.ptpCapture(camera._dev, [0x0, 0x0], cb);},
        function(cb){
            var check = function() {
                ptp.getPropData(camera._dev, 0xd212, function(err, data) { // wait if busy
                    console.log("data:", data);
                    if(data.length >= 4 && data.readUInt16LE(2) == 0xD20E) {
                        var objectId = 0x00000001;
                        ptp.getObjectInfo(camera._dev, objectId, function(err, oi) {
                            console.log(oi);
                            var image = null;
                            results.filename = oi.filename;
                            if(camera.thumbnail) {
                                ptp.getThumb(camera._dev, objectId, function(err, jpeg) {
                                    ptp.deleteObject(camera._dev, objectId, function() {
                                        results.thumb = jpeg;
                                        cb(err);
                                    });
                                })
                            } else {
                                ptp.getObject(camera._dev, objectId, function(err, image) {
                                    //fs.writeFileSync("embedded.jpg", ptp.extractJpeg(image));
                                    //fs.writeFileSync("image.raf", image);
                                    ptp.deleteObject(camera._dev, objectId, function() {
                                        results.thumb = ptp.extractJpeg(image);
                                        results.rawImage = image;
                                        cb(err);
                                    });
                                })
                            }
                        });
                    } else {
                        check();
                    }
                });
            }
            check();
        },
    ], function(err) {
        callback && callback(err, results.thumb, results.filename, results.rawImage);
    });
}

driver.captureHDR = function(camera, target, options, frames, stops, darkerOnly, callback) {

}

driver.liveviewMode = function(camera, enable, callback) {

}

driver.liveviewImage = function(camera, nable, callback) {

}

driver.moveFocus = function(camera, steps, resolution, callback) {

}

driver.get = function(camera, param, value, callback) {

}

module.exports = driver;
<|endoftext|>


<commit_before>module.exports = {
    context: __dirname,
    devtool: "eval",
    resolve: {
        extensions: [ "", ".webpack.js", ".ts", ".tsx", ".js" ]
    },
    entry: {
        chook: "./index.ts"
    },
    output: {
        path: 'build/lib',
        filename: "chook.js",
        libraryTarget: 'umd'
    },
    target: 'node',
    module: {
        loaders: [
            {
                test: /\.tsx?$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'ts-loader'
            },
            {
                test: /\.json$/,
                loader: 'json-loader'
            }
        ]
    },
    externals: [ 'express', 'js-yaml' ]
};<commit_msg>Now webpack development configuration points to development entrypoint<commit_after>module.exports = {
    context: __dirname,
    devtool: "eval",
    resolve: {
        extensions: [ "", ".webpack.js", ".ts", ".tsx", ".js" ]
    },
    entry: {
        chook: "./dev-index.ts"
    },
    output: {
        path: 'build/lib',
        filename: "chook.js",
        libraryTarget: 'umd'
    },
    target: 'node',
    module: {
        loaders: [
            {
                test: /\.tsx?$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'ts-loader'
            },
            {
                test: /\.json$/,
                loader: 'json-loader'
            }
        ]
    },
    externals: [ 'express', 'js-yaml' ]
};<|endoftext|>


<commit_before>/* @flow */

import React from 'react';
import { compose, withState, mapProps, pure, lifecycle } from 'recompose';
import AngleIcon from 'react-icons/lib/fa/angle-down';

import styled from '@ncigdc/theme/styled';
import withRouter from '@ncigdc/utils/withRouter';
import Input from '@ncigdc/uikit/Form/Input';
import { parseFilterParam } from '@ncigdc/utils/uri';
import { Row, Column } from '@ncigdc/uikit/Flex';

import Link from '../Links/Link';

const getCurrentFromAndTo = ({ field, query }) => {
  const dotField = field.replace(/__/g, '.');
  const currentFilters = (query && parseFilterParam((query || {}).filters, {}).content) || [];
  return currentFilters.reduce(
    (acc, c) => (c.content.field === dotField ? { ...acc, [c.op]: c.content.value[0] } : acc),
    { '>=': undefined, '<=': undefined }
  );
};

const conversionFactor = 365.25;
const convertMaxMin = ({ max, min, convertDays, selectedUnit, setState }) => {
  if (convertDays && selectedUnit === 'years') {
    setState(s => ({
      ...s,
      minDisplayed: Math.ceil(min / conversionFactor),
      maxDisplayed: Math.ceil(((max + 1) - conversionFactor) / conversionFactor),
    }));
  } else {
    setState(s => ({ ...s, maxDisplayed: max, minDisplayed: min }));
  }
};

const inputChanged = ({ from, to, convertDays, selectedUnit, setState }) => {
  if (!convertDays || selectedUnit === 'days') {
    setState(s => ({
      ...s,
      from: from ? from : undefined,
      to: to ? to : undefined,
      fromDisplayed: from ? from : '',
      toDisplayed: to ? to : '',
    }));
  } else if (selectedUnit === 'years') {
    setState(s => ({
      ...s,
      from: from ? Math.floor(from * conversionFactor) : undefined,
      to: to ? Math.floor(((to * conversionFactor) + conversionFactor) - 1) : undefined,
      fromDisplayed: from ? from : '',
      toDisplayed: to ? to : '',
    }));
  }
};

const convertInputs = ({ from, to, selectedUnit, setState }) => {
  if (selectedUnit === 'days') {
    setState(s => ({
      ...s,
      from,
      to,
      fromDisplayed: from,
      toDisplayed: to,
    }));
  } else if (selectedUnit === 'years') {
    setState(s => ({
      ...s,
      from,
      to,
      fromDisplayed: Math.ceil(from / conversionFactor),
      toDisplayed: Math.ceil(((to + 1) - conversionFactor) / conversionFactor),
    }));
  }
};

const Container = styled(Column, ({
  padding: '1rem 1.2rem',
  backgroundColor: 'white',
}));

const HeaderRow = styled(Row, ({
  color: ({ theme }) => theme.primary,
  fontSize: '1.7rem',
  marginBottom: '0.5rem',
  cursor: 'pointer',
  alignItems: 'center',
}));

const InputLabel = styled.label({
  backgroundColor: ({ theme }) => theme.greyScale5,
  color: ({ theme }) => theme.greyScale2,
  padding: '0.8rem',
  height: '3.4rem',
  border: ({ theme }) => `1px solid ${theme.greyScale4}`,
});

const StyledInput = styled(Input, ({
  height: '3.4rem',
  borderRadius: 0,
}));

const GoLink = styled(Link, ({
  color: ({ theme, dark }) => (dark ? theme.greyScale2 : theme.greyScale4),
  textDecoration: 'none',
  border: ({ theme }) => `1px solid ${theme.greyScale4}`,
  borderLeft: 0,
  padding: '6px 4px 2px 4px',
  height: '3.4rem',
  borderRadius: '0 4px 4px 0',
}));

const enhance = compose(
  withState('state', 'setState', {
    collapsed: false,
    from: undefined,
    to: undefined,
    fromDisplayed: '',
    toDisplayed: '',
    maxDisplayed: 0,
    minDisplayed: 0,
    selectedUnit: 'years',
  }),
  withRouter,
  lifecycle({
    componentDidMount(): void {
      const { field, query, max, min, convertDays, state: { selectedUnit }, setState } = this.props;
      const thisFieldCurrent = getCurrentFromAndTo({ field, query });
      const opToWord = { '>=': 'from', '<=': 'to' };
      const newState = Object.keys(thisFieldCurrent)
        .filter(k => thisFieldCurrent[k])
        .reduce((acc, k) => ({ ...acc, [opToWord[k]]: thisFieldCurrent[k] }), {});
      if (convertDays) {
        convertInputs({ from: newState.from, to: newState.to, selectedUnit, setState });
      } else {
        setState(s => ({ ...s, ...newState, fromDisplayed: newState.from, toDisplayed: newState.to }));
      }
      convertMaxMin({ max, min, convertDays, selectedUnit, setState });
    },
    componentWillReceiveProps(nextProps: Object): void {
      if (Object.entries(this.props.query).some(([key, val]) =>
        val !== nextProps.query[key]
      )) {
        const { field, query } = nextProps;
        const { selectedUnit, setState, convertDays } = this.props;
        const thisFieldCurrent = getCurrentFromAndTo({ field, query });
        const opToWord = { '>=': 'from', '<=': 'to' };
        const newState = Object.keys(thisFieldCurrent)
          .filter(k => thisFieldCurrent[k])
          .reduce((acc, k) => ({ ...acc, [opToWord[k]]: thisFieldCurrent[k] }), {});
        if (convertDays) {
          convertInputs({ from: newState.from, to: newState.to, selectedUnit, setState });
        } else {
          setState(s => ({ ...s, ...newState, fromDisplayed: newState.from, toDisplayed: newState.to }));
        }
      }
    },
  }),
  mapProps(({ setState, max, min, convertDays, ...rest }) => ({
    toggleCollapsed: () => setState(state => ({ ...state, collapsed: !state.collapsed })),
    handleFromChanged: (e) => {
      const v = e.target.value;
      const { state: { toDisplayed, selectedUnit } } = rest;
      inputChanged({ from: v, to: toDisplayed, convertDays, selectedUnit, setState });
    },
    handleToChanged: (e) => {
      const v = e.target.value;
      const { state: { fromDisplayed, selectedUnit } } = rest;
      inputChanged({ from: fromDisplayed, to: v, convertDays, selectedUnit, setState });
    },
    handleUnitChanged: (e) => {
      const v = e.target.value;
      const { state: { from, to } } = rest;
      setState(s => ({ ...s, selectedUnit: v }));
      convertMaxMin({ max, min, convertDays, selectedUnit: v, setState });
      convertInputs({ from, to, selectedUnit: v, setState });
    },
    setState,
    max,
    min,
    convertDays,
    ...rest,
  })),
  pure
);

type TProps = {
  theme: Object,
  field: string,
  query: Object,
  title: string,
  state: {
    collapsed: boolean,
    to: number,
    from: number,
    selectedUnit: string,
    fromDisplayed: number,
    toDisplayed: number,
  },
  style: Object,
  toggleCollapsed: Function,
  handleToChanged: Function,
  handleFromChanged: Function,
  handleUnitChanged: Function,
  min: Number,
  max: Number,
  convertDays: boolean,
};

const RangeFacet = (props: TProps) => {
  const dotField = props.field.replace(/__/g, '.');
  const innerContent = [
    { op: '>=', value: props.state.from },
    { op: '<=', value: props.state.to },
  ].filter(v => v.value)
    .map(v => ({
      op: v.op,
      content: {
        field: dotField,
        value: [v.value],
      },
    }));
  const query = {
    offset: 0,
    filters: {
      op: 'and',
      content: innerContent,
    },
  };
  const { maxDisplayed, minDisplayed } = props.state;
    return (
    <Container style={{ ...props.style }}>
      <HeaderRow onClick={() => props.toggleCollapsed()}>
        <AngleIcon style={{ transform: `rotate(${props.state.collapsed ? 270 : 0}deg)` }} />
        {props.title}
      </HeaderRow>
      {!props.state.collapsed && props.convertDays && (
        <Row>
          <form name={`${dotField}-radio`}>
            <label htmlFor={`${dotField}-years-radio`} style={{ paddingRight: '10px' }}>
              <input
                type="radio"
                value="years"
                onChange={props.handleUnitChanged}
                checked={props.state.selectedUnit === 'years'}
                id={`${dotField}-years-radio`}
                style={{ marginRight: '5px' }}
              />
                Years
            </label>
            <label
              htmlFor={`${dotField}-days-radio`}
              style={{ paddingRight: '10px' }}
            >
              <input
                type="radio"
                value="days"
                onChange={props.handleUnitChanged}
                checked={props.state.selectedUnit === 'days'}
                id={`${dotField}-days-radio`}
                style={{ marginRight: '5px' }}
              />
                Days
            </label>
          </form>
        </Row>
      )}
      {!props.state.collapsed &&
      (<Row>
        <InputLabel
          style={{
            borderRight: 0,
            borderRadius: '4px 0 0 4px',
          }}
          htmlFor={`from-${dotField}`}
        >
          From:
        </InputLabel>
        <StyledInput
          value={props.state.fromDisplayed}
          onChange={props.handleFromChanged}
          id={`from-${dotField}`}
          key={`from-${dotField}`}
          type="number"
          placeholder={minDisplayed}
          max={maxDisplayed}
          min={minDisplayed}
          title="todo"
        />
        <InputLabel
          style={{
            borderLeft: 0,
            borderRight: 0,
          }}
          htmlFor={`to-${dotField}`}
        >
          To:
        </InputLabel>
        <Input
          value={props.state.toDisplayed}
          onChange={props.handleToChanged}
          id={`to-${dotField}`}
          key={`to-${dotField}`}
          type="number"
          placeholder={maxDisplayed}
          max={maxDisplayed}
          min={minDisplayed}
          title='todo'
        />
        <GoLink
          dark={!!innerContent.length}
          merge="replace"
          query={innerContent.length && query}
        >
          Go!
        </GoLink>
      </Row>
      )}
    </Container>
    );
};

export default enhance(RangeFacet);
<commit_msg>🐛 guard against null/undefined in controlled input<commit_after>/* @flow */

import React from 'react';
import { compose, withState, mapProps, pure, lifecycle } from 'recompose';
import AngleIcon from 'react-icons/lib/fa/angle-down';

import styled from '@ncigdc/theme/styled';
import withRouter from '@ncigdc/utils/withRouter';
import Input from '@ncigdc/uikit/Form/Input';
import { parseFilterParam } from '@ncigdc/utils/uri';
import { Row, Column } from '@ncigdc/uikit/Flex';

import Link from '../Links/Link';

const getCurrentFromAndTo = ({ field, query }) => {
  const dotField = field.replace(/__/g, '.');
  const currentFilters = (query && parseFilterParam((query || {}).filters, {}).content) || [];
  return currentFilters.reduce(
    (acc, c) => (c.content.field === dotField ? { ...acc, [c.op]: c.content.value[0] } : acc),
    { '>=': undefined, '<=': undefined }
  );
};

const conversionFactor = 365.25;
const convertMaxMin = ({ max, min, convertDays, selectedUnit, setState }) => {
  if (convertDays && selectedUnit === 'years') {
    setState(s => ({
      ...s,
      minDisplayed: Math.ceil(min / conversionFactor),
      maxDisplayed: Math.ceil(((max + 1) - conversionFactor) / conversionFactor),
    }));
  } else {
    setState(s => ({ ...s, maxDisplayed: max, minDisplayed: min }));
  }
};

const inputChanged = ({ from, to, convertDays, selectedUnit, setState }) => {
  if (!convertDays || selectedUnit === 'days') {
    setState(s => ({
      ...s,
      from: from ? from : undefined,
      to: to ? to : undefined,
      fromDisplayed: from ? from : '',
      toDisplayed: to ? to : '',
    }));
  } else if (selectedUnit === 'years') {
    setState(s => ({
      ...s,
      from: from ? Math.floor(from * conversionFactor) : undefined,
      to: to ? Math.floor(((to * conversionFactor) + conversionFactor) - 1) : undefined,
      fromDisplayed: from ? from : '',
      toDisplayed: to ? to : '',
    }));
  }
};

const convertInputs = ({ from, to, selectedUnit, setState }) => {
  if (selectedUnit === 'days') {
    setState(s => ({
      ...s,
      from,
      to,
      fromDisplayed: from,
      toDisplayed: to,
    }));
  } else if (selectedUnit === 'years') {
    setState(s => ({
      ...s,
      from,
      to,
      fromDisplayed: Math.ceil(from / conversionFactor),
      toDisplayed: Math.ceil(((to + 1) - conversionFactor) / conversionFactor),
    }));
  }
};

const Container = styled(Column, ({
  padding: '1rem 1.2rem',
  backgroundColor: 'white',
}));

const HeaderRow = styled(Row, ({
  color: ({ theme }) => theme.primary,
  fontSize: '1.7rem',
  marginBottom: '0.5rem',
  cursor: 'pointer',
  alignItems: 'center',
}));

const InputLabel = styled.label({
  backgroundColor: ({ theme }) => theme.greyScale5,
  color: ({ theme }) => theme.greyScale2,
  padding: '0.8rem',
  height: '3.4rem',
  border: ({ theme }) => `1px solid ${theme.greyScale4}`,
});

const StyledInput = styled(Input, ({
  height: '3.4rem',
  borderRadius: 0,
}));

const GoLink = styled(Link, ({
  color: ({ theme, dark }) => (dark ? theme.greyScale2 : theme.greyScale4),
  textDecoration: 'none',
  border: ({ theme }) => `1px solid ${theme.greyScale4}`,
  borderLeft: 0,
  padding: '6px 4px 2px 4px',
  height: '3.4rem',
  borderRadius: '0 4px 4px 0',
}));

const enhance = compose(
  withState('state', 'setState', {
    collapsed: false,
    from: undefined,
    to: undefined,
    fromDisplayed: '',
    toDisplayed: '',
    maxDisplayed: 0,
    minDisplayed: 0,
    selectedUnit: 'years',
  }),
  withRouter,
  lifecycle({
    componentDidMount(): void {
      const { field, query, max, min, convertDays, state: { selectedUnit }, setState } = this.props;
      const thisFieldCurrent = getCurrentFromAndTo({ field, query });
      const opToWord = { '>=': 'from', '<=': 'to' };
      const newState = Object.keys(thisFieldCurrent)
        .filter(k => thisFieldCurrent[k])
        .reduce((acc, k) => ({ ...acc, [opToWord[k]]: thisFieldCurrent[k] }), {});
      if (convertDays) {
        convertInputs({ from: newState.from, to: newState.to, selectedUnit, setState });
      } else {
        setState(s => ({ ...s, ...newState, fromDisplayed: newState.from, toDisplayed: newState.to }));
      }
      convertMaxMin({ max, min, convertDays, selectedUnit, setState });
    },
    componentWillReceiveProps(nextProps: Object): void {
      if (Object.entries(this.props.query).some(([key, val]) =>
        val !== nextProps.query[key]
      )) {
        const { field, query } = nextProps;
        const { selectedUnit, setState, convertDays } = this.props;
        const thisFieldCurrent = getCurrentFromAndTo({ field, query });
        const opToWord = { '>=': 'from', '<=': 'to' };
        const newState = Object.keys(thisFieldCurrent)
          .filter(k => thisFieldCurrent[k])
          .reduce((acc, k) => ({ ...acc, [opToWord[k]]: thisFieldCurrent[k] }), {});
        if (convertDays) {
          convertInputs({ from: newState.from, to: newState.to, selectedUnit, setState });
        } else {
          setState(s => ({ ...s, ...newState, fromDisplayed: newState.from, toDisplayed: newState.to }));
        }
      }
    },
  }),
  mapProps(({ setState, max, min, convertDays, ...rest }) => ({
    toggleCollapsed: () => setState(state => ({ ...state, collapsed: !state.collapsed })),
    handleFromChanged: (e) => {
      const v = e.target.value;
      const { state: { toDisplayed, selectedUnit } } = rest;
      inputChanged({ from: v, to: toDisplayed, convertDays, selectedUnit, setState });
    },
    handleToChanged: (e) => {
      const v = e.target.value;
      const { state: { fromDisplayed, selectedUnit } } = rest;
      inputChanged({ from: fromDisplayed, to: v, convertDays, selectedUnit, setState });
    },
    handleUnitChanged: (e) => {
      const v = e.target.value;
      const { state: { from, to } } = rest;
      setState(s => ({ ...s, selectedUnit: v }));
      convertMaxMin({ max, min, convertDays, selectedUnit: v, setState });
      convertInputs({ from, to, selectedUnit: v, setState });
    },
    setState,
    max,
    min,
    convertDays,
    ...rest,
  })),
  pure
);

type TProps = {
  theme: Object,
  field: string,
  query: Object,
  title: string,
  state: {
    collapsed: boolean,
    to: number,
    from: number,
    selectedUnit: string,
    fromDisplayed: number,
    toDisplayed: number,
  },
  style: Object,
  toggleCollapsed: Function,
  handleToChanged: Function,
  handleFromChanged: Function,
  handleUnitChanged: Function,
  min: Number,
  max: Number,
  convertDays: boolean,
};

const RangeFacet = (props: TProps) => {
  const dotField = props.field.replace(/__/g, '.');
  const innerContent = [
    { op: '>=', value: props.state.from },
    { op: '<=', value: props.state.to },
  ].filter(v => v.value)
    .map(v => ({
      op: v.op,
      content: {
        field: dotField,
        value: [v.value],
      },
    }));
  const query = {
    offset: 0,
    filters: {
      op: 'and',
      content: innerContent,
    },
  };
  const { maxDisplayed, minDisplayed } = props.state;

  return (
    <Container style={{ ...props.style }}>
      <HeaderRow onClick={() => props.toggleCollapsed()}>
        <AngleIcon style={{ transform: `rotate(${props.state.collapsed ? 270 : 0}deg)` }} />
        {props.title}
      </HeaderRow>
      {!props.state.collapsed && props.convertDays && (
        <Row>
          <form name={`${dotField}-radio`}>
            <label htmlFor={`${dotField}-years-radio`} style={{ paddingRight: '10px' }}>
              <input
                type="radio"
                value="years"
                onChange={props.handleUnitChanged}
                checked={props.state.selectedUnit === 'years'}
                id={`${dotField}-years-radio`}
                style={{ marginRight: '5px' }}
              />
                Years
            </label>
            <label
              htmlFor={`${dotField}-days-radio`}
              style={{ paddingRight: '10px' }}
            >
              <input
                type="radio"
                value="days"
                onChange={props.handleUnitChanged}
                checked={props.state.selectedUnit === 'days'}
                id={`${dotField}-days-radio`}
                style={{ marginRight: '5px' }}
              />
                Days
            </label>
          </form>
        </Row>
      )}
      {!props.state.collapsed &&
      (<Row>
        <InputLabel
          style={{
            borderRight: 0,
            borderRadius: '4px 0 0 4px',
          }}
          htmlFor={`from-${dotField}`}
        >
          From:
        </InputLabel>
        <StyledInput
          value={props.state.fromDisplayed || ''}
          onChange={props.handleFromChanged}
          id={`from-${dotField}`}
          key={`from-${dotField}`}
          type="number"
          placeholder={minDisplayed}
          max={maxDisplayed}
          min={minDisplayed}
          title="todo"
        />
        <InputLabel
          style={{
            borderLeft: 0,
            borderRight: 0,
          }}
          htmlFor={`to-${dotField}`}
        >
          To:
        </InputLabel>
        <Input
          value={props.state.toDisplayed || ''}
          onChange={props.handleToChanged}
          id={`to-${dotField}`}
          key={`to-${dotField}`}
          type="number"
          placeholder={maxDisplayed}
          max={maxDisplayed}
          min={minDisplayed}
          title='todo'
        />
        <GoLink
          dark={!!innerContent.length}
          merge="replace"
          query={innerContent.length && query}
        >
          Go!
        </GoLink>
      </Row>
      )}
    </Container>
    );
};

export default enhance(RangeFacet);
<|endoftext|>


<commit_before>/**
 * Tiny simplistic tooltip plugin for jQuery
 * version 0.1.1
 * Kane Cohen [KaneCohen@gmail.com] | https://github.com/KaneCohen
 * @preserve
 */
(function(factory) {
	if (typeof define === 'function' && define.amd) {
		define(['jquery'], factory);
	} else {
		factory(jQuery);
	}
}(function($) {
	$.fn.tip = function(options) {
		var args = arguments,
		    o = $.extend(true, {}, options);

		var tip = $(o.parent || document).data('tip');
		o.selector = this.selector || '.tip';
		if (tip) {
			tip.trigger.apply(tip, args);
		} else {
			new Tip(o);
		}
		return this;
	};

	function Tip(o) {
		this.init(o);
	}

	Tip.prototype = {
		o: {},
		d: {
			parent:   null,   // Object to bind listeners to.
			showTime: 200,
			hideTime: 1000,
			arrowSize: 5,
			follow:   false,   // Follow mouse. Values: 'x', 'y', 'xy', false.
			position: 'auto',  // top, bottom, left, right, auto.
			align:    'right', // center, right
			aside:    false,   // Place tooltip to the left/right based on "position" option. true, false.
			selector: '.tip',
			tpl: '
' +
				'

' +
				'' +
			'
'
		},
		v: {},
		dv: {
			timer: null,
			enter: null,
			active: false,
			follow: {
				x: false,
				y: false
			}
		},
		init: function(o) {
			this.o = $.extend({}, this.d, o);
			this.v = $.extend({}, this.dv);
			this.o.parent = o.parent || document;
			this.initEvents();
			$(this.o.parent).data('tip', this);
		},

		initEvents: function() {
			var self = this;
			$(this.o.parent).on('mouseover.tip', this.o.selector, function(e) {
				var el = $(this);
				if (! el.data('tip') && el.attr('title')) {
					el.attr('data-tip', $.trim(el.attr('title')));
				}
				el.removeAttr('title');
				$('#tip').remove();
				clearTimeout(self.v.timer);
				clearTimeout(self.v.enter);
				if (self.v.active) {
					self.show(e, el);
				} else {
					self.v.timer = setTimeout(function() {
						self.v.active = true;
						self.show(e, el);
					}, self.o.showTime);
				}
			});

			$(this.o.parent).on('mouseout.tip mousedown.tip', self.o.selector+', #tip', function() {
				$(self.o.parent).off('mousemove.tip');
				$('#tip').remove();
				clearTimeout(self.v.timer);
				clearTimeout(self.v.enter);
				self.v.enter = setTimeout(function() {
					self.v.active = false;
				}, self.o.hideTime);
			});
		},

		show: function(e, el) {
			var self = this,
			    o    = this.o,
			    v    = this.v,
			    tip  = $.trim(el.data('tip')),
			    follow   = el.data('tipFollow') || o.follow,
			    align    = el.data('tipAlign') || o.align,
			    aside    = el.data('tipAside') || o.aside,
			    position = el.data('tipPosition') || o.position;

			if (follow) {
				v.follow.x = follow.indexOf('x') >= 0;
				v.follow.y = follow.indexOf('y') >= 0;
			}

			if (tip !== null && tip.length !== 0) {
				var template = $(self.o.tpl),
				    arrow = template.find('.arrow'),
						win = {
							left: $(window).scrollLeft(),
							top: $(window).scrollTop(),
							width: $(window).width(),
							height: $(window).height()
						},
				    b = el[0].getBoundingClientRect();

				template.find('.content').html(tip);
				$('body').append(template);

				var tb = template[0].getBoundingClientRect(),
				    w  = tb.width,
				    h  = tb.height,
				    maxX = win.width - w,
				    maxY = win.height - h;
				template.css({
					width: w,
					height: h
				});

				var p = {
					left: align == 'right' ? b.left + (b.width/2) - 9 : b.left + (b.width/2) - (tb.width/2),
					top:  b.top-h-o.arrowSize
				};

				if (aside || position == 'left' || position == 'right') {
					position = position != 'left' || position != 'right' ? 'right' : position;
					p.top = b.top + (b.height/2) - (h/2) + 2;
					p.left = b.left - w - o.arrowSize;
					if (p.left > maxX) {
						p.left = b.right + o.arrowSize;
						position = 'left';
					} else if (p.left < 0 || position == 'right') {
						p.left = b.right + o.arrowSize;
					}
				} else {
					if (align == 'center') {
						arrow.css({left: (tb.width/2)-o.arrowSize});
					}
					if (p.left > maxX) {
						arrow.css({left: p.left-maxX+o.arrowSize});
						p.left = maxX;
					} else if (p.left < 0) {
						p.left = 0;
					}
					if (p.top > maxY) {
						p.top = maxY;
					} else if (p.top < 0 || position == 'bottom') {
						p.top = b.bottom + o.arrowSize;
						position = 'bottom';
					}
				}

				position = position == 'auto' ? 'top' : position;
				template.addClass(position);

				if (follow) {
					p = this.calculatePos(position, p, tb, win, align, e);

					$(this.o.parent).on('mousemove.tip', function(e) {
						p = self.calculatePos(position, p, tb, win, align, e);
						template[0].style.left = p.left+'px';
						template[0].style.top = p.top+'px';
					});
				}

				template.css({left: p.left, top: p.top, visibility: 'visible'});
			}
		},

		calculatePos: function(position, p, tb, win, align, e) {
			if (position == 'top' || position == 'bottom') {
				if (this.v.follow.x) {
					p.left = align == 'right' ? (e.pageX - win.left - 9) : (e.pageX - win.left - (tb.width/2));
				}
				if (this.v.follow.y) {
					p.top = e.pageY - tb.height - win.top - 9;
					p.top += p.top < 0 ? h*2 : 0;
				}
			} else {
				if (v.follow.x) {
					p.left = e.pageX - win.left + 9;
				}
				if (v.follow.y) {
					p.top = e.pageY - (tb.height/2) - win.top + 2;
				}
			}
			return p;
		},

		destroy: function() {
			$(this.o.parent).off('.tip');
			$('#tip').remove();
		},

		trigger: function(name) {
			var args = Array.prototype.slice.call(arguments, 1);
			if (this[name]) {
				if (this[name].apply(this, args) === false)
					return false;
			}
			return true;
		}
	};

}));
<commit_msg>Missed one variable.<commit_after>/**
 * Tiny simplistic tooltip plugin for jQuery
 * version 0.1.1
 * Kane Cohen [KaneCohen@gmail.com] | https://github.com/KaneCohen
 * @preserve
 */
(function(factory) {
	if (typeof define === 'function' && define.amd) {
		define(['jquery'], factory);
	} else {
		factory(jQuery);
	}
}(function($) {
	$.fn.tip = function(options) {
		var args = arguments,
		    o = $.extend(true, {}, options);

		var tip = $(o.parent || document).data('tip');
		o.selector = this.selector || '.tip';
		if (tip) {
			tip.trigger.apply(tip, args);
		} else {
			new Tip(o);
		}
		return this;
	};

	function Tip(o) {
		this.init(o);
	}

	Tip.prototype = {
		o: {},
		d: {
			parent:   null,   // Object to bind listeners to.
			showTime: 200,
			hideTime: 1000,
			arrowSize: 5,
			follow:   false,   // Follow mouse. Values: 'x', 'y', 'xy', false.
			position: 'auto',  // top, bottom, left, right, auto.
			align:    'right', // center, right
			aside:    false,   // Place tooltip to the left/right based on "position" option. true, false.
			selector: '.tip',
			tpl: '
' +
				'

' +
				'' +
			'
'
		},
		v: {},
		dv: {
			timer: null,
			enter: null,
			active: false,
			follow: {
				x: false,
				y: false
			}
		},
		init: function(o) {
			this.o = $.extend({}, this.d, o);
			this.v = $.extend({}, this.dv);
			this.o.parent = o.parent || document;
			this.initEvents();
			$(this.o.parent).data('tip', this);
		},

		initEvents: function() {
			var self = this;
			$(this.o.parent).on('mouseover.tip', this.o.selector, function(e) {
				var el = $(this);
				if (! el.data('tip') && el.attr('title')) {
					el.attr('data-tip', $.trim(el.attr('title')));
				}
				el.removeAttr('title');
				$('#tip').remove();
				clearTimeout(self.v.timer);
				clearTimeout(self.v.enter);
				if (self.v.active) {
					self.show(e, el);
				} else {
					self.v.timer = setTimeout(function() {
						self.v.active = true;
						self.show(e, el);
					}, self.o.showTime);
				}
			});

			$(this.o.parent).on('mouseout.tip mousedown.tip', self.o.selector+', #tip', function() {
				$(self.o.parent).off('mousemove.tip');
				$('#tip').remove();
				clearTimeout(self.v.timer);
				clearTimeout(self.v.enter);
				self.v.enter = setTimeout(function() {
					self.v.active = false;
				}, self.o.hideTime);
			});
		},

		show: function(e, el) {
			var self = this,
			    o    = this.o,
			    v    = this.v,
			    tip  = $.trim(el.data('tip')),
			    follow   = el.data('tipFollow') || o.follow,
			    align    = el.data('tipAlign') || o.align,
			    aside    = el.data('tipAside') || o.aside,
			    position = el.data('tipPosition') || o.position;

			if (follow) {
				v.follow.x = follow.indexOf('x') >= 0;
				v.follow.y = follow.indexOf('y') >= 0;
			}

			if (tip !== null && tip.length !== 0) {
				var template = $(self.o.tpl),
				    arrow = template.find('.arrow'),
						win = {
							left: $(window).scrollLeft(),
							top: $(window).scrollTop(),
							width: $(window).width(),
							height: $(window).height()
						},
				    b = el[0].getBoundingClientRect();

				template.find('.content').html(tip);
				$('body').append(template);

				var tb = template[0].getBoundingClientRect(),
				    w  = tb.width,
				    h  = tb.height,
				    maxX = win.width - w,
				    maxY = win.height - h;
				template.css({
					width: w,
					height: h
				});

				var p = {
					left: align == 'right' ? b.left + (b.width/2) - 9 : b.left + (b.width/2) - (tb.width/2),
					top:  b.top-h-o.arrowSize
				};

				if (aside || position == 'left' || position == 'right') {
					position = position != 'left' || position != 'right' ? 'right' : position;
					p.top = b.top + (b.height/2) - (h/2) + 2;
					p.left = b.left - w - o.arrowSize;
					if (p.left > maxX) {
						p.left = b.right + o.arrowSize;
						position = 'left';
					} else if (p.left < 0 || position == 'right') {
						p.left = b.right + o.arrowSize;
					}
				} else {
					if (align == 'center') {
						arrow.css({left: (tb.width/2)-o.arrowSize});
					}
					if (p.left > maxX) {
						arrow.css({left: p.left-maxX+o.arrowSize});
						p.left = maxX;
					} else if (p.left < 0) {
						p.left = 0;
					}
					if (p.top > maxY) {
						p.top = maxY;
					} else if (p.top < 0 || position == 'bottom') {
						p.top = b.bottom + o.arrowSize;
						position = 'bottom';
					}
				}

				position = position == 'auto' ? 'top' : position;
				template.addClass(position);

				if (follow) {
					p = this.calculatePos(position, p, tb, win, align, e);

					$(this.o.parent).on('mousemove.tip', function(e) {
						p = self.calculatePos(position, p, tb, win, align, e);
						template[0].style.left = p.left+'px';
						template[0].style.top = p.top+'px';
					});
				}

				template.css({left: p.left, top: p.top, visibility: 'visible'});
			}
		},

		calculatePos: function(position, p, tb, win, align, e) {
			if (position == 'top' || position == 'bottom') {
				if (this.v.follow.x) {
					p.left = align == 'right' ? (e.pageX - win.left - 9) : (e.pageX - win.left - (tb.width/2));
				}
				if (this.v.follow.y) {
					p.top = e.pageY - tb.height - win.top - 9;
					p.top += p.top < 0 ? tb.height * 2 : 0;
				}
			} else {
				if (v.follow.x) {
					p.left = e.pageX - win.left + 9;
				}
				if (v.follow.y) {
					p.top = e.pageY - (tb.height/2) - win.top + 2;
				}
			}
			return p;
		},

		destroy: function() {
			$(this.o.parent).off('.tip');
			$('#tip').remove();
		},

		trigger: function(name) {
			var args = Array.prototype.slice.call(arguments, 1);
			if (this[name]) {
				if (this[name].apply(this, args) === false)
					return false;
			}
			return true;
		}
	};

}));
<|endoftext|>


<commit_before>
// Given

this.Given(/^я нахожусь на экране "([^"]*)"$/, function (viewName, next) {
    window.testHelpers.waitView(viewName,
		function () {
		    window.currentView = window.configWindow.contextApp.getChildView(viewName);
		    window.currentViewContext = window.currentView.getContext();
		    next();
		},
		function () {
		    next(new Error(viewName + ' not found'));
		}
	);
});

// Then

this.Then(/^система отобразит экран "([^"]*)"$/, function (viewName, next) {
    window.testHelpers.waitView(viewName,
		function () {
		    window.currentView = window.configWindow.contextApp.getChildView(viewName);
		    window.currentViewContext = window.currentView.getContext();
		    next();
		},
		function () {
		    next(new Error(viewName + ' not found'));
		}
	);
});

this.Then(/^система отобразит окно-сообщение "([^"]*)"$/, function (message, next) {
    var hasMessageBox = function () {
        return (window.configWindow.$.find('.messagebox:visible').length > 0);
    };

    var checkMessageText = function () {
        var messageBody = window.configWindow.$.find('.messagebox:visible > .modal-body');
        var text = $.trim($(messageBody).text());

        try {
            chai.assert.equal(text, message);
            next();
        } catch (err) {
            next(err);
        }
    };

    var fail = function () {
        next(new Error('MessageBox not found'));
    };

    window.testHelpers.waitCondition(hasMessageBox, checkMessageText, fail);
});

this.Then(/^система отобразит список кнопок: (.*?)$/, function (values, next) {
    var extValues = values
						.split(",")
						.map(function (item) {
						    var result = item.trim();
						    return result.substring(1, result.length - 1); //Удаляются кавычки
						});

    var actValues = window.configWindow.$(".btn-group.open .dropdown-menu > li .btntext")
					.map(function (index, item) {
					    return $(item).text();
					})
					.toArray();

    try{
		chai.assert.deepEqual(actValues, extValues);
		next();
	}catch(err){
		next(err);
	}
});

this.Then(/^система отобразит модальное окно "([^"]*)"$/, function (dialogView, next) {
    window.testHelpers.waitModalView(dialogView,
		function () {
		    window.currentView = window.currentView.getChildView(dialogView) || window.configWindow.contextApp.getChildView(dialogView);
		    window.currentViewContext = window.currentView.getContext();
		    next();
		},
		function () {
		    next(new Error(dialogView + ' not found'));
		}
	);
});

this.Then(/^система отобразит значения выпадающего списка: (.*?)$/, function (values, next) {
    var extValues = values
						.split(",")
						.map(function (item) {
						    var result = item.trim();
						    return result.substring(1, result.length - 1); //Удаляются кавычки
						});

    var actValues = window.configWindow.$(".select2-results > li .select2-result-label")
					.map(function (index, item) {
					    return $(item).text();
					})
					.toArray();

    try{
		chai.assert.deepEqual(actValues, extValues);
    	next();
	}catch(err){
	    next(err);
	}
});

this.Then(/^система отобразит список валидационных сообщений: (.*?)$/, function(msgs, next){
	var haveToastr = function(){
		return window.configWindow.$("#toast-container") !== null;
	};
	var success = function(){
		var actual = window.configWindow.$("#toast-container .toast-message");
		var actualMessages = [];
		for(var i = 0;i < actual.length;i++){
			actualMessages.push(actual[i].innerHTML);
		}
		var messages = msgs.split(',').map(function(item){
			var result = item.trim();
			return result.substring(1, result.length - 1).replace(/'/g, '"')
		});

		try{
			chai.assert.deepEqual(actualMessages, messages);
			next();
		}catch(err){
			next(err);
		}
	};
	var fail = function(){
		next(new Error("Окно не найдено"));
	};
	window.testHelpers.waitCondition(haveToastr, success, fail);
});

this.Then(/^система не отобразит валидационных сообщений$/, function(next){
	var haveToastr = function(){
		return 	window.configWindow.$("#toast-container") !== null &&
				window.configWindow.$("#toast-container").length != 0;
	};
	var success = function(){
		next();
	}
	var fail = function(){
		next(new Error("Было обнаружено одно или несколько окон"));
	};

	window.testHelpers.waitCondition(haveToastr, fail, success, 3000, 500);
});
<commit_msg>PC-2287: Написать конструкция для закрытия модального окна #resolved<commit_after>
// Given

this.Given(/^я нахожусь на экране "([^"]*)"$/, function (viewName, next) {
    window.testHelpers.waitView(viewName,
		function () {
		    window.currentView = window.configWindow.contextApp.getChildView(viewName);
		    window.currentViewContext = window.currentView.getContext();
		    next();
		},
		function () {
		    next(new Error(viewName + ' not found'));
		}
	);
});

// Then

this.Then(/^система отобразит экран "([^"]*)"$/, function (viewName, next) {
    window.testHelpers.waitView(viewName,
		function () {
		    window.currentView = window.configWindow.contextApp.getChildView(viewName);
		    window.currentViewContext = window.currentView.getContext();
		    next();
		},
		function () {
		    next(new Error(viewName + ' not found'));
		}
	);
});

this.Then(/^система отобразит окно-сообщение "([^"]*)"$/, function (message, next) {
    var hasMessageBox = function () {
        return (window.configWindow.$.find('.messagebox:visible').length > 0);
    };

    var checkMessageText = function () {
        var messageBody = window.configWindow.$.find('.messagebox:visible > .modal-body');
        var text = $.trim($(messageBody).text());

        try {
            chai.assert.equal(text, message);
            next();
        } catch (err) {
            next(err);
        }
    };

    var fail = function () {
        next(new Error('MessageBox not found'));
    };

    window.testHelpers.waitCondition(hasMessageBox, checkMessageText, fail);
});

this.Then(/^система отобразит список кнопок: (.*?)$/, function (values, next) {
    var extValues = values
						.split(",")
						.map(function (item) {
						    var result = item.trim();
						    return result.substring(1, result.length - 1); //Удаляются кавычки
						});

    var actValues = window.configWindow.$(".btn-group.open .dropdown-menu > li .btntext")
					.map(function (index, item) {
					    return $(item).text();
					})
					.toArray();

    try{
		chai.assert.deepEqual(actValues, extValues);
		next();
	}catch(err){
		next(err);
	}
});

this.Then(/^система отобразит модальное окно "([^"]*)"$/, function (dialogView, next) {
    window.testHelpers.waitModalView(dialogView,
		function () {
		    window.currentView = window.currentView.getChildView(dialogView) || window.configWindow.contextApp.getChildView(dialogView);
		    window.currentViewContext = window.currentView.getContext();
		    next();
		},
		function () {
		    next(new Error(dialogView + ' not found'));
		}
	);
});

this.When(/^я закрою текущее модальное окно$/, function(next){
	if(window.currentView.close != undefined){
		window.currentView.close();
		next();
	}else{
		next(new Error('Method close() not found!'));
	}
});

this.Then(/^система отобразит значения выпадающего списка: (.*?)$/, function (values, next) {
    var extValues = values
						.split(",")
						.map(function (item) {
						    var result = item.trim();
						    return result.substring(1, result.length - 1); //Удаляются кавычки
						});

    var actValues = window.configWindow.$(".select2-results > li .select2-result-label")
					.map(function (index, item) {
					    return $(item).text();
					})
					.toArray();

    try{
		chai.assert.deepEqual(actValues, extValues);
    	next();
	}catch(err){
	    next(err);
	}
});

this.Then(/^система отобразит список валидационных сообщений: (.*?)$/, function(msgs, next){
	var haveToastr = function(){
		return window.configWindow.$("#toast-container") !== null;
	};
	var success = function(){
		var actual = window.configWindow.$("#toast-container .toast-message");
		var actualMessages = [];
		for(var i = 0;i < actual.length;i++){
			actualMessages.push(actual[i].innerHTML);
		}
		var messages = msgs.split(',').map(function(item){
			var result = item.trim();
			return result.substring(1, result.length - 1).replace(/'/g, '"')
		});

		try{
			chai.assert.deepEqual(actualMessages, messages);
			next();
		}catch(err){
			next(err);
		}
	};
	var fail = function(){
		next(new Error("Окно не найдено"));
	};
	window.testHelpers.waitCondition(haveToastr, success, fail);
});

this.Then(/^система не отобразит валидационных сообщений$/, function(next){
	var haveToastr = function(){
		return 	window.configWindow.$("#toast-container") !== null &&
				window.configWindow.$("#toast-container").length != 0;
	};
	var success = function(){
		next();
	}
	var fail = function(){
		next(new Error("Было обнаружено одно или несколько окон"));
	};

	window.testHelpers.waitCondition(haveToastr, fail, success, 3000, 500);
});
<|endoftext|>


<commit_before>const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    name: {
        first: String,
        last: String
    },
    accessToken: String
});

module.exports = mongoose.model('User', userSchema);<commit_msg>Add id.<commit_after>const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    id: Number,
    firstName: String,
    lastName: String,
    accessToken: String
});

module.exports = mongoose.model('User', userSchema);<|endoftext|>


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

var program = require("commander");
var path = require("path");
var fs = require("fs")
var optinPackage = require(path.join(__dirname, "../", "package.json"));
var q = require("q");
/* commands */

var loadCommand = function(cmd) {
    var self = this;
    return function() {
        require("../lib/" + cmd)
            .apply(self, arguments);
    }
}
program
    .version(optinPackage.version)
    .usage(" - " + optinPackage.description)
    .description(optinPackage.description)
    .option("-o --option [value]", "generic option")

program
    .command("host <variation_id> [port]")
    .description("Host")
    .action(loadCommand("host"));

program
    .command("init [project_description]")
    .description("Initialize an optimizely project.")
    .option("-r --remote", "Initialize project remotely as well as locally.")
    .option("-p --pull", "Pull project by initializing")
    .option("-j --jquery", "Include Jquery (new project)")
    .option("-a --archive", "Archive (new project)")
    .option("-e --experiments", "Download experiments.")
    .option("-v --variations", "Download variations. (Implies --experiments)")
    .action(loadCommand("init-project"));

program
    .command("experiment <description> <url> [variation_descriptions]")
    .description("Create Experiment Host")
    .option("-r --remote", "Create experiment remotely as well as locally.")
    .action(loadCommand("create-experiment"));

program
    .command("variation <experiment> <descriptions>")
    .description("Create Experiment Host")
    .option("-r --remote", "Create experiment remotely as well as locally.")
    .action(loadCommand("create-variation"));

/*
program
    .command("list <experiment> <descriptions>")
    .description("List all experiments and variations")
    .option("-r --remote", "Include remote experiments and variations")
    .action(loadCommand("list"));

program
    .command("push <experiment>")
    .description("Synchronize experiments and variations")
    .action(loadCommand("push"));

program
.command("experiment <description> [variation_descriptions...]")
.description("Create an experiment")
.option("-r --remote", "Initialize experiment remotely as well as locally.")
.action(loadCommand("init-project"));

program
.command("variation <experiment> [description]")
.description("Create a variation")
.option("-r --remote", "Initialize variation remotely as well as locally.")
.action(loadCommand("init-project"));

program
.command("list")
.description("List experiments and variations")
.option("-r --remote", "List remote projects as well as local experiments.")
.action(loadCommand("init-project"));

program
.command("status")
.description("Show project status")
.option("-r --remote", "Also show remote project status.")
.action(loadCommand("init-project"));

program
.command("sync [id]")
.description("Sync objects")
.option("-u --upstream", "Sync upstream")
.option("-d --downstream", "Sync downstream")
.action(loadCommand("init-project"));

program
.command("asset <path> [name]")
.description("Sync objects")
.option("-u --upstream", "Sync upstream")
.option("-d --downstream", "Sync downstream")
.action(loadCommand("init-project"));

program
    .command("set-token [token]")
    .description("Set Optimizely API Token")
    .action(loadCommand("set-token"));

program
    .command("push-variation <path>")
    .description("Add a variation to an experiment.")
    .action(loadCommand("push-variations"));

program
    .command("open-variation <variation_id>")
    .description("Add a variation to an experiment.")
    .action(loadCommand("open-variation"));

program
    .command("server [port]")
    .description("Start Installation Server")
    .action(loadCommand("server"));
    */

/*
program
.command("")
.description("")
.action(function(arg) {
    program.help();
});
*/

program
    .command("*")
    .description("")
    .action(function(arg) {
        console.log("invalid command: '%s'", arg);
        program.help();
    });

program.parse(process.argv);
<commit_msg>Modified Descriptions<commit_after>#!/usr/bin/env node

var program = require("commander");
var path = require("path");
var fs = require("fs")
var optinPackage = require(path.join(__dirname, "../", "package.json"));
var q = require("q");
/* commands */

var loadCommand = function(cmd) {
    var self = this;
    return function() {
        require("../lib/" + cmd)
            .apply(self, arguments);
    }
}
program
    .version(optinPackage.version)
    .usage(" - " + optinPackage.description)
    .description(optinPackage.description)
    .option("-o --option [value]", "generic option")

program
    .command("host <variation_id> [port]")
    .description("Host Variations")
    .action(loadCommand("host"));

program
    .command("init [project_description]")
    .description("Initialize an optimizely project.")
    .option("-r --remote", "Initialize project remotely as well as locally.")
    .option("-p --pull", "Pull project by initializing")
    .option("-j --jquery", "Include Jquery (new project)")
    .option("-a --archive", "Archive (new project)")
    .option("-e --experiments", "Download experiments.")
    .option("-v --variations", "Download variations. (Implies --experiments)")
    .action(loadCommand("init-project"));

program
    .command("experiment <description> <url> [variation_descriptions]")
    .description("Create Variation")
    .option("-r --remote", "Create experiment remotely as well as locally.")
    .action(loadCommand("create-experiment"));

program
    .command("variation <experiment> <descriptions>")
    .description("Create Experiment")
    .option("-r --remote", "Create variation remotely as well as locally.")
    .action(loadCommand("create-variation"));

/*
program
    .command("list <experiment> <descriptions>")
    .description("List all experiments and variations")
    .option("-r --remote", "Include remote experiments and variations")
    .action(loadCommand("list"));

program
    .command("push <experiment>")
    .description("Synchronize experiments and variations")
    .action(loadCommand("push"));

program
.command("experiment <description> [variation_descriptions...]")
.description("Create an experiment")
.option("-r --remote", "Initialize experiment remotely as well as locally.")
.action(loadCommand("init-project"));

program
.command("variation <experiment> [description]")
.description("Create a variation")
.option("-r --remote", "Initialize variation remotely as well as locally.")
.action(loadCommand("init-project"));

program
.command("list")
.description("List experiments and variations")
.option("-r --remote", "List remote projects as well as local experiments.")
.action(loadCommand("init-project"));

program
.command("status")
.description("Show project status")
.option("-r --remote", "Also show remote project status.")
.action(loadCommand("init-project"));

program
.command("sync [id]")
.description("Sync objects")
.option("-u --upstream", "Sync upstream")
.option("-d --downstream", "Sync downstream")
.action(loadCommand("init-project"));

program
.command("asset <path> [name]")
.description("Sync objects")
.option("-u --upstream", "Sync upstream")
.option("-d --downstream", "Sync downstream")
.action(loadCommand("init-project"));

program
    .command("set-token [token]")
    .description("Set Optimizely API Token")
    .action(loadCommand("set-token"));

program
    .command("push-variation <path>")
    .description("Add a variation to an experiment.")
    .action(loadCommand("push-variations"));

program
    .command("open-variation <variation_id>")
    .description("Add a variation to an experiment.")
    .action(loadCommand("open-variation"));

program
    .command("server [port]")
    .description("Start Installation Server")
    .action(loadCommand("server"));
    */

/*
program
.command("")
.description("")
.action(function(arg) {
    program.help();
});
*/

program
    .command("*")
    .description("")
    .action(function(arg) {
        console.log("invalid command: '%s'", arg);
        program.help();
    });

program.parse(process.argv);
<|endoftext|>


<commit_before>/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
 * full list of contributors). Published under the 2-clause BSD license.
 * See license.txt in the OpenLayers distribution or repository for the
 * full text of the license. */

/**
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Handler/Drag.js
 */

/**
 * Class: OpenLayers.Control.DragPan
 * The DragPan control pans the map with a drag of the mouse.
 *
 * Inherits from:
 *  - <OpenLayers.Control>
 */
OpenLayers.Control.DragPan = OpenLayers.Class(OpenLayers.Control, {

    /**
     * Property: type
     * {OpenLayers.Control.TYPES}
     */
    type: OpenLayers.Control.TYPE_TOOL,

    /**
     * Property: panned
     * {Boolean} The map moved.
     */
    panned: false,

    /**
     * Property: interval
     * {Integer} The number of milliseconds that should ellapse before
     *     panning the map again. Defaults to 1 millisecond. In most cases
     *     you won't want to change this value. For slow machines/devices
     *     larger values can be tried out.
     */
    interval: 1,

    /**
     * APIProperty: documentDrag
     * {Boolean} If set to true, mouse dragging will continue even if the
     *     mouse cursor leaves the map viewport. Default is false.
     */
    documentDrag: false,

    /**
     * Property: kinetic
     * {<OpenLayers.Kinetic>} The OpenLayers.Kinetic object.
     */
    kinetic: null,

    /**
     * APIProperty: enableKinetic
     * {Boolean} Set this option to enable "kinetic dragging". Can be
     *     set to true or to an object. If set to an object this
     *     object will be passed to the {<OpenLayers.Kinetic>}
     *     constructor. Defaults to true.
     *     To get kinetic dragging, ensure that OpenLayers/Kinetic.js is
     *     included in your build config.
     */
    enableKinetic: true,

    /**
     * APIProperty: kineticInterval
     * {Integer} Interval in milliseconds between 2 steps in the "kinetic
     *     scrolling". Applies only if enableKinetic is set. Defaults
     *     to 10 milliseconds.
     */
    kineticInterval: 10,

    /**
     * Method: draw
     * Creates a Drag handler, using <panMap> and
     * <panMapDone> as callbacks.
     */
    draw: function() {
        if (this.enableKinetic && OpenLayers.Kinetic) {
            var config = {interval: this.kineticInterval};
            if(typeof this.enableKinetic === "object") {
                config = OpenLayers.Util.extend(config, this.enableKinetic);
            }
            this.kinetic = new OpenLayers.Kinetic(config);
        }
        this.handler = new OpenLayers.Handler.Drag(this, {
                "move": this.panMap,
                "done": this.panMapDone,
                "down": this.panMapStart
            }, {
                interval: this.interval,
                documentDrag: this.documentDrag
            }
        );
    },

    /**
     * Method: panMapStart
     */
    panMapStart: function() {
        if(this.kinetic) {
            this.kinetic.begin();
        }
    },

    /**
    * Method: panMap
    *
    * Parameters:
    * xy - {<OpenLayers.Pixel>} Pixel of the mouse position
    */
    panMap: function(xy) {
        if(this.kinetic) {
            this.kinetic.update(xy);
        }
        this.panned = true;
        this.map.pan(
            this.handler.last.x - xy.x,
            this.handler.last.y - xy.y,
            {dragging: true, animate: false}
        );
    },

    /**
     * Method: panMapDone
     * Finish the panning operation.  Only call setCenter (through <panMap>)
     *     if the map has actually been moved.
     *
     * Parameters:
     * xy - {<OpenLayers.Pixel>} Pixel of the mouse position
     */
    panMapDone: function(xy) {
        if(this.panned) {
            var res = null;
            if (this.kinetic) {
                res = this.kinetic.end(xy);
            }
            this.map.pan(
                this.handler.last.x - xy.x,
                this.handler.last.y - xy.y,
                {dragging: !!res, animate: false}
            );
            if (res) {
                var self = this;
                this.kinetic.move(res, function(x, y, end) {
                    self.map.pan(x, y, {dragging: !end, animate: false});
                });
            }
            this.panned = false;
        }
    },

    CLASS_NAME: "OpenLayers.Control.DragPan"
});
<commit_msg>Drag interval of 0 (i.e. no separate cycle) seems appropriate now<commit_after>/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
 * full list of contributors). Published under the 2-clause BSD license.
 * See license.txt in the OpenLayers distribution or repository for the
 * full text of the license. */

/**
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Handler/Drag.js
 */

/**
 * Class: OpenLayers.Control.DragPan
 * The DragPan control pans the map with a drag of the mouse.
 *
 * Inherits from:
 *  - <OpenLayers.Control>
 */
OpenLayers.Control.DragPan = OpenLayers.Class(OpenLayers.Control, {

    /**
     * Property: type
     * {OpenLayers.Control.TYPES}
     */
    type: OpenLayers.Control.TYPE_TOOL,

    /**
     * Property: panned
     * {Boolean} The map moved.
     */
    panned: false,

    /**
     * Property: interval
     * {Integer} The number of milliseconds that should ellapse before
     *     panning the map again. Defaults to 0 milliseconds, which means that
     *     no separate cycle is used for panning. In most cases you won't want
     *     to change this value. For slow machines/devices larger values can be
     *     tried out.
     */
    interval: 0,

    /**
     * APIProperty: documentDrag
     * {Boolean} If set to true, mouse dragging will continue even if the
     *     mouse cursor leaves the map viewport. Default is false.
     */
    documentDrag: false,

    /**
     * Property: kinetic
     * {<OpenLayers.Kinetic>} The OpenLayers.Kinetic object.
     */
    kinetic: null,

    /**
     * APIProperty: enableKinetic
     * {Boolean} Set this option to enable "kinetic dragging". Can be
     *     set to true or to an object. If set to an object this
     *     object will be passed to the {<OpenLayers.Kinetic>}
     *     constructor. Defaults to true.
     *     To get kinetic dragging, ensure that OpenLayers/Kinetic.js is
     *     included in your build config.
     */
    enableKinetic: true,

    /**
     * APIProperty: kineticInterval
     * {Integer} Interval in milliseconds between 2 steps in the "kinetic
     *     scrolling". Applies only if enableKinetic is set. Defaults
     *     to 10 milliseconds.
     */
    kineticInterval: 10,

    /**
     * Method: draw
     * Creates a Drag handler, using <panMap> and
     * <panMapDone> as callbacks.
     */
    draw: function() {
        if (this.enableKinetic && OpenLayers.Kinetic) {
            var config = {interval: this.kineticInterval};
            if(typeof this.enableKinetic === "object") {
                config = OpenLayers.Util.extend(config, this.enableKinetic);
            }
            this.kinetic = new OpenLayers.Kinetic(config);
        }
        this.handler = new OpenLayers.Handler.Drag(this, {
                "move": this.panMap,
                "done": this.panMapDone,
                "down": this.panMapStart
            }, {
                interval: this.interval,
                documentDrag: this.documentDrag
            }
        );
    },

    /**
     * Method: panMapStart
     */
    panMapStart: function() {
        if(this.kinetic) {
            this.kinetic.begin();
        }
    },

    /**
    * Method: panMap
    *
    * Parameters:
    * xy - {<OpenLayers.Pixel>} Pixel of the mouse position
    */
    panMap: function(xy) {
        if(this.kinetic) {
            this.kinetic.update(xy);
        }
        this.panned = true;
        this.map.pan(
            this.handler.last.x - xy.x,
            this.handler.last.y - xy.y,
            {dragging: true, animate: false}
        );
    },

    /**
     * Method: panMapDone
     * Finish the panning operation.  Only call setCenter (through <panMap>)
     *     if the map has actually been moved.
     *
     * Parameters:
     * xy - {<OpenLayers.Pixel>} Pixel of the mouse position
     */
    panMapDone: function(xy) {
        if(this.panned) {
            var res = null;
            if (this.kinetic) {
                res = this.kinetic.end(xy);
            }
            this.map.pan(
                this.handler.last.x - xy.x,
                this.handler.last.y - xy.y,
                {dragging: !!res, animate: false}
            );
            if (res) {
                var self = this;
                this.kinetic.move(res, function(x, y, end) {
                    self.map.pan(x, y, {dragging: !end, animate: false});
                });
            }
            this.panned = false;
        }
    },

    CLASS_NAME: "OpenLayers.Control.DragPan"
});
<|endoftext|>