<commit_before>/*
* jQuery QueryBuilder Elasticsearch 'bool' query support
* https://github.com/mistic100/jQuery-QueryBuilder
* https://www.elastic.co/
* https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html
*/

// Register plugin
(function(root, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['jquery', 'query-builder'], factory);
    }
    else {
        factory(root.jQuery);
    }
}(this, function($) {
    "use strict";

    var QueryBuilder = $.fn.queryBuilder;

    // DEFAULT CONFIG
    // ===============================
    QueryBuilder.defaults({
        ESBoolOperators: {
            equal:            function(v){ return v; },
            not_equal:        function(v){ return v; },
            less:             function(v){ return {'lt': v}; },
            less_or_equal:    function(v){ return {'lte': v}; },
            greater:          function(v){ return {'gt': v}; },
            greater_or_equal: function(v){ return {'gte': v}; },
            between:          function(v){ return {'gte': v[0], 'lte': v[1]}; },
            in :              function(v){ return v.split(',').map(function(e) { return e.trim();}); },
            not_in:           function(v){ return v.split(',').map(function(e) { return e.trim();}); },
            contains:         function(v){ return v; }
        },
        ESQueryStringQueryOperators: {
            is_not_null:           function(){ return "_exists_:"; },
            is_null:          function(){ return "_missing_:";},
            contains:         function(v){ return v; },
            between:          function(v){ return '[' + v[0] + ' TO '+ v[1] + "]"; },
        }
    });

    // PUBLIC METHODS
    // ===============================
    QueryBuilder.extend({
        /**
        * Get rules as an elasticsearch bool query
        * @param data {object} (optional) rules
        * @return {object}
        */
        getESBool: function(data) {
            data = (data===undefined) ? this.getRules() : data;

            var that = this;

            return (function parse(data) {
                if (!data.condition) {
                    data.condition = that.settings.default_condition;
                }

                if (['AND', 'OR'].indexOf(data.condition.toUpperCase()) === -1) {
                    throw new Error(
                        'Unable to build Elasticsearch bool query with condition "{0}"'
                        .replace('{0}', data.condition)
                    );
                }

                if (!data.rules) {
                    return {};
                }

                var parts = {};
                parts.add = function (k, v) {
                    if (this.hasOwnProperty(k)) { this[k].push(v) }
                    else { this[k] = [v] }
                };

                data.rules.forEach(function(rule) {

                    function get_value(rule) {
                        if (rule.data && rule.data.hasOwnProperty('transform')) {
                            return window[rule.data.transform].call(this, rule.value);
                        } else {
                            return rule.value;
                        }
                    }

                    function make_query(rule) {
                        var mdb = that.settings.ESBoolOperators[rule.operator],
                        ope = that.getOperatorByType(rule.operator),
                        part = {};

                        if (mdb === undefined) {
                            throw new Error(
                                'Unknown elasticsearch operation for operator "{0}"'
                                .replace('{0}', rule.operator)
                            );
                        }

                        if (ope.nb_inputs !== 0) {
                            var es_key_val = {};
                            es_key_val[rule.field] =  mdb.call(that, get_value(rule));
                            part[getQueryDSLWord(rule)] = es_key_val;
                        }

                        // this is a corner case, when we have an "or" group and a negative operator,
                        // we express this with a sub boolean query and must_not.
                        if (data.condition === 'OR' && (rule.operator === 'not_equal' || rule.operator === 'not_in')) {
                            return {'bool': {'must_not': [part]}}
                        } else {
                            return part
                        }
                    }

                    var clause = getClauseWord(data.condition, rule.operator);

                    if (rule.rules && rule.rules.length>0) {
                        parts.add(clause, parse(rule));
                    } else {
                        parts.add(clause, make_query(rule));
                    }

                });

                delete parts.add;
                return {'bool': parts}
            }(data));
        },

        /**
        * Get rules as an elasticsearch query string query
        * @param data {object} (optional) rules
        * @return {object}
        */
        getESQueryStringQuery: function(data) {
            data = (data===undefined) ? this.getRules() : data;

            var that = this;

            return (function parse(data) {
                if (!data.condition) {
                    data.condition = that.settings.default_condition;
                }

                if (['AND', 'OR'].indexOf(data.condition.toUpperCase()) === -1) {
                    throw new Error(
                        'Unable to build Elasticsearch query String query with condition "{0}"'
                        .replace('{0}', data.condition)
                    );
                }

                if (!data.rules) {
                    return "";
                }

                // generate query string
                var parts = "";

                data.rules.forEach(function(rule, index) {
                    function get_value(rule) {
                            return rule.value;
                    }

                    function make_query(rule) {
                        var mdb = that.settings.ESQueryStringQueryOperators[rule.operator],
                        ope = that.getOperatorByType(rule.operator),
                        part = "";

                        if (mdb === undefined) {
                            throw new Error(
                                'Unknown elasticsearch operation for operator "{0}"'
                                .replace('{0}', rule.operator)
                            );
                        }

                        var es_key_val = "";
                        if (ope.nb_inputs !== 0) {
                            es_key_val += rule.field + ":" + mdb.call(that, rule.value);
                            part += es_key_val;
                        }
                        else if (ope.nb_inputs === 0) {
                            es_key_val += mdb.call(that, rule.value) + rule.field;
                            part += es_key_val;
                        }

                        if(data.rules[index+1]) {
                            return part + " " + data.condition + " ";
                        }
                        else {
                            return part;
                        }

                    }
                    if (rule.rules && rule.rules.length>0) {
                        parts += "(" + parse(rule) + ")";
                    } else {
                        parts += make_query(rule);
                    }

                });
                return parts;
            }(data));
        }
    });

    /**
    * Get the right type of query term in elasticsearch DSL
    */
    function getQueryDSLWord(rule) {
        var term = /^(equal|not_equal)$/.exec(rule.operator),
            wildcard = /.(\*|\?)/.exec(rule.value),
            terms = /^(in|not_in)$/.exec(rule.operator);

        if (term !== null && wildcard !== null) { return 'wildcard'; }
        if (term !== null) { return 'term'; }
        if (terms !== null) { return 'terms'; }
        return 'range';
    }

    /**
    * Get the right type of clause in the bool query
    */
    function getClauseWord(condition, operator) {
        if (condition === 'AND' && (operator !== 'not_equal' && operator !== 'not_in')) { return 'must' }
        if (condition === 'AND' && (operator === 'not_equal' || operator == 'not_in')) { return 'must_not' }
        if (condition === 'OR') { return 'should' }
    }

}));
<commit_msg>Revert "Update query-builder-elasticsearch.js"<commit_after>/*
* jQuery QueryBuilder Elasticsearch 'bool' query support
* https://github.com/mistic100/jQuery-QueryBuilder
* https://www.elastic.co/
* https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html
*/

// Register plugin
(function(root, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['jquery', 'query-builder'], factory);
    }
    else {
        factory(root.jQuery);
    }
}(this, function($) {
    "use strict";

    var QueryBuilder = $.fn.queryBuilder;

    // DEFAULT CONFIG
    // ===============================
    QueryBuilder.defaults({
        ESBoolOperators: {
            equal:            function(v){ return v; },
            not_equal:        function(v){ return v; },
            less:             function(v){ return {'lt': v}; },
            less_or_equal:    function(v){ return {'lte': v}; },
            greater:          function(v){ return {'gt': v}; },
            greater_or_equal: function(v){ return {'gte': v}; },
            between:          function(v){ return {'gte': v[0], 'lte': v[1]}; },
            in :              function(v){ return v.split(',').map(function(e) { return e.trim();}); },
            not_in:           function(v){ return v.split(',').map(function(e) { return e.trim();}); }
        },
        ESQueryStringQueryOperators: {
            is_not_null:           function(){ return "_exists_:"; },
            is_null:          function(){ return "_missing_:";},
            contains:         function(v){ return v; },
            between:          function(v){ return '[' + v[0] + ' TO '+ v[1] + "]"; },
        }
    });

    // PUBLIC METHODS
    // ===============================
    QueryBuilder.extend({
        /**
        * Get rules as an elasticsearch bool query
        * @param data {object} (optional) rules
        * @return {object}
        */
        getESBool: function(data) {
            data = (data===undefined) ? this.getRules() : data;

            var that = this;

            return (function parse(data) {
                if (!data.condition) {
                    data.condition = that.settings.default_condition;
                }

                if (['AND', 'OR'].indexOf(data.condition.toUpperCase()) === -1) {
                    throw new Error(
                        'Unable to build Elasticsearch bool query with condition "{0}"'
                        .replace('{0}', data.condition)
                    );
                }

                if (!data.rules) {
                    return {};
                }

                var parts = {};
                parts.add = function (k, v) {
                    if (this.hasOwnProperty(k)) { this[k].push(v) }
                    else { this[k] = [v] }
                };

                data.rules.forEach(function(rule) {

                    function get_value(rule) {
                        if (rule.data && rule.data.hasOwnProperty('transform')) {
                            return window[rule.data.transform].call(this, rule.value);
                        } else {
                            return rule.value;
                        }
                    }

                    function make_query(rule) {
                        var mdb = that.settings.ESBoolOperators[rule.operator],
                        ope = that.getOperatorByType(rule.operator),
                        part = {};

                        if (mdb === undefined) {
                            throw new Error(
                                'Unknown elasticsearch operation for operator "{0}"'
                                .replace('{0}', rule.operator)
                            );
                        }

                        if (ope.nb_inputs !== 0) {
                            var es_key_val = {};
                            es_key_val[rule.field] =  mdb.call(that, get_value(rule));
                            part[getQueryDSLWord(rule)] = es_key_val;
                        }

                        // this is a corner case, when we have an "or" group and a negative operator,
                        // we express this with a sub boolean query and must_not.
                        if (data.condition === 'OR' && (rule.operator === 'not_equal' || rule.operator === 'not_in')) {
                            return {'bool': {'must_not': [part]}}
                        } else {
                            return part
                        }
                    }

                    var clause = getClauseWord(data.condition, rule.operator);

                    if (rule.rules && rule.rules.length>0) {
                        parts.add(clause, parse(rule));
                    } else {
                        parts.add(clause, make_query(rule));
                    }

                });

                delete parts.add;
                return {'bool': parts}
            }(data));
        },

        /**
        * Get rules as an elasticsearch query string query
        * @param data {object} (optional) rules
        * @return {object}
        */
        getESQueryStringQuery: function(data) {
            data = (data===undefined) ? this.getRules() : data;

            var that = this;

            return (function parse(data) {
                if (!data.condition) {
                    data.condition = that.settings.default_condition;
                }

                if (['AND', 'OR'].indexOf(data.condition.toUpperCase()) === -1) {
                    throw new Error(
                        'Unable to build Elasticsearch query String query with condition "{0}"'
                        .replace('{0}', data.condition)
                    );
                }

                if (!data.rules) {
                    return "";
                }

                // generate query string
                var parts = "";

                data.rules.forEach(function(rule, index) {
                    function get_value(rule) {
                            return rule.value;
                    }

                    function make_query(rule) {
                        var mdb = that.settings.ESQueryStringQueryOperators[rule.operator],
                        ope = that.getOperatorByType(rule.operator),
                        part = "";

                        if (mdb === undefined) {
                            throw new Error(
                                'Unknown elasticsearch operation for operator "{0}"'
                                .replace('{0}', rule.operator)
                            );
                        }

                        var es_key_val = "";
                        if (ope.nb_inputs !== 0) {
                            es_key_val += rule.field + ":" + mdb.call(that, rule.value);
                            part += es_key_val;
                        }
                        else if (ope.nb_inputs === 0) {
                            es_key_val += mdb.call(that, rule.value) + rule.field;
                            part += es_key_val;
                        }

                        if(data.rules[index+1]) {
                            return part + " " + data.condition + " ";
                        }
                        else {
                            return part;
                        }

                    }
                    if (rule.rules && rule.rules.length>0) {
                        parts += "(" + parse(rule) + ")";
                    } else {
                        parts += make_query(rule);
                    }

                });
                return parts;
            }(data));
        }
    });

    /**
    * Get the right type of query term in elasticsearch DSL
    */
    function getQueryDSLWord(rule) {
        var term = /^(equal|not_equal)$/.exec(rule.operator),
            wildcard = /.(\*|\?)/.exec(rule.value),
            terms = /^(in|not_in)$/.exec(rule.operator);

        if (term !== null && wildcard !== null) { return 'wildcard'; }
        if (term !== null) { return 'term'; }
        if (terms !== null) { return 'terms'; }
        return 'range';
    }

    /**
    * Get the right type of clause in the bool query
    */
    function getClauseWord(condition, operator) {
        if (condition === 'AND' && (operator !== 'not_equal' && operator !== 'not_in')) { return 'must' }
        if (condition === 'AND' && (operator === 'not_equal' || operator == 'not_in')) { return 'must_not' }
        if (condition === 'OR') { return 'should' }
    }

}));
<|endoftext|>


<commit_before>const fs = require('fs')
const path = require('path')
const url = require('url')
const electron = require('electron')
const ipcMain = electron.ipcMain
const dialog = electron.dialog
const app = electron.app
const BrowserWindow = electron.BrowserWindow

const autoUpdater = require('electron-updater').autoUpdater
const log = require('electron-log')
autoUpdater.logger = log
autoUpdater.logger.transports.file.level = 'info'
autoUpdater.autoDownload = false

const __DEV__ = process.env.NODE_ENV === 'development'

let windowsRegistry = []

function createWindow (opt = {})
{
	let options = Object.assign(
	{
		width: 1600,
		height: 1200,
		'web-security': false,
		webPreferences: {
			// preload: path.resolve('./preload.js'),
		},
	}, opt)

	let mainWindow = new BrowserWindow(options)
	windowsRegistry.push(mainWindow)

	console.log('createWindow', opt)

	let wurl = url.format(
	{
		pathname: `${__dirname}/index.html`,
		protocol: 'file:',
		query:
		{
			'dev': __DEV__ ? 1 : 0,
			'test': __DEV__ ? 1 : 0,
			'db': 0,
			'gapi': 0,
			'od': 0,
			'gh': 0,
			'tr': 0,
			'analytics': 0,
			'picker': 0,
			'mode': 'device',
			'browser': 0,
			'p': 'electron',
		},
		slashes: true,
	})

//`file://${__dirname}/index.html?dev=1&test=1&db=0&gapi=0&od=0&analytics=0&picker=0&mode=device&browser=0&p=electron`
	// and load the index.html of the app.
	mainWindow.loadURL(wurl)

	// Open the DevTools.
	if (__DEV__)
	{
		mainWindow.webContents.openDevTools()
	}

	mainWindow.on('close', (event/*:WindowEvent*/) =>
	{
		const win = event.sender
		const index = windowsRegistry.indexOf(win)
		console.log('Window on close idx:%d', index)
		const contents = win.webContents

		if (contents != null)
		{
			contents.executeJavaScript(`global.__emt_isModified()`, true,
				isModified =>
				{
					console.log('__emt_isModified', isModified)
					if (isModified)
					{
						var choice = dialog.showMessageBox(
							win,
							{
								type: 'question',
								buttons: ['Cancel', 'Discard Changes'],
								title: 'Confirm',
								message: 'The document has unsaved changes. Do you really want to quit without saving?' //mxResources.get('allChangesLost')
							})

						if (choice === 1)
						{
							win.destroy()
						}
					}
					else
					{
						win.destroy()
					}
				})

			event.preventDefault()
		}
	})

	// Emitted when the window is closed.
	mainWindow.on('closed', (event/*:WindowEvent*/) =>
	{
		const index = windowsRegistry.indexOf(event.sender)
		console.log('Window closed idx:%d', index)
		windowsRegistry.splice(index, 1)
	})

	return mainWindow.id
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', e =>
{
	//asynchronous
	ipcMain.on('asynchronous-message', (event, arg) =>
	{
		console.log(arg)  // prints "ping"
		event.sender.send('asynchronous-reply', 'pong')
	})
	//synchronous
	ipcMain.on('winman', (event, arg) =>
	{
		console.log('ipcMain.on winman', arg)

		if (arg.action === 'newfile')
		{
			event.returnValue = createWindow(arg.opt)
			return
		}

		event.returnValue = 'pong'
	})

	createWindow()
	autoUpdater.checkForUpdates()

	if (process.platform === 'darwin')
	{
	    template = [{
	      label: app.getName(),
	      submenu: [
	        {
	          label: 'About ' + app.getName(),
	          click() { shell.openExternal('https://about.draw.io'); }
	        },
	        {
	          label: 'Support',
	          click() { shell.openExternal('https://about.draw.io/support'); }
	        },
	        {
	          type: 'separator'
	        },
	        {
	          label: 'Quit',
	          accelerator: 'Command+Q',
	          click() { app.quit(); }
	        }
	      ]
	    }, {
	      label: 'Edit',
	      submenu: [{
	        label: 'Cut',
	        accelerator: 'CmdOrCtrl+X',
	        selector: 'cut:'
	      }, {
	        label: 'Copy',
	        accelerator: 'CmdOrCtrl+C',
	        selector: 'copy:'
	      }, {
	        label: 'Paste',
	        accelerator: 'CmdOrCtrl+V',
	        selector: 'paste:'
	      }]
	    }];
	}
})

// Quit when all windows are closed.
app.on('window-all-closed', function ()
{
	console.log('window-all-closed', windowsRegistry.length)
	// On OS X it is common for applications and their menu bar
	// to stay active until the user quits explicitly with Cmd + Q
	if (process.platform !== 'darwin')
	{
		app.quit()
	}
})

app.on('activate', function ()
{
	console.log('app on activate', windowsRegistry.length)
	// On OS X it's common to re-create a window in the app when the
	// dock icon is clicked and there are no other windows open.
	if (windowsRegistry.length === 0)
	{
		createWindow()
	}
})

autoUpdater.on('error', e => log.error('@error@\n', e))

autoUpdater.on('update-available', (a, b) =>
{
	log.info('@update-available@\n', a, b)

	dialog.showMessageBox(
	{
		type: 'question',
		buttons: ['Ok', 'Cancel'],
		title: 'Confirm Update',
		message: 'Update available.\n\nWould you like to download and install new version?',
		detail: 'Application will automatically restart to apply update after download',
	}, response =>
	{
		if (response === 0)
		{
			return autoUpdater.downloadUpdate()
		}
	})
})

/**/
autoUpdater.on('update-downloaded', (event, info) =>
{
	log.info('@update-downloaded@\n', info, event)
	// Ask user to update the app
	dialog.showMessageBox(
	{
		type: 'question',
		buttons: ['Install and Relaunch', 'Later'],
		defaultId: 0,
		message: 'A new version of ' + app.getName() + ' has been downloaded',
		detail: 'It will be installed the next time you restart the application',
	}, response =>
	{
		if (response === 0)
		{
			setTimeout(() => autoUpdater.quitAndInstall(), 1)
		}
	})
})
/**/<commit_msg>menu fixes<commit_after>const fs = require('fs')
const path = require('path')
const url = require('url')
const electron = require('electron')
const {Menu: menu, shell} = require('electron')
const ipcMain = electron.ipcMain
const dialog = electron.dialog
const app = electron.app
const BrowserWindow = electron.BrowserWindow

const autoUpdater = require('electron-updater').autoUpdater
const log = require('electron-log')
autoUpdater.logger = log
autoUpdater.logger.transports.file.level = 'info'
autoUpdater.autoDownload = false

const __DEV__ = process.env.NODE_ENV === 'development'

let windowsRegistry = []

function createWindow (opt = {})
{
	let options = Object.assign(
	{
		width: 1600,
		height: 1200,
		'web-security': false,
		webPreferences: {
			// preload: path.resolve('./preload.js'),
		},
	}, opt)

	let mainWindow = new BrowserWindow(options)
	windowsRegistry.push(mainWindow)

	console.log('createWindow', opt)

	let wurl = url.format(
	{
		pathname: `${__dirname}/index.html`,
		protocol: 'file:',
		query:
		{
			'dev': __DEV__ ? 1 : 0,
			'test': __DEV__ ? 1 : 0,
			'db': 0,
			'gapi': 0,
			'od': 0,
			'gh': 0,
			'tr': 0,
			'analytics': 0,
			'picker': 0,
			'mode': 'device',
			'browser': 0,
			'p': 'electron',
		},
		slashes: true,
	})

//`file://${__dirname}/index.html?dev=1&test=1&db=0&gapi=0&od=0&analytics=0&picker=0&mode=device&browser=0&p=electron`
	// and load the index.html of the app.
	mainWindow.loadURL(wurl)

	// Open the DevTools.
	if (__DEV__)
	{
		mainWindow.webContents.openDevTools()
	}

	mainWindow.on('close', (event/*:WindowEvent*/) =>
	{
		const win = event.sender
		const index = windowsRegistry.indexOf(win)
		console.log('Window on close idx:%d', index)
		const contents = win.webContents

		if (contents != null)
		{
			contents.executeJavaScript(`global.__emt_isModified()`, true,
				isModified =>
				{
					console.log('__emt_isModified', isModified)
					if (isModified)
					{
						var choice = dialog.showMessageBox(
							win,
							{
								type: 'question',
								buttons: ['Cancel', 'Discard Changes'],
								title: 'Confirm',
								message: 'The document has unsaved changes. Do you really want to quit without saving?' //mxResources.get('allChangesLost')
							})

						if (choice === 1)
						{
							win.destroy()
						}
					}
					else
					{
						win.destroy()
					}
				})

			event.preventDefault()
		}
	})

	// Emitted when the window is closed.
	mainWindow.on('closed', (event/*:WindowEvent*/) =>
	{
		const index = windowsRegistry.indexOf(event.sender)
		console.log('Window closed idx:%d', index)
		windowsRegistry.splice(index, 1)
	})

	return mainWindow.id
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', e =>
{
	//asynchronous
	ipcMain.on('asynchronous-message', (event, arg) =>
	{
		console.log(arg)  // prints "ping"
		event.sender.send('asynchronous-reply', 'pong')
	})
	//synchronous
	ipcMain.on('winman', (event, arg) =>
	{
		console.log('ipcMain.on winman', arg)

		if (arg.action === 'newfile')
		{
			event.returnValue = createWindow(arg.opt)
			return
		}

		event.returnValue = 'pong'
	})

	createWindow()
	autoUpdater.checkForUpdates()

	let template = [{
	    label: app.getName(),
	    submenu: [
	      {
	        label: 'Website',
	        click() { shell.openExternal('https://about.draw.io'); }
	      },
	      {
	        label: 'Support',
	        click() { shell.openExternal('https://about.draw.io/support'); }
	      },
	      {
	        type: 'separator'
	      },
	      {
	        label: 'Quit',
	        accelerator: 'CmdOrCtrl+Q',
	        click() { app.quit(); }
	      }]
	}];

	if (process.platform === 'darwin')
	{
	    template = [{
	      label: app.getName(),
	      submenu: [
	        {
	          label: 'About ' + app.getName(),
	          click() { shell.openExternal('https://about.draw.io'); }
	        },
	        {
	          label: 'Support',
	          click() { shell.openExternal('https://about.draw.io/support'); }
	        },
	        {
	          type: 'separator'
	        },
	        {
	          label: 'Quit',
	          accelerator: 'Command+Q',
	          click() { app.quit(); }
	        }
	      ]
	    }, {
	      label: 'Edit',
	      submenu: [{
	        label: 'Cut',
	        accelerator: 'CmdOrCtrl+X',
	        selector: 'cut:'
	      }, {
	        label: 'Copy',
	        accelerator: 'CmdOrCtrl+C',
	        selector: 'copy:'
	      }, {
	        label: 'Paste',
	        accelerator: 'CmdOrCtrl+V',
	        selector: 'paste:'
	      }]
	    }];
	}

	const menuBar = menu.buildFromTemplate(template);
	menu.setApplicationMenu(menuBar);
})

// Quit when all windows are closed.
app.on('window-all-closed', function ()
{
	console.log('window-all-closed', windowsRegistry.length)
	// On OS X it is common for applications and their menu bar
	// to stay active until the user quits explicitly with Cmd + Q
	if (process.platform !== 'darwin')
	{
		app.quit()
	}
})

app.on('activate', function ()
{
	console.log('app on activate', windowsRegistry.length)
	// On OS X it's common to re-create a window in the app when the
	// dock icon is clicked and there are no other windows open.
	if (windowsRegistry.length === 0)
	{
		createWindow()
	}
})

autoUpdater.on('error', e => log.error('@error@\n', e))

autoUpdater.on('update-available', (a, b) =>
{
	log.info('@update-available@\n', a, b)

	dialog.showMessageBox(
	{
		type: 'question',
		buttons: ['Ok', 'Cancel'],
		title: 'Confirm Update',
		message: 'Update available.\n\nWould you like to download and install new version?',
		detail: 'Application will automatically restart to apply update after download',
	}, response =>
	{
		if (response === 0)
		{
			return autoUpdater.downloadUpdate()
		}
	})
})

/**/
autoUpdater.on('update-downloaded', (event, info) =>
{
	log.info('@update-downloaded@\n', info, event)
	// Ask user to update the app
	dialog.showMessageBox(
	{
		type: 'question',
		buttons: ['Install and Relaunch', 'Later'],
		defaultId: 0,
		message: 'A new version of ' + app.getName() + ' has been downloaded',
		detail: 'It will be installed the next time you restart the application',
	}, response =>
	{
		if (response === 0)
		{
			setTimeout(() => autoUpdater.quitAndInstall(), 1)
		}
	})
})
/**/<|endoftext|>


<commit_before>/**
 * @fileoverview layout component
 * @dependency code-snippet.js jquery.1.8.3
 * @author NHN entertainment FE dev team Jein Yi(jein.yi@nhnent.com)
 */
ne.util.defineNamespace('ne.component');

ne.component.Layout = ne.util.defineClass({
	/**
	 * initialize layout
	 * @param {object} opitons
	 * 	@param {array} options.grouplist group option list
	 * @param {JQueryObject} $element
	 */
	init: function(opitons, $element) {
		this.$element = $element;
		this._makeGroup(opitons.grouplist);
		this._makeGuide(opitons.guideHTML);
		this._setEvents();
	},

	/**
	 * make group
	 * @param {array} grouplist The list of group options
	 * @private
	 */
	_makeGroup: function(grouplist) {
		var group;
		this.groups = {};

		ne.util.forEach(grouplist, function(item) {
			group = this.groups[item.id] = new ne.component.Layout.Group(item);
			this.$element.append(group.$element);
		}, this);
	},

	/**
	 * get group item
	 * @param {(string|object)} group The item id or information to find group
	 * @returns {*}
	 * @private
	 */
	_getGroup: function(group) {
		if (ne.util.isObject(group)) {
			if (group.attr('data-group')) {
				group = group.attr('data-group');
			} else {
				group = group.parent().attr('data-group');
			}
		}
		return this.groups[group];
	},

	/**
	 * make guide object
	 * @param {string} [guideHTML] guide element html
	 * @private
	 */
	_makeGuide: function(guideHTML) {
		this._guide = new ne.component.Layout.Guide({
			guideHTML: guideHTML
		});
	},

	/**
	 * set Events
	 * @private
	 */
	_setEvents: function() {
		this.onMouseDown = $.proxy(this._onMouseDown, this);
		this.onMouseMove = $.proxy(this._onMouseMove, this);
		this.onMouseUp = $.proxy(this._onMouseUp, this);
		$('.drag-item-move').on('mousedown', this.onMouseDown);
	},

	/**
	 * mouse down event handler
	 * @param e
	 * @private
	 */
	_onMouseDown: function(e) {
		var $doc = $(document);
		this._setGuide(e.target, e.clientX, e.clientY);
		$doc.on('mousemove', this.onMouseMove);
		$doc.on('mouseup', this.onMouseUp);
	},

	/**
	 * set guide
	 * @param {object} target guide target
	 * @param {number} pointX
	 * @param {number} pointY
	 * @private
	 */
	_setGuide: function(target, pointX, pointY) {
		var initPos = {
				x: pointX + this.getX() + 10,
				y: pointY + this.getY() + 10
			},
			itemId = $(target).attr('data-item'),
			$moveEl = $('#' + itemId);

		this._guide.ready(initPos, $moveEl);
		this._guide.setMoveElement($moveEl);
		this.$temp = $moveEl;
		this._lockTemp();
	},

	/**
	 *
	 * @private
	 */
	_lockTemp: function() {
		var group = this._getGroup(this.$temp),
			item = group.list[this.$temp.attr('data-index')];
		this.$temp.css('opacity', '0.2');
		this.$temp.find('#' + item.contentId).css('visibility', 'hidden');
	},

	/**
	 *
	 * @private
	 */
	_unlockTemp: function() {
		var group = this._getGroup(this.$temp),
			item = group.list[this.$temp.attr('data-index')];
		this.$temp.css('opacity', '1');
		this.$temp.find('#' + item.contentId).css('visibility', 'visible');
	},

	/**
	 * mouse move handler
	 * @param {JqueryEvent} e event object
	 * @private
	 */
	_onMouseMove: function(e) {
		var parent = $(e.target).parent(),
			pointX = e.clientX + this.getX(),
			group = parent.attr('data-group'),
			pointY = e.clientY + this.getY();

		this._moveGuide(pointX, pointY);

		if (group) {
			this._detectMove(parent, pointX, pointY);
		}
	},

	/**
	 * detect move with group
	 * @param {object} item compare position with
	 * @param {number} pointX x position
	 * @param {number} pointY y position
	 * @private
	 */
	_detectMove: function(item, pointX, pointY) {
		var groupInst = this._getGroup(item),
			group = item.attr('data-group'),
			$before,
			top = $(document).scrollTop(),
			left = $(document).scrollLeft();

		if (ne.util.isEmpty(groupInst.list)) {
			item.append(this.$temp);
			this.$temp.way = 'after';
			this.$temp.index = 0;
		} else {
			$before = this._detectTargetByPosition({
				x: pointX + left,
				y: pointY + top
			}, groupInst);

			if ($before && $before.way) {
				$before[$before.way](this.$temp);
				this.$temp.way = $before.way;
				this.$temp.index = $before.attr('data-index');
			}
		}
	},

	/**
	 * move drag effect element
	 * @param {number} x move position x
	 * @param {number} y move position y
	 * @private
	 */
	_moveGuide: function(x, y) {
		this._guide.moveTo({
			x: x + 10 + 'px',
			y: y + 10 + 'px'
		});
	},

	/**
	 * detect target by move element position
	 * @param {object} pos position to detect
	 * @param {object} group  group that has child
	 * @returns {string|*}
	 * @private
	 */
	_detectTargetByPosition: function(pos, group) {

		var target;

		ne.util.forEach(group.list, function(item) {
			if (!this._isValidItem(item)) {
				return;
			}
			target = this._getTarget(item, pos, group) || target;
		}, this);

		return target;
	},

	/**
	 * get target element
	 * @param {object} item The item to compare with pos
	 * @param {object} pos The pos to figure whether target or not
	 * @param {object} group The group has item
	 * @private
	 */
	_getTarget: function(item, pos, group) {
		var bound = item.$element.offset(),
			bottom = this._getBottom(item, group),
			height = item.$element.height(),
			top = this.getY() + bound.top,
			$target;
		if (pos.y > top && pos.y <= top + (height / 2)) {
			$target = item.$element;
			$target.way = 'before';
		} else if (pos.y > top + (height / 2) && pos.y < bottom) {
			$target = item.$element;
			$target.way = 'after';
		}

		return $target;
	},

	/**
	 * check whether Vaild item or not
	 * @param {param} item
	 * @returns {boolean}
	 * @private
	 */
	_isValidItem: function(item) {
		return (item.$element[0] !== this.$temp[0]);
	},

	/**
	 * if next element exist, set bottom next element's top position, else set bottom limit(group element's bottom position) position
	 * @param {object} item The object to figure bottom position
	 * @param {object} group The group to figure bottom position
	 * @returns {*}
	 * @private
	 */
	_getBottom: function(item, group) {
		var $next = item.$element.next(),
			bottom,
			gbound = group.$element.offset(),
			limit = this.getY() + gbound.top + group.$element.height();
		if ($next.hasClass(DIMMED_LAYER_CLASS)) {
			bottom = limit;
		} else {
			bottom = this.getY() + $next.offset().top;
		}
		return bottom;
	},

	/**
	 * get add index by $temp, $temp.way
	 * @returns {Number}
	 * @private
	 */
	_getAddIndex: function() {
		var temp = this.$temp,
			index = parseInt(temp.index, 10);
		if (temp.way === 'after') {
			index += 1;
		}
		return index;
	},

	/**
	 * get scrollX
	 * @returns {Number}
	 */
	getX: function() {
		return (window.scrollX || $(window).scrollLeft());
	},

	/**
	 * get scrollY
	 * @returns {Number}
	 */
	getY: function() {
		return (window.scrollY || $(window).scrollTop());
	},

	/**
	 * mouse up handler
	 * @param {JqueryEvent} e A event object
	 * @private
	 */
	_onMouseUp: function(e) {
		var drag = this._guide,
			$doc = $(document),
			group = this._getGroup(this.$temp.attr('data-groupInfo')),
			$target = this._detectTargetByPosition({
				x: e.clientX + this.getX(),
				y: e.clientY + this.getY()
			}, group);

		this._update();
		this._unlockTemp();
		drag.finish();

		$doc.off('mousemove', this.onMouseMove);
		$doc.off('mouseup', this.onMouseUp);
	},

	/**
	 * update groups
	 * @private
	 */
	_update: function() {
		var temp = this.$temp,
			oldGroup = this._getGroup(temp.attr('data-groupInfo')),
			targetGroup = this._getGroup(temp.parent()),
			removeIndex = parseInt(temp.attr('data-index'), 10),
			addIndex = this._getAddIndex(),
			item = oldGroup.list[removeIndex];

		if (!isNaN(addIndex)) {
			oldGroup.storePool();
			targetGroup.storePool();
			oldGroup.remove(removeIndex);
			targetGroup.add(item, addIndex);
			targetGroup.render();
			oldGroup.render();
		}
	}
});<commit_msg>space<commit_after>/**
 * @fileoverview layout component
 * @dependency code-snippet.js jquery.1.8.3
 * @author NHN entertainment FE dev team Jein Yi(jein.yi@nhnent.com)
 */
ne.util.defineNamespace('ne.component');

ne.component.Layout = ne.util.defineClass({
	/**
	 * initialize layout
	 * @param {object} opitons
	 * 	@param {array} options.grouplist group option list
	 * @param {JQueryObject} $element
	 */
	init: function(opitons, $element) {
		this.$element = $element;
		this._makeGroup(opitons.grouplist);
		this._makeGuide(opitons.guideHTML);
		this._setEvents();
	},

	/**
	 * make group
	 * @param {array} grouplist The list of group options
	 * @private
	 */
	_makeGroup: function(grouplist) {
		var group;
		this.groups = {};

		ne.util.forEach(grouplist, function(item) {
			group = this.groups[item.id] = new ne.component.Layout.Group(item);
			this.$element.append(group.$element);
		}, this);
	},

	/**
	 * get group item
	 * @param {(string|object)} group The item id or information to find group
	 * @returns {*}
	 * @private
	 */
	_getGroup: function(group) {
		if (ne.util.isObject(group)) {
			if (group.attr('data-group')) {
				group = group.attr('data-group');
			} else {
				group = group.parent().attr('data-group');
			}
		}
		return this.groups[group];
	},

	/**
	 * make guide object
	 * @param {string} [guideHTML] guide element html
	 * @private
	 */
	_makeGuide: function(guideHTML) {
		this._guide = new ne.component.Layout.Guide({
			guideHTML: guideHTML
		});
	},

	/**
	 * set Events
	 * @private
	 */
	_setEvents: function() {
		this.onMouseDown = $.proxy(this._onMouseDown, this);
		this.onMouseMove = $.proxy(this._onMouseMove, this);
		this.onMouseUp = $.proxy(this._onMouseUp, this);
		$('.drag-item-move').on('mousedown', this.onMouseDown);
	},

	/**
	 * mouse down event handler
	 * @param e
	 * @private
	 */
	_onMouseDown: function(e) {
		var $doc = $(document);
		this._setGuide(e.target, e.clientX, e.clientY);
		$doc.on('mousemove', this.onMouseMove);
		$doc.on('mouseup', this.onMouseUp);
	},

	/**
	 * set guide
	 * @param {object} target guide target
	 * @param {number} pointX
	 * @param {number} pointY
	 * @private
	 */
	_setGuide: function(target, pointX, pointY) {
		var initPos = {
				x: pointX + this.getX() + 10,
				y: pointY + this.getY() + 10
			},
			itemId = $(target).attr('data-item'),
			$moveEl = $('#' + itemId);

		this._guide.ready(initPos, $moveEl);
		this._guide.setMoveElement($moveEl);
		this.$temp = $moveEl;
		this._lockTemp();
	},

	/**
	 *
	 * @private
	 */
	_lockTemp: function() {
		var group = this._getGroup(this.$temp),
			item = group.list[this.$temp.attr('data-index')];
		this.$temp.css('opacity', '0.2');
		this.$temp.find('#' + item.contentId).css('visibility', 'hidden');
	},

	/**
	 *
	 * @private
	 */
	_unlockTemp: function() {
		var group = this._getGroup(this.$temp),
			item = group.list[this.$temp.attr('data-index')];
		this.$temp.css('opacity', '1');
		this.$temp.find('#' + item.contentId).css('visibility', 'visible');
	},

	/**
	 * mouse move handler
	 * @param {JqueryEvent} e event object
	 * @private
	 */
	_onMouseMove: function(e) {
		var parent = $(e.target).parent(),
			pointX = e.clientX + this.getX(),
			group = parent.attr('data-group'),
			pointY = e.clientY + this.getY();

		this._moveGuide(pointX, pointY);

		if (group) {
			this._detectMove(parent, pointX, pointY);
		}
	},

	/**
	 * detect move with group
	 * @param {object} item compare position with
	 * @param {number} pointX x position
	 * @param {number} pointY y position
	 * @private
	 */
	_detectMove: function(item, pointX, pointY) {
		var groupInst = this._getGroup(item),
			group = item.attr('data-group'),
			$before,
			top = $(document).scrollTop(),
			left = $(document).scrollLeft();

		if (ne.util.isEmpty(groupInst.list)) {
			item.append(this.$temp);
			this.$temp.way = 'after';
			this.$temp.index = 0;
		} else {
			$before = this._detectTargetByPosition({
				x: pointX + left,
				y: pointY + top
			}, groupInst);

			if ($before && $before.way) {
				$before[$before.way](this.$temp);
				this.$temp.way = $before.way;
				this.$temp.index = $before.attr('data-index');
			}
		}
	},

	/**
	 * move drag effect element
	 * @param {number} x move position x
	 * @param {number} y move position y
	 * @private
	 */
	_moveGuide: function(x, y) {
		this._guide.moveTo({
			x: x + 10 + 'px',
			y: y + 10 + 'px'
		});
	},

	/**
	 * detect target by move element position
	 * @param {object} pos position to detect
	 * @param {object} group  group that has child
	 * @returns {string|*}
	 * @private
	 */
	_detectTargetByPosition: function(pos, group) {
		var target;

		ne.util.forEach(group.list, function(item) {
			if (!this._isValidItem(item)) {
				return;
			}
			target = this._getTarget(item, pos, group) || target;
		}, this);

		return target;
	},

	/**
	 * get target element
	 * @param {object} item The item to compare with pos
	 * @param {object} pos The pos to figure whether target or not
	 * @param {object} group The group has item
	 * @private
	 */
	_getTarget: function(item, pos, group) {
		var bound = item.$element.offset(),
			bottom = this._getBottom(item, group),
			height = item.$element.height(),
			top = this.getY() + bound.top,
			$target;
		if (pos.y > top && pos.y <= top + (height / 2)) {
			$target = item.$element;
			$target.way = 'before';
		} else if (pos.y > top + (height / 2) && pos.y < bottom) {
			$target = item.$element;
			$target.way = 'after';
		}

		return $target;
	},

	/**
	 * check whether Vaild item or not
	 * @param {param} item
	 * @returns {boolean}
	 * @private
	 */
	_isValidItem: function(item) {
		return (item.$element[0] !== this.$temp[0]);
	},

	/**
	 * if next element exist, set bottom next element's top position, else set bottom limit(group element's bottom position) position
	 * @param {object} item The object to figure bottom position
	 * @param {object} group The group to figure bottom position
	 * @returns {*}
	 * @private
	 */
	_getBottom: function(item, group) {
		var $next = item.$element.next(),
			bottom,
			gbound = group.$element.offset(),
			limit = this.getY() + gbound.top + group.$element.height();
		if ($next.hasClass(DIMMED_LAYER_CLASS)) {
			bottom = limit;
		} else {
			bottom = this.getY() + $next.offset().top;
		}
		return bottom;
	},

	/**
	 * get add index by $temp, $temp.way
	 * @returns {Number}
	 * @private
	 */
	_getAddIndex: function() {
		var temp = this.$temp,
			index = parseInt(temp.index, 10);
		if (temp.way === 'after') {
			index += 1;
		}
		return index;
	},

	/**
	 * get scrollX
	 * @returns {Number}
	 */
	getX: function() {
		return (window.scrollX || $(window).scrollLeft());
	},

	/**
	 * get scrollY
	 * @returns {Number}
	 */
	getY: function() {
		return (window.scrollY || $(window).scrollTop());
	},

	/**
	 * mouse up handler
	 * @param {JqueryEvent} e A event object
	 * @private
	 */
	_onMouseUp: function(e) {
		var drag = this._guide,
			$doc = $(document),
			group = this._getGroup(this.$temp.attr('data-groupInfo')),
			$target = this._detectTargetByPosition({
				x: e.clientX + this.getX(),
				y: e.clientY + this.getY()
			}, group);

		this._update();
		this._unlockTemp();
		drag.finish();

		$doc.off('mousemove', this.onMouseMove);
		$doc.off('mouseup', this.onMouseUp);
	},

	/**
	 * update groups
	 * @private
	 */
	_update: function() {
		var temp = this.$temp,
			oldGroup = this._getGroup(temp.attr('data-groupInfo')),
			targetGroup = this._getGroup(temp.parent()),
			removeIndex = parseInt(temp.attr('data-index'), 10),
			addIndex = this._getAddIndex(),
			item = oldGroup.list[removeIndex];

		if (!isNaN(addIndex)) {
			oldGroup.storePool();
			targetGroup.storePool();
			oldGroup.remove(removeIndex);
			targetGroup.add(item, addIndex);
			targetGroup.render();
			oldGroup.render();
		}
	}
});<|endoftext|>


<commit_before>var pull = require('pull-stream')
var computed = require('mutant/computed')
var MutantPullReduce = require('mutant-pull-reduce')
var nest = require('depnest')
var ref = require('ssb-ref')

var throttle = require('mutant/throttle')

exports.needs = nest({
  'sbot.pull.userFeed': 'first'
})

exports.gives = nest({
  'channel.obs': ['subscribed']
})

exports.create = function (api) {
  var cache = {}

  return nest({
    'channel.obs': {subscribed}
  })

  function subscribed (userId) {
    if (!ref.isFeed(userId)) throw new Error('a feed id must be specified')
    if (cache[userId]) {
      return cache[userId]
    } else {
      var stream = pull(
        api.sbot.pull.userFeed({id: userId, live: true}),
        pull.filter((msg) => {
          return !msg.value || msg.value.content.type === 'channel'
        })
      )

      var result = MutantPullReduce(stream, (result, msg) => {
        var c = msg.value.content
        if (typeof c.channel === 'string' && c.channel) {
          var channel = c.channel.trim()
          if (channel) {
            if (typeof c.subscribed === 'boolean') {
              if (c.subscribed) {
                result.add(channel)
              } else {
                result.delete(channel)
              }
            }
          }
        }
        return result
      }, {
        startValue: new Set(),
        nextTick: true
      })

      var instance = throttle(result, 2000)
      instance.sync = result.sync

      instance.has = function (value) {
        return computed(instance, x => x.has(value))
      }

      cache[userId] = instance
      return instance
    }
  }
}
<commit_msg>channel/obs/subscribed: use sbot.hook for more responsive interface<commit_after>var pull = require('pull-stream')
var computed = require('mutant/computed')
var MutantPullReduce = require('mutant-pull-reduce')
var nest = require('depnest')
var ref = require('ssb-ref')

var throttle = require('mutant/throttle')

exports.needs = nest({
  'sbot.pull.userFeed': 'first'
})

exports.gives = nest({
  'channel.obs.subscribed': true,
  'sbot.hook.feed': true
})

exports.create = function (api) {
  var cache = {}
  var reducers = {}

  return nest({
    'channel.obs.subscribed': subscribed,
    'sbot.hook.feed': function (msg) {
      if (isChannelSubscription(msg)) {
        if (msg.value.content.channel && reducers[msg.value.author]) {
          reducers[msg.value.author].push(msg)
        }
      }
    }
  })

  function subscribed (userId) {
    if (!ref.isFeed(userId)) throw new Error('a feed id must be specified')
    if (cache[userId]) {
      return cache[userId]
    } else {
      var stream = pull(
        api.sbot.pull.userFeed({id: userId, live: true}),
        pull.filter((msg) => {
          return !msg.value || msg.value.content.type === 'channel'
        })
      )

      var latestTimestamp = 0

      var result = MutantPullReduce(stream, (result, msg) => {
        if (msg.value.timestamp > latestTimestamp) {
          var c = msg.value.content
          if (typeof c.channel === 'string' && c.channel) {
            latestTimestamp = msg.value.timestamp
            var channel = c.channel.trim()
            if (channel) {
              if (typeof c.subscribed === 'boolean') {
                if (c.subscribed) {
                  result.add(channel)
                } else {
                  result.delete(channel)
                }
              }
            }
          }
        }
        return result
      }, {
        startValue: new Set(),
        nextTick: true
      })

      reducers[userId] = result

      var instance = throttle(result, 2000)
      instance.sync = result.sync

      instance.has = function (value) {
        return computed(instance, x => x.has(value))
      }

      cache[userId] = instance
      return instance
    }
  }
}

function isChannelSubscription (msg) {
  return msg.value && msg.value.content && msg.value.content.type === 'channel'
}
<|endoftext|>


<commit_before>import AKButton from '@atlaskit/button';
import AKButtonGroup from '@atlaskit/button-group';
import ModalDialog from '@atlaskit/modal-dialog';
import React, { Component } from 'react';

import { translate } from '../../i18n';

import { DIALOG_PROP_TYPES } from '../constants';

/**
 * The ID to be used for the cancel button if enabled.
 * @type {string}
 */
const CANCEL_BUTTON_ID = 'modal-dialog-cancel-button';

/**
 * The ID to be used for the ok button if enabled.
 * @type {string}
 */
const OK_BUTTON_ID = 'modal-dialog-ok-button';

/**
 * Web dialog that uses atlaskit modal-dialog to display dialogs.
 */
class StatelessDialog extends Component {
    /**
     * {@code StatelessDialog} component's property types.
     *
     * @static
     */
    static propTypes = {
        ...DIALOG_PROP_TYPES,

        /**
         * This is the body of the dialog, the component children.
         */
        children: React.PropTypes.node,

        /**
         * Disables dismissing the dialog when the blanket is clicked. Enabled
         * by default.
         */
        disableBlanketClickDismiss: React.PropTypes.bool,

        /**
         * Whether the dialog is modal. This means clicking on the blanket will
         * leave the dialog open. No cancel button.
         */
        isModal: React.PropTypes.bool,

        /**
         * Disables rendering of the submit button.
         */
        submitDisabled: React.PropTypes.bool,

        /**
         * Width of the dialog, can be:
         * - 'small' (400px), 'medium' (600px), 'large' (800px),
         *   'x-large' (968px)
         * - integer value for pixel width
         * - string value for percentage
         */
        width: React.PropTypes.string
    };

    /**
     * Initializes a new {@code StatelessDialog} instance.
     *
     * @param {Object} props - The read-only properties with which the new
     * instance is to be initialized.
     */
    constructor(props) {
        super(props);

        // Bind event handlers so they are only bound once for every instance.
        this._onCancel = this._onCancel.bind(this);
        this._onDialogDismissed = this._onDialogDismissed.bind(this);
        this._onKeyDown = this._onKeyDown.bind(this);
        this._onSubmit = this._onSubmit.bind(this);
        this._setDialogElement = this._setDialogElement.bind(this);
    }

    /**
     * React Component method that executes once component is mounted.
     *
     * @inheritdoc
     */
    componentDidMount() {
        this._updateButtonFocus();
    }

    /**
     * React Component method that executes once component is updated.
     *
     * @param {Object} prevProps - The previous properties, before the update.
     * @returns {void}
     */
    componentDidUpdate(prevProps) {
        // if there is an update in any of the buttons enable/disable props
        // update the focus if needed
        if (prevProps.okDisabled !== this.props.okDisabled
            || prevProps.cancelDisabled !== this.props.cancelDisabled
            || prevProps.submitDisabled !== this.props.submitDisabled) {
            this._updateButtonFocus();
        }
    }

    /**
     * Implements React's {@link Component#render()}.
     *
     * @inheritdoc
     * @returns {ReactElement}
     */
    render() {
        return (

                <ModalDialog
                    footer = { this._renderFooter() }
                    header = { this._renderHeader() }
                    isOpen = { true }
                    onDialogDismissed = { this._onDialogDismissed }
                    width = { this.props.width || 'medium' }>

                        <form
                            className = 'modal-dialog-form'
                            id = 'modal-dialog-form'
                            onSubmit = { this._onSubmit }>
                            { this.props.children }
                        </form>

                </ModalDialog>

        );
    }

    /**
     * Dispatches action to hide the dialog.
     *
     * @returns {void}
     */
    _onCancel() {
        if (!this.props.isModal) {
            this.props.onCancel();
        }
    }

    /**
     * Handles click on the blanket area.
     *
     * @returns {void}
     */
    _onDialogDismissed() {
        if (!this.props.disableBlanketClickDismiss) {
            this._onCancel();
        }
    }

    /**
     * Dispatches the action when submitting the dialog.
     *
     * @private
     * @param {string} value - The submitted value if any.
     * @returns {void}
     */
    _onSubmit(value) {
        this.props.onSubmit(value);
    }

    /**
     * Renders Cancel button.
     *
     * @private
     * @returns {*} The Cancel button if enabled and dialog is not modal.
     */
    _renderCancelButton() {
        if (this.props.cancelDisabled || this.props.isModal) {
            return null;
        }

        return (
            <AKButton
                appearance = 'subtle'
                id = { CANCEL_BUTTON_ID }
                onClick = { this._onCancel }>
                { this.props.t(this.props.cancelTitleKey || 'dialog.Cancel') }
            </AKButton>
        );
    }

    /**
     * Renders component in dialog footer.
     *
     * @private
     * @returns {ReactElement}
     */
    _renderFooter() {
        return (

                <AKButtonGroup>
                    { this._renderCancelButton() }
                    { this._renderOKButton() }
                </AKButtonGroup>

        );
    }

    /**
     * Renders component in dialog header.
     *
     * @private
     * @returns {ReactElement}
     */
    _renderHeader() {
        const { t } = this.props;

        return (

                    { this.props.titleString || t(this.props.titleKey) }

        );
    }

    /**
     * Renders OK button.
     *
     * @private
     * @returns {*} The OK button if enabled.
     */
    _renderOKButton() {
        if (this.props.submitDisabled) {
            return null;
        }

        return (
            <AKButton
                appearance = 'primary'
                form = 'modal-dialog-form'
                id = { OK_BUTTON_ID }
                isDisabled = { this.props.okDisabled }
                onClick = { this._onSubmit }>
                { this.props.t(this.props.okTitleKey || 'dialog.Ok') }
            </AKButton>
        );
    }

    /**
     * Sets the instance variable for the div containing the component's dialog
     * element so it can be accessed directly.
     *
     * @param {Object} element - The DOM element for the component's dialog.
     * @private
     * @returns {void}
     */
    _setDialogElement(element) {
        this._dialogElement = element;
    }

    /**
     * Handles 'Enter' key in the dialog to submit/hide dialog depending on
     * the available buttons and their disabled state.
     *
     * @param {Object} event - the key event.
     * @private
     * @returns {void}
     */
    _onKeyDown(event) {
        if (event.key === 'Enter') {
            if (this.props.submitDisabled && !this.props.cancelDisabled) {
                this._onCancel();
            } else if (!this.props.okDisabled) {
                this._onSubmit();
            }
        }
    }

    /**
     * Updates focused button, if we have a reference to the dialog element.
     * Focus on available button if there is no focus already.
     *
     * @private
     * @returns {void}
     */
    _updateButtonFocus() {
        if (this._dialogElement) {

            // if we have a focused element inside the dialog, skip changing
            // the focus
            if (this._dialogElement.contains(document.activeElement)) {
                return;
            }

            let buttonToFocus;

            if (this.props.submitDisabled) {
                buttonToFocus = this._dialogElement
                    .querySelector(`[id=${CANCEL_BUTTON_ID}]`);
            } else if (!this.props.okDisabled) {
                buttonToFocus = this._dialogElement
                    .querySelector(`[id=${OK_BUTTON_ID}]`);
            }

            if (buttonToFocus) {
                buttonToFocus.focus();
            }
        }
    }
}

export default translate(StatelessDialog);
<commit_msg>Fixes a jsdoc/require-description-complete-sentence warning<commit_after>import AKButton from '@atlaskit/button';
import AKButtonGroup from '@atlaskit/button-group';
import ModalDialog from '@atlaskit/modal-dialog';
import React, { Component } from 'react';

import { translate } from '../../i18n';

import { DIALOG_PROP_TYPES } from '../constants';

/**
 * The ID to be used for the cancel button if enabled.
 * @type {string}
 */
const CANCEL_BUTTON_ID = 'modal-dialog-cancel-button';

/**
 * The ID to be used for the ok button if enabled.
 * @type {string}
 */
const OK_BUTTON_ID = 'modal-dialog-ok-button';

/**
 * Web dialog that uses atlaskit modal-dialog to display dialogs.
 */
class StatelessDialog extends Component {
    /**
     * {@code StatelessDialog} component's property types.
     *
     * @static
     */
    static propTypes = {
        ...DIALOG_PROP_TYPES,

        /**
         * This is the body of the dialog, the component children.
         */
        children: React.PropTypes.node,

        /**
         * Disables dismissing the dialog when the blanket is clicked. Enabled
         * by default.
         */
        disableBlanketClickDismiss: React.PropTypes.bool,

        /**
         * Whether the dialog is modal. This means clicking on the blanket will
         * leave the dialog open. No cancel button.
         */
        isModal: React.PropTypes.bool,

        /**
         * Disables rendering of the submit button.
         */
        submitDisabled: React.PropTypes.bool,

        /**
         * Width of the dialog, can be:
         * - 'small' (400px), 'medium' (600px), 'large' (800px),
         *   'x-large' (968px)
         * - integer value for pixel width
         * - string value for percentage
         */
        width: React.PropTypes.string
    };

    /**
     * Initializes a new {@code StatelessDialog} instance.
     *
     * @param {Object} props - The read-only properties with which the new
     * instance is to be initialized.
     */
    constructor(props) {
        super(props);

        // Bind event handlers so they are only bound once for every instance.
        this._onCancel = this._onCancel.bind(this);
        this._onDialogDismissed = this._onDialogDismissed.bind(this);
        this._onKeyDown = this._onKeyDown.bind(this);
        this._onSubmit = this._onSubmit.bind(this);
        this._setDialogElement = this._setDialogElement.bind(this);
    }

    /**
     * React Component method that executes once component is mounted.
     *
     * @inheritdoc
     */
    componentDidMount() {
        this._updateButtonFocus();
    }

    /**
     * React Component method that executes once component is updated.
     *
     * @param {Object} prevProps - The previous properties, before the update.
     * @returns {void}
     */
    componentDidUpdate(prevProps) {
        // if there is an update in any of the buttons enable/disable props
        // update the focus if needed
        if (prevProps.okDisabled !== this.props.okDisabled
            || prevProps.cancelDisabled !== this.props.cancelDisabled
            || prevProps.submitDisabled !== this.props.submitDisabled) {
            this._updateButtonFocus();
        }
    }

    /**
     * Implements React's {@link Component#render()}.
     *
     * @inheritdoc
     * @returns {ReactElement}
     */
    render() {
        return (

                <ModalDialog
                    footer = { this._renderFooter() }
                    header = { this._renderHeader() }
                    isOpen = { true }
                    onDialogDismissed = { this._onDialogDismissed }
                    width = { this.props.width || 'medium' }>

                        <form
                            className = 'modal-dialog-form'
                            id = 'modal-dialog-form'
                            onSubmit = { this._onSubmit }>
                            { this.props.children }
                        </form>

                </ModalDialog>

        );
    }

    /**
     * Dispatches action to hide the dialog.
     *
     * @returns {void}
     */
    _onCancel() {
        if (!this.props.isModal) {
            this.props.onCancel();
        }
    }

    /**
     * Handles click on the blanket area.
     *
     * @returns {void}
     */
    _onDialogDismissed() {
        if (!this.props.disableBlanketClickDismiss) {
            this._onCancel();
        }
    }

    /**
     * Dispatches the action when submitting the dialog.
     *
     * @private
     * @param {string} value - The submitted value if any.
     * @returns {void}
     */
    _onSubmit(value) {
        this.props.onSubmit(value);
    }

    /**
     * Renders Cancel button.
     *
     * @private
     * @returns {*} The Cancel button if enabled and dialog is not modal.
     */
    _renderCancelButton() {
        if (this.props.cancelDisabled || this.props.isModal) {
            return null;
        }

        return (
            <AKButton
                appearance = 'subtle'
                id = { CANCEL_BUTTON_ID }
                onClick = { this._onCancel }>
                { this.props.t(this.props.cancelTitleKey || 'dialog.Cancel') }
            </AKButton>
        );
    }

    /**
     * Renders component in dialog footer.
     *
     * @private
     * @returns {ReactElement}
     */
    _renderFooter() {
        return (

                <AKButtonGroup>
                    { this._renderCancelButton() }
                    { this._renderOKButton() }
                </AKButtonGroup>

        );
    }

    /**
     * Renders component in dialog header.
     *
     * @private
     * @returns {ReactElement}
     */
    _renderHeader() {
        const { t } = this.props;

        return (

                    { this.props.titleString || t(this.props.titleKey) }

        );
    }

    /**
     * Renders OK button.
     *
     * @private
     * @returns {*} The OK button if enabled.
     */
    _renderOKButton() {
        if (this.props.submitDisabled) {
            return null;
        }

        return (
            <AKButton
                appearance = 'primary'
                form = 'modal-dialog-form'
                id = { OK_BUTTON_ID }
                isDisabled = { this.props.okDisabled }
                onClick = { this._onSubmit }>
                { this.props.t(this.props.okTitleKey || 'dialog.Ok') }
            </AKButton>
        );
    }

    /**
     * Sets the instance variable for the div containing the component's dialog
     * element so it can be accessed directly.
     *
     * @param {Object} element - The DOM element for the component's dialog.
     * @private
     * @returns {void}
     */
    _setDialogElement(element) {
        this._dialogElement = element;
    }

    /**
     * Handles 'Enter' key in the dialog to submit/hide dialog depending on
     * the available buttons and their disabled state.
     *
     * @param {Object} event - The key event.
     * @private
     * @returns {void}
     */
    _onKeyDown(event) {
        if (event.key === 'Enter') {
            if (this.props.submitDisabled && !this.props.cancelDisabled) {
                this._onCancel();
            } else if (!this.props.okDisabled) {
                this._onSubmit();
            }
        }
    }

    /**
     * Updates focused button, if we have a reference to the dialog element.
     * Focus on available button if there is no focus already.
     *
     * @private
     * @returns {void}
     */
    _updateButtonFocus() {
        if (this._dialogElement) {

            // if we have a focused element inside the dialog, skip changing
            // the focus
            if (this._dialogElement.contains(document.activeElement)) {
                return;
            }

            let buttonToFocus;

            if (this.props.submitDisabled) {
                buttonToFocus = this._dialogElement
                    .querySelector(`[id=${CANCEL_BUTTON_ID}]`);
            } else if (!this.props.okDisabled) {
                buttonToFocus = this._dialogElement
                    .querySelector(`[id=${OK_BUTTON_ID}]`);
            }

            if (buttonToFocus) {
                buttonToFocus.focus();
            }
        }
    }
}

export default translate(StatelessDialog);
<|endoftext|>


<commit_before>module.exports = {
  cmd: "cl",
  name: "x86",
  args: [
    "/D_UNICODE",
    "/DUNICODE",
    "/DWIN32",
    "/D_WINDOWS",
    "mousejump.cpp"
  ],
  sh: true,
  env: {
    INCLUDE: "/Program Files (x86)/Windows Kits/10/Include/10.0.14393.0/ucrt;/Program Files (x86)/Windows Kits/10/Include/10.0.14393.0/shared;/Program Files (x86)/Windows Kits/10/Include/10.0.14393.0/um;/Program Files (x86)/Windows Kits/10/Include/10.0.14393.0/winrt;/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.10.24728/include",
    LIB: "/Program Files (x86)/Windows Kits/10/Lib/10.0.14393.0/ucrt/x86;/Program Files (x86)/Windows Kits/10/Lib/10.0.14393.0/um/x86;/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.10.24728/lib/x86"
  },
  errorMatch: [
    "(?<file>.+)\\((?<line>\\d+)\\): (?<message>error.*)"
  ],
  warningMatch: [
    "^regexp1$"
  ],
  keymap: "f5",
  atomCommandName: "visualstudio:win32",
  postBuild: function (buildOutcome) {
    if (buildOutcome) {
      atom.commands.dispatch(atom.views.getView(atom.workspace), "script:run-with-profile");
    }
  }
};
<commit_msg>minor build file improvements<commit_after>module.exports = {
  cmd: "cl",
  name: "x86",
  args: [
    "/EHsc",
    "/D_UNICODE",
    "/DUNICODE",
    "/DWIN32",
    "/D_WINDOWS",
    "mousejump.cpp"
  ],
  sh: true,
  env: {
    INCLUDE: "/Program Files (x86)/Windows Kits/10/Include/10.0.14393.0/ucrt;/Program Files (x86)/Windows Kits/10/Include/10.0.14393.0/shared;/Program Files (x86)/Windows Kits/10/Include/10.0.14393.0/um;/Program Files (x86)/Windows Kits/10/Include/10.0.14393.0/winrt;/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.10.24728/include",
    LIB: "/Program Files (x86)/Windows Kits/10/Lib/10.0.14393.0/ucrt/x86;/Program Files (x86)/Windows Kits/10/Lib/10.0.14393.0/um/x86;/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.10.24728/lib/x86"
  },
  errorMatch: [
    "(?<file>.+)\\((?<line>\\d+)\\): (?<message>error.*)"
  ],
  warningMatch: [
    "(?<file>.+)\\((?<line>\\d+)\\): (?<message>warning.*)"
  ],
  keymap: "f5",
  atomCommandName: "visualstudio:win32",
  postBuild: function (buildOutcome) {
    if (buildOutcome) {
      atom.commands.dispatch(atom.views.getView(atom.workspace), "script:run-with-profile");
    }
  }
};
<|endoftext|>


<commit_before>// site1.js

/**
*    Copyright (C) 2008 10gen Inc.
*
*    This program is free software: you can redistribute it and/or  modify
*    it under the terms of the GNU Affero General Public License, version 3,
*    as published by the Free Software Foundation.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU Affero General Public License for more details.
*
*    You should have received a copy of the GNU Affero General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

Cloud.Environment = function(){
    this.branch = null;
    this.name = this.branch;
    this.db = null;
    this.pool = null;
    this.iid = ObjectId();
    this.aliases = [];
};

Cloud.SiteDB = function(){
    this.name = null;
    this.server = null;
    this.did = ObjectId();
};

Cloud.Site = function( name ){
    this.name = name;
    this.created = new Date();

    this.environments = [];
    this.environments._dbCons = Cloud.Environment;

    this.dbs = [];
    this.dbs._dbCons = Cloud.SiteDB;
};

Cloud.Site.prototype.environmentNames = function(){
    return this.environments.map( function(z){ return z.name } );
}

Cloud.Site.prototype.dbNames = function(){
    return this.dbs.map( function(z){ return z.name } );
}

Cloud.Site.prototype.findEnvironmentByName = function( name ){
    if ( ! name )
        return null;

    var ret = null;
    var ali = null;
    this.environments.forEach( function(z){

        if ( z.name == name )
            ret = z;

        if ( z.aliases && z.aliases.contains( name ) )
            ali = z;
    } );

    return ret || ali;
};

Cloud.Site.prototype.findEnvironmentById = function( iid ){
    if ( ! iid )
        return null;

    if ( isString( iid ) )
        iid = ObjectId( iid );

    var ret = null;
    this.environments.forEach( function(z){
        if ( z.iid == iid )
            ret = z;
    } );
    return ret;
};

/**
this returns the 10gen server name (prod1)
*/
Cloud.Site.prototype.getDatabaseServerForEnvironmentName = function( name ){
    name = name || "www";

    var env = this.findEnvironmentByName( name );

    if ( ! env )
        throw "can't find environment [" + name + "] choices [" + this.environmentNames() + "] site:" + this.name;

    var db = this.findDBByName( env.db );
    if ( ! db )
        throw "something is wrong, can't find db [" + env.db + "] choices [" + this.dbNames() + "]";

    if ( ! db.server )
	throw "we found db [" + env.db + "] but its misconfigured";

    return db.server;
}

Cloud.Site.prototype.findDBByName = function( name ){
    if ( ! name )
        return null;

    var ret = null;
    this.dbs.forEach( function(z){
        if ( z.name == name )
            ret = z;
    } );
    return ret;
};

Cloud.Site.prototype.findDBById = function( did ){
    if ( ! did )
        return null;

    if ( isString( did ) )
        did = ObjectId( did );

    var ret = null;
    this.dbs.forEach( function(z){
        if ( z.did == did )
            ret = z;
    } );
    return ret;
};

Cloud.Site.prototype.toString = function(){
    return "Site: " + this.name;
};

Cloud.Site.forName = function( name , create ){
    var s = db.sites.findOne( { name : name } );

    if ( s || ! create )
	return s;

    s = new Cloud.Site( name );
    db.sites.apply( s );
    return s;
};

db.sites.setConstructor( Cloud.Site );
if ( me.real ){
    db.sites.ensureIndex( { name : 1 } );
}
<commit_msg>method to get git branch names if its not hosted by us, will go and fetch<commit_after>// site1.js

/**
*    Copyright (C) 2008 10gen Inc.
*
*    This program is free software: you can redistribute it and/or  modify
*    it under the terms of the GNU Affero General Public License, version 3,
*    as published by the Free Software Foundation.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU Affero General Public License for more details.
*
*    You should have received a copy of the GNU Affero General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

Cloud.Environment = function(){
    this.branch = null;
    this.name = this.branch;
    this.db = null;
    this.pool = null;
    this.giturl = null;
    this.iid = ObjectId();
    this.aliases = [];
};

Cloud.SiteDB = function(){
    this.name = null;
    this.server = null;
    this.did = ObjectId();
};

Cloud.Site = function( name ){
    this.name = name;
    this.created = new Date();

    this.environments = [];
    this.environments._dbCons = Cloud.Environment;

    this.dbs = [];
    this.dbs._dbCons = Cloud.SiteDB;
};

Cloud.Site.prototype.environmentNames = function(){
    return this.environments.map( function(z){ return z.name } );
}

Cloud.Site.prototype.dbNames = function(){
    return this.dbs.map( function(z){ return z.name } );
}

Cloud.Site.prototype.findEnvironmentByName = function( name ){
    if ( ! name )
        return null;

    var ret = null;
    var ali = null;
    this.environments.forEach( function(z){

        if ( z.name == name )
            ret = z;

        if ( z.aliases && z.aliases.contains( name ) )
            ali = z;
    } );

    return ret || ali;
};

Cloud.Site.prototype.findEnvironmentById = function( iid ){
    if ( ! iid )
        return null;

    if ( isString( iid ) )
        iid = ObjectId( iid );

    var ret = null;
    this.environments.forEach( function(z){
        if ( z.iid == iid )
            ret = z;
    } );
    return ret;
};

/**
this returns the 10gen server name (prod1)
*/
Cloud.Site.prototype.getDatabaseServerForEnvironmentName = function( name ){
    name = name || "www";

    var env = this.findEnvironmentByName( name );

    if ( ! env )
        throw "can't find environment [" + name + "] choices [" + this.environmentNames() + "] site:" + this.name;

    var db = this.findDBByName( env.db );
    if ( ! db )
        throw "something is wrong, can't find db [" + env.db + "] choices [" + this.dbNames() + "]";

    if ( ! db.server )
	throw "we found db [" + env.db + "] but its misconfigured";

    return db.server;
}

Cloud.Site.prototype.findDBByName = function( name ){
    if ( ! name )
        return null;

    var ret = null;
    this.dbs.forEach( function(z){
        if ( z.name == name )
            ret = z;
    } );
    return ret;
};

Cloud.Site.prototype.findDBById = function( did ){
    if ( ! did )
        return null;

    if ( isString( did ) )
        did = ObjectId( did );

    var ret = null;
    this.dbs.forEach( function(z){
        if ( z.did == did )
            ret = z;
    } );
    return ret;
};

Cloud.Site.prototype.getGitBranchNames = function( force ){

    if ( ! this.giturl || this.giturl.startsWith( "ssh://git.10gen.com/data/gitroot/" ) ){
        var g = db.git.findOne( { name : "sites/" + this.name } );
        if ( ! g )
            return null;
        return g.branches.keySet();
    }

    var base = javaCreate( "java.io.File" , "/data/tmp/externalgit/" );
    base.mkdirs();
    var root = javaCreate( "java.io.File" , base , this.name );

    if ( ! root.exists() ){
        var msg = "clone [" + this.giturl + "] to [" + root + "]";

        log.git.info( msg );
        if ( ! javaStatic( "ed.util.GitUtils" , "clone" , this.giturl , base , this.name ) ){
            log.git.error( "failed " + msg );
            throw "couldn't " + msg;
        }
        force = true;
    }

    var now = new Date();

    var ts = javaCreate( "java.io.File" , root , ".git/10gents" );
    if ( ! ts.exists() ){
        force = true;
        ts.createNewFile();
    }
    else {
        if ( ( ts.lastModified() + ( 1000 * 60 * 5 ) ) < now.getTime() )
            force = true;
    }

    if ( force ){
        log.git.info( " doing full update for [" + this.name + "]" );
        javaStatic( "ed.util.GitUtils" , "fullUpdate" , root );
        ts.setLastModified( now.getTime() );
    }

    return javaStatic( "ed.util.GitUtils" , "getAllBranchAndTagNames" , root );
};

Cloud.Site.prototype.toString = function(){
    return "Site: " + this.name;
};

Cloud.Site.forName = function( name , create ){
    var s = db.sites.findOne( { name : name } );

    if ( s || ! create )
	return s;

    s = new Cloud.Site( name );
    db.sites.apply( s );
    return s;
};

db.sites.setConstructor( Cloud.Site );
if ( me.real ){
    db.sites.ensureIndex( { name : 1 } );
}
<|endoftext|>


<commit_before>/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

var gData = null;

$(document).ready(function() {
  $.ajaxSetup({
    cache:false
  });

  $.getJSON("measurements.json", function(result) {
    gData = result;
    renderVersions();
    update();

    $("#select_constraint").change(update);
    $("#select_version").change(update);
    $("#optout").change(update);
    $("#text_search").change(update);
    $("#search_constraint").change(update);
  });
});

function update() {
  var version_constraint = $("#select_constraint").val();
  var optout = $("#optout").prop("checked");
  var revision = $("#select_version").val();
  var text_search = $("#text_search").val();
  var text_constraint = $("#search_constraint").val();
  var measurements = gData.measurements;

  // No filtering? Just render everything.
  if ((revision == "any") && !optout && (text_search == "")) {
    renderMeasurements(measurements);
    return;
  }

  // Filter out by selected criteria.
  var filtered = {};

  $.each(measurements, (id, data) => {
    var history = data.history

    // Filter by optout.
    if (optout) {
      history = history.filter(m => m.optout);
    }

    // Filter for version constraint.
    if (revision != "any") {
      var version = parseInt(gData.revisions[revision].version);
      history = history.filter(m => {
        switch (version_constraint) {
          case "is_in":
            var first_ver = parseInt(gData.revisions[m.revisions.first].version);
            var last_ver = parseInt(gData.revisions[m.revisions.last].version);
            return (first_ver <= version) && (last_ver >= version);
          case "new_in":
            return m.revisions.first == revision;
          default:
            throw "Yuck, unknown selector.";
        }
      });
    }

    // Filter for text search.
    if (text_search != "") {
      var s = text_search.toLowerCase();
      var test = (str) => str.toLowerCase().includes(s);
      history = history.filter(h => {
        switch (text_constraint) {
          case "in_name": return test(data.name);
          case "in_description": return test(h.description);
          case "in_any": return test(data.name) || test(h.description);
          default: throw "Yuck, unsupported text search constraint.";
        }
      });
    }

    // Extract properties
    if (history.length > 0) {
      filtered[id] = {};
      for (var p of Object.keys(measurements[id])) {
        filtered[id][p] = measurements[id][p];
      }
      filtered[id]["history"] = history;
    }
  });

  renderMeasurements(filtered);
}

function renderVersions() {
  var select = $("#select_version");
  var versions = [];
  var versionToRev = {};

  $.each(gData.revisions, (rev, details) => {
    versions.push(details.version);
    versionToRev[details.version] = rev;
  });
  versions.sort().reverse();

  for (var version of versions) {
    var rev = versionToRev[version];
    select.append("<option value=\""+rev+"\" >"+version+"</option>");
  }
}

function getHistogramDistributionURL(name, type, min_version="null", max_version="null") {
  if (type != "histogram") {
    return "";
  }

  return `https://telemetry.mozilla.org/new-pipeline/dist.html#!` +
          `max_channel_version=release%252F${max_version}&`+
          `min_channel_version=release%252F${min_version}&` +
          `measure=${name}` +
          `&product=Firefox`;
}

function renderMeasurements(measurements) {
  var container = $("#measurements");
  var items = [];

  $.each(measurements, (id, data) => {
    items.push("
" + data.name + "
");

    var history = data.history;
    var first_version = h => gData.revisions[h["revisions"]["first"]].version;
    var last_version = h => gData.revisions[h["revisions"]["last"]].version;

    var columns = new Map([
      ["type", (d, h) => d.type],
      ["optout", (d, h) => h.optout],
      ["first", (d, h) => first_version(h)],
      ["last", (d, h) => last_version(h)],
      ["dist", (d, h) => `<a href="${getHistogramDistributionURL(d.name, d.type, first_version(h), last_version(h))}">#</a>`],
      ["description", (d, h) => h.description],
    ]);

    var table = "
";
    table += ("
" + [...columns.keys()].join("	") + "
");
    for (var h of history) {
      var cells = [...columns.values()].map(fn => fn(data, h));
      table += "
" + cells.join("	") + "
";
    }
    table += "
";
    items.push(table);
  });

  container.empty();
  container.append(items.join(""));
}
<commit_msg>Use keyup event for search input<commit_after>/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

var gData = null;

$(document).ready(function() {
  $.ajaxSetup({
    cache:false
  });

  $.getJSON("measurements.json", function(result) {
    gData = result;
    renderVersions();
    update();

    $("#select_constraint").change(update);
    $("#select_version").change(update);
    $("#optout").change(update);
    $("#text_search").keyup(update);
    $("#search_constraint").change(update);
  });
});

function update() {
  var version_constraint = $("#select_constraint").val();
  var optout = $("#optout").prop("checked");
  var revision = $("#select_version").val();
  var text_search = $("#text_search").val();
  var text_constraint = $("#search_constraint").val();
  var measurements = gData.measurements;

  // No filtering? Just render everything.
  if ((revision == "any") && !optout && (text_search == "")) {
    renderMeasurements(measurements);
    return;
  }

  // Filter out by selected criteria.
  var filtered = {};

  $.each(measurements, (id, data) => {
    var history = data.history

    // Filter by optout.
    if (optout) {
      history = history.filter(m => m.optout);
    }

    // Filter for version constraint.
    if (revision != "any") {
      var version = parseInt(gData.revisions[revision].version);
      history = history.filter(m => {
        switch (version_constraint) {
          case "is_in":
            var first_ver = parseInt(gData.revisions[m.revisions.first].version);
            var last_ver = parseInt(gData.revisions[m.revisions.last].version);
            return (first_ver <= version) && (last_ver >= version);
          case "new_in":
            return m.revisions.first == revision;
          default:
            throw "Yuck, unknown selector.";
        }
      });
    }

    // Filter for text search.
    if (text_search != "") {
      var s = text_search.toLowerCase();
      var test = (str) => str.toLowerCase().includes(s);
      history = history.filter(h => {
        switch (text_constraint) {
          case "in_name": return test(data.name);
          case "in_description": return test(h.description);
          case "in_any": return test(data.name) || test(h.description);
          default: throw "Yuck, unsupported text search constraint.";
        }
      });
    }

    // Extract properties
    if (history.length > 0) {
      filtered[id] = {};
      for (var p of Object.keys(measurements[id])) {
        filtered[id][p] = measurements[id][p];
      }
      filtered[id]["history"] = history;
    }
  });

  renderMeasurements(filtered);
}

function renderVersions() {
  var select = $("#select_version");
  var versions = [];
  var versionToRev = {};

  $.each(gData.revisions, (rev, details) => {
    versions.push(details.version);
    versionToRev[details.version] = rev;
  });
  versions.sort().reverse();

  for (var version of versions) {
    var rev = versionToRev[version];
    select.append("<option value=\""+rev+"\" >"+version+"</option>");
  }
}

function getHistogramDistributionURL(name, type, min_version="null", max_version="null") {
  if (type != "histogram") {
    return "";
  }

  return `https://telemetry.mozilla.org/new-pipeline/dist.html#!` +
          `max_channel_version=release%252F${max_version}&`+
          `min_channel_version=release%252F${min_version}&` +
          `measure=${name}` +
          `&product=Firefox`;
}

function renderMeasurements(measurements) {
  var container = $("#measurements");
  var items = [];

  $.each(measurements, (id, data) => {
    items.push("
" + data.name + "
");

    var history = data.history;
    var first_version = h => gData.revisions[h["revisions"]["first"]].version;
    var last_version = h => gData.revisions[h["revisions"]["last"]].version;

    var columns = new Map([
      ["type", (d, h) => d.type],
      ["optout", (d, h) => h.optout],
      ["first", (d, h) => first_version(h)],
      ["last", (d, h) => last_version(h)],
      ["dist", (d, h) => `<a href="${getHistogramDistributionURL(d.name, d.type, first_version(h), last_version(h))}">#</a>`],
      ["description", (d, h) => h.description],
    ]);

    var table = "
";
    table += ("
" + [...columns.keys()].join("	") + "
");
    for (var h of history) {
      var cells = [...columns.values()].map(fn => fn(data, h));
      table += "
" + cells.join("	") + "
";
    }
    table += "
";
    items.push(table);
  });

  container.empty();
  container.append(items.join(""));
}
<|endoftext|>


<commit_before>//This is where I would put my javascript code

// This is a comment that belongs only in my develop branch<commit_msg>Ryan Edited this file.<commit_after>//This is where I would put my javascript code

// This is a comment that belongs only in my develop branch
<|endoftext|>


<commit_before>/*
 * Rebind bootstrap UI components after Primefaces ajax calls
 */
function bind_bsui_components(){
    //console.log('bind_bsui_components');
    // Breadcrumb Tree Keep Open
    $(document).on('click', '.dropdown-menu', function (e) {
        $(this).hasClass('keep-open'),
        e.stopPropagation();
    });
    // Collapse Header Icons
    $('div[id^="collapse"]').on('shown.bs.collapse', function () {
      //console.log('hello block');
      $(this).siblings('div.panel-heading').children('span.glyphicon').removeClass("glyphicon-chevron-down").addClass("glyphicon-chevron-up");
    });

    $('div[id^="collapse"]').on('hidden.bs.collapse', function () {
      //console.log('goodbye block');
       $(this).siblings('div.panel-heading').children('span.glyphicon').removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
    });

    // Permissions + Dataset Tooltips/Popovers
    $("a[data-toggle='tooltip'], #citation span.glyphicon").tooltip({container: 'body'});
    $("a[data-toggle='popover']").popover();

}

/*
 * show breadcrumb navigation
 */
function show_breadcrumb(){
   $('#breadcrumbNavBlock').show();
}

/*
 * hide breadcrumb navigation
 */
function hide_breadcrumb(){
    $('#breadcrumbNavBlock').hide();
}

/*
 * Hide notification message
 */
function hide_info_msg(){
    if ($('div.messagePanel').length > 0){
        $('div.messagePanel').html('');
    }
}

/*
 * Show notification message
 */
function show_info_msg(mtitle, mtext){
   if ($('div.messagePanel').length > 0){
     //  alert('msg panel exists');
       edit_msg = '
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">x</button>'
                       + ''
                       + ' ' + mtitle + ' – ' + mtext + '
';
       $('div.messagePanel').html(edit_msg );
   }else{
     //console.log('message panel does not exist');
   }
}

/*
 * Called after "Edit Dataverse" - "General Information"
 */
function post_edit_dv_general_info(){
    show_info_msg('Edit Dataverse', 'Edit your dataverse and click Save Changes. Asterisks indicate required fields.');
    post_edit_dv();
}

/*
 * Called after "Edit Dataverse" - "Setup"
 */
function post_edit_dv_setup(){
    show_info_msg('Dataverse Setup', 'Edit the Metadata Blocks and Facets you want to associate with your dataverse. Note: facets will appear in the order shown on the list.');
    post_edit_dv();
}
/*
 * Called after "Edit Dataverse" -  "General Information" or "Setup"
 */
function post_edit_dv(){
   // alert('hallo');
   hide_breadcrumb();
   hide_search_panels();
   bind_bsui_components();
   //console.log('hide after edit3');
}

/*
 * Used after cancelling "Edit Dataverse"
 */
function post_cancel_edit_dv(){
   show_breadcrumb();
   show_search_panels()
   hide_info_msg();
   bind_bsui_components();
   //console.log('show after cancel edit3');
}

/*
 * Hide search panels when editing a dv
 */
function hide_search_panels(){
    if($(".panelSerchForm").length>0){
       $(".panelSerchForm").hide();
        if($(".panelSerchForm").next().length>0){
            $(".panelSerchForm").next().hide();
        }
   }
}

/*
 * Show search panels when cancel a dv edit
 */

function show_search_panels(){
    if($(".panelSerchForm").length>0){
        if($(".panelSerchForm").next().length>0){
            $(".panelSerchForm").next().show();
        }
       $(".panelSerchForm").show();
   }
}

/*
 * Called after "Upload + Edit Files"
 */
function post_edit_files(){
   //console.log('post_edit_files');
   hide_breadcrumb();
   bind_bsui_components();
   show_info_msg('Upload + Edit Dataset Files', 'You can drag and drop your files from your desktop, directly into the upload widget.');
}

/*
 * Called after "Edit Metadta"
 */
function post_edit_metadata(){
   //console.log('post_edit_metadata');
   hide_breadcrumb();
   bind_bsui_components();
   show_info_msg('Edit Dataset Metadata ', 'Add more metadata about your dataset to help others easily find it.');

}

/*
 *  Used when cancelling either "Upload + Edit Files" or "Edit Metadata"
 */
function post_cancel_edit_files_or_metadata(){
   //console.log('post_cancel_edit_metadata');
   show_breadcrumb();
   bind_bsui_components();
   hide_info_msg();
}
<commit_msg>Removed commented out alert from .js file<commit_after>/*
 * Rebind bootstrap UI components after Primefaces ajax calls
 */
function bind_bsui_components(){
    //console.log('bind_bsui_components');
    // Breadcrumb Tree Keep Open
    $(document).on('click', '.dropdown-menu', function (e) {
        $(this).hasClass('keep-open'),
        e.stopPropagation();
    });
    // Collapse Header Icons
    $('div[id^="collapse"]').on('shown.bs.collapse', function () {
      //console.log('hello block');
      $(this).siblings('div.panel-heading').children('span.glyphicon').removeClass("glyphicon-chevron-down").addClass("glyphicon-chevron-up");
    });

    $('div[id^="collapse"]').on('hidden.bs.collapse', function () {
      //console.log('goodbye block');
       $(this).siblings('div.panel-heading').children('span.glyphicon').removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
    });

    // Permissions + Dataset Tooltips/Popovers
    $("a[data-toggle='tooltip'], #citation span.glyphicon").tooltip({container: 'body'});
    $("a[data-toggle='popover']").popover();

}

/*
 * show breadcrumb navigation
 */
function show_breadcrumb(){
   $('#breadcrumbNavBlock').show();
}

/*
 * hide breadcrumb navigation
 */
function hide_breadcrumb(){
    $('#breadcrumbNavBlock').hide();
}

/*
 * Hide notification message
 */
function hide_info_msg(){
    if ($('div.messagePanel').length > 0){
        $('div.messagePanel').html('');
    }
}

/*
 * Show notification message
 */
function show_info_msg(mtitle, mtext){
   if ($('div.messagePanel').length > 0){
     //  alert('msg panel exists');
       edit_msg = '
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">x</button>'
                       + ''
                       + ' ' + mtitle + ' – ' + mtext + '
';
       $('div.messagePanel').html(edit_msg );
   }else{
     //console.log('message panel does not exist');
   }
}

/*
 * Called after "Edit Dataverse" - "General Information"
 */
function post_edit_dv_general_info(){
    show_info_msg('Edit Dataverse', 'Edit your dataverse and click Save Changes. Asterisks indicate required fields.');
    post_edit_dv();
}

/*
 * Called after "Edit Dataverse" - "Setup"
 */
function post_edit_dv_setup(){
    show_info_msg('Dataverse Setup', 'Edit the Metadata Blocks and Facets you want to associate with your dataverse. Note: facets will appear in the order shown on the list.');
    post_edit_dv();
}
/*
 * Called after "Edit Dataverse" -  "General Information" or "Setup"
 */
function post_edit_dv(){
   hide_breadcrumb();
   hide_search_panels();
   bind_bsui_components();
   //console.log('hide after edit3');
}

/*
 * Used after cancelling "Edit Dataverse"
 */
function post_cancel_edit_dv(){
   show_breadcrumb();
   show_search_panels()
   hide_info_msg();
   bind_bsui_components();
   //console.log('show after cancel edit3');
}

/*
 * Hide search panels when editing a dv
 */
function hide_search_panels(){
    if($(".panelSerchForm").length>0){
       $(".panelSerchForm").hide();
        if($(".panelSerchForm").next().length>0){
            $(".panelSerchForm").next().hide();
        }
   }
}

/*
 * Show search panels when cancel a dv edit
 */

function show_search_panels(){
    if($(".panelSerchForm").length>0){
        if($(".panelSerchForm").next().length>0){
            $(".panelSerchForm").next().show();
        }
       $(".panelSerchForm").show();
   }
}

/*
 * Called after "Upload + Edit Files"
 */
function post_edit_files(){
   //console.log('post_edit_files');
   hide_breadcrumb();
   bind_bsui_components();
   show_info_msg('Upload + Edit Dataset Files', 'You can drag and drop your files from your desktop, directly into the upload widget.');
}

/*
 * Called after "Edit Metadta"
 */
function post_edit_metadata(){
   //console.log('post_edit_metadata');
   hide_breadcrumb();
   bind_bsui_components();
   show_info_msg('Edit Dataset Metadata ', 'Add more metadata about your dataset to help others easily find it.');

}

/*
 *  Used when cancelling either "Upload + Edit Files" or "Edit Metadata"
 */
function post_cancel_edit_files_or_metadata(){
   //console.log('post_cancel_edit_metadata');
   show_breadcrumb();
   bind_bsui_components();
   hide_info_msg();
}
<|endoftext|>