<commit_before>/*
 Copyright 2016 Aleksandar Jankovic

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

const SocketManager = require('../library/SocketManager');
const LoginBox = require('../library/view/templates/LoginBox');
const Messenger = require('../library/view/templates/Messenger');
const Time = require('../library/view/templates/Time');
const OnlineStatus = require('../library/view/templates/OnlineStatus');
const KeyHandler = require('../library/KeyHandler');
const MainMenu = require('../library/view/templates/MainMenu');
const storage = require('../library/storage');
const textTools = require('../library/textTools');
const accessRestrictor = require('../library/accessRestrictor');
const aliasUpdater = require('../library/aliasUpdater');

const mainView = document.getElementById('main');
const onlineStatus = new OnlineStatus(document.getElementById('onlineStatus'));
const isTouchDevice = navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/iP(hone|ad|od)/i);

if (storage.getDeviceId() === null) {
  storage.setDeviceId(textTools.createAlphaNumbericalString(16, false));
}

if (!storage.getUserName()) {
  storage.setAccessLevel(0);
}

window.addEventListener('error', (event) => {
  /**
   * Reloads page
   * @private
   */
  function restart() {
    window.location.reload();
  }

  console.log(event.error);
  // setTimeout(restart, 3000);

  return false;
});

const socketManager = new SocketManager({ socket: io() }); // eslint-disable-line no-undef
const keyHandler = new KeyHandler();
const messenger = new Messenger({ isFullscreen: true, sendButtonText: 'Skicka', isTopDown: false, socketManager, keyHandler });
const topMenu = new MainMenu({ socketManager, keyHandler, parentElement: mainView });
const top = document.getElementById('top');

accessRestrictor.addAccessView(messenger);
accessRestrictor.addAccessView(topMenu);
topMenu.appendTo(top);

top.addEventListener('click', () => {
  topMenu.element.classList.toggle('hide');
});

const goFullScreen = () => {
  const element = document.documentElement;

  if (element.requestFullscreen) {
    element.requestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
  } else if (element.webkitRequestFullscreen) {
    element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
  } else if (element.mozRequestFullScreen) {
    element.mozRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
  }
};

keyHandler.addKey(112, goFullScreen);

if (isTouchDevice) {
  window.addEventListener('click', () => {
    goFullScreen();
  });
}

socketManager.addEvents([
  {
    event: 'disconnect',
    func: () => {
      onlineStatus.setOffline();
    },
  }, {
    event: 'reconnect',
    func: () => {
      onlineStatus.setOnline();
      socketManager.reconnectDone();
    },
  }, {
    event: 'startup',
    func: ({ yearModification }) => {
      storage.setLocalVal('yearModification', yearModification);

      messenger.toggleAccessElements(storage.getAccessLevel());
      messenger.appendTo(mainView);

      onlineStatus.setOnline();
      new Time(document.getElementById('time')).startClock();

      socketManager.emitEvent('updateId', {
        user: { userName: storage.getUserName() },
        device: { deviceId: storage.getDeviceId() },
      }, ({ error, data = {} }) => {
        if (error) {
          return;
        }

        const userName = storage.getUserName();

        if (userName && data.anonUser) {
          storage.removeUser();
          new LoginBox({
            description: ['Endast för Krismyndigheten och Försvarsmakten'],
            extraDescription: [
              'Din användare kunde inte hittas i databasen',
              'Ni behöver registrera en ny användare',
            ],
            parentElement: mainView,
            socketManager,
            keyHandler,
          }).appendTo(mainView);
        } else if (data.anonUser) {
          new LoginBox({
            description: ['Endast för Krismyndigheten och Försvarsmakten'],
            extraDescription: ['Skriv in ert användarnamn och lösenord'],
            parentElement: mainView,
            socketManager,
            keyHandler,
          }).appendTo(mainView);
        } else {
          aliasUpdater.updateAliasLists(storage.getAliases());
          console.log('I remember you');
        }

        accessRestrictor.toggleAllAccessViews(storage.getAccessLevel());

        socketManager.emitEvent('history', { lines: 10000 }, ({ data: historyData, historyError }) => {
          if (historyError) {
            console.log('history', historyError);

            return;
          }

          messenger.addMessages({ messages: historyData.messages, options: { printable: true }, shouldScroll: true });
        });
      });
    },
  }, {
    event: 'message',
    func: ({ message }) => {
      console.log(message);
    },
  }, {
    event: 'chatMsg',
    func: ({ message }) => {
      messenger.addMessage(message, { printable: true });
    },
  }, {
    event: 'chatMsgs',
    func: ({ messages }) => {
      messenger.addMessages({ options: { printable: true }, messages });
    },
  },
]);

messenger.addMessages({
  messages: [{
    time: new Date(2013, 6, 21, 23, 21, 0),
    text: ['Ryssland har invaderat. Explosioner i Stockholm, Göteborg, Malmö, Köpenhamn. Kommunikationsinfrastrukturen skadad. Totalförsvaret mobiliserat.'],
    userName: 'Centralen',
  }, {
    time: new Date(2013, 6, 22, 0, 2, 0),
    text: ['Kärnvapenexplosioner bekräftade i Stockholm, Göteborg, Malmö, Köpenhamn.'],
    userName: 'Centralen',
  }, {
    time: new Date(2014, 4, 14, 0, 0, 0),
    text: ['Tidfunktion trasig i systemet. Har ej tillgång till tekniker. Tappat kontakt med andra centraler.'],
    userName: 'Centralen',
  }, {
    time: new Date(2016, 1, 5, 0, 0, 0),
    text: ['Spridning av dödlig sjukdom. Leder till feber, utslag under armarna, hosta. Rekommenderar att undvika kontakt med andra människor.'],
    userName: 'Centralen',
  }, {
    time: new Date(2016, 1, 19, 0, 0, 0),
    text: ['Rosen är röd och nu är jag död.'],
    userName: 'Centralen',
  }, {
    time: new Date(2016, 1, 24, 0, 0, 0),
    text: ['HUVUDCENTRALEN HAR VARIT INAKTIV I 5 DAGAR. DETTA ÄR ETT AUTOMATISERAT MEDDELANDE'],
    userName: 'Centralen',
  }, {
    time: new Date(2044, 8, 10, 0, 0, 0),
    text: ['Test test'],
    userName: 'OKÄND SÄNDARE',
  }, {
    time: new Date(2044, 8, 10, 0, 0, 0),
    text: ['trst test med namn'],
    userName: 'Värnhem',
  }, {
    time: new Date(2044, 8, 10, 0, 0, 0),
    text: ['Östbacken online. tidstämpeln verkar inte fungera. kommer försöka hämta gamla meddelanden'],
    userName: 'Östbacken',
  }, {
    time: new Date(2044, 9, 30, 12, 7, 0),
    text: ['Rifall är inkopplat. Jag fick igång tidstämpeln och har lyckats hämta några gamla meddelanden från "Centralen"'],
    userName: 'Rifall',
  }],
  options: { printable: false },
  shouldScroll: true,
});
<commit_msg>Go into full screen on any click<commit_after>/*
 Copyright 2016 Aleksandar Jankovic

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

const SocketManager = require('../library/SocketManager');
const LoginBox = require('../library/view/templates/LoginBox');
const Messenger = require('../library/view/templates/Messenger');
const Time = require('../library/view/templates/Time');
const OnlineStatus = require('../library/view/templates/OnlineStatus');
const KeyHandler = require('../library/KeyHandler');
const MainMenu = require('../library/view/templates/MainMenu');
const storage = require('../library/storage');
const textTools = require('../library/textTools');
const accessRestrictor = require('../library/accessRestrictor');
const aliasUpdater = require('../library/aliasUpdater');

const mainView = document.getElementById('main');
const onlineStatus = new OnlineStatus(document.getElementById('onlineStatus'));
const isTouchDevice = navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/iP(hone|ad|od)/i);

if (storage.getDeviceId() === null) {
  storage.setDeviceId(textTools.createAlphaNumbericalString(16, false));
}

if (!storage.getUserName()) {
  storage.setAccessLevel(0);
}

window.addEventListener('error', (event) => {
  /**
   * Reloads page
   * @private
   */
  function restart() {
    window.location.reload();
  }

  console.log(event.error);
  // setTimeout(restart, 3000);

  return false;
});

const socketManager = new SocketManager({ socket: io() }); // eslint-disable-line no-undef
const keyHandler = new KeyHandler();
const messenger = new Messenger({ isFullscreen: true, sendButtonText: 'Skicka', isTopDown: false, socketManager, keyHandler });
const topMenu = new MainMenu({ socketManager, keyHandler, parentElement: mainView });
const top = document.getElementById('top');

accessRestrictor.addAccessView(messenger);
accessRestrictor.addAccessView(topMenu);
topMenu.appendTo(top);

top.addEventListener('click', () => {
  topMenu.element.classList.toggle('hide');
});

const goFullScreen = () => {
  const element = document.documentElement;

  if (element.requestFullscreen) {
    element.requestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
  } else if (element.webkitRequestFullscreen) {
    element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
  } else if (element.mozRequestFullScreen) {
    element.mozRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
  }
};

keyHandler.addKey(112, goFullScreen);
window.addEventListener('click', () => {
  goFullScreen();
});

socketManager.addEvents([
  {
    event: 'disconnect',
    func: () => {
      onlineStatus.setOffline();
    },
  }, {
    event: 'reconnect',
    func: () => {
      onlineStatus.setOnline();
      socketManager.reconnectDone();
    },
  }, {
    event: 'startup',
    func: ({ yearModification }) => {
      storage.setLocalVal('yearModification', yearModification);

      messenger.toggleAccessElements(storage.getAccessLevel());
      messenger.appendTo(mainView);

      onlineStatus.setOnline();
      new Time(document.getElementById('time')).startClock();

      socketManager.emitEvent('updateId', {
        user: { userName: storage.getUserName() },
        device: { deviceId: storage.getDeviceId() },
      }, ({ error, data = {} }) => {
        if (error) {
          return;
        }

        const userName = storage.getUserName();

        if (userName && data.anonUser) {
          storage.removeUser();
          new LoginBox({
            description: ['Endast för Krismyndigheten och Försvarsmakten'],
            extraDescription: [
              'Din användare kunde inte hittas i databasen',
              'Ni behöver registrera en ny användare',
            ],
            parentElement: mainView,
            socketManager,
            keyHandler,
          }).appendTo(mainView);
        } else if (data.anonUser) {
          new LoginBox({
            description: ['Endast för Krismyndigheten och Försvarsmakten'],
            extraDescription: ['Skriv in ert användarnamn och lösenord'],
            parentElement: mainView,
            socketManager,
            keyHandler,
          }).appendTo(mainView);
        } else {
          aliasUpdater.updateAliasLists(storage.getAliases());
          console.log('I remember you');
        }

        accessRestrictor.toggleAllAccessViews(storage.getAccessLevel());

        socketManager.emitEvent('history', { lines: 10000 }, ({ data: historyData, historyError }) => {
          if (historyError) {
            console.log('history', historyError);

            return;
          }

          messenger.addMessages({ messages: historyData.messages, options: { printable: true }, shouldScroll: true });
        });
      });
    },
  }, {
    event: 'message',
    func: ({ message }) => {
      console.log(message);
    },
  }, {
    event: 'chatMsg',
    func: ({ message }) => {
      messenger.addMessage(message, { printable: true });
    },
  }, {
    event: 'chatMsgs',
    func: ({ messages }) => {
      messenger.addMessages({ options: { printable: true }, messages });
    },
  },
]);

messenger.addMessages({
  messages: [{
    time: new Date(2013, 6, 21, 23, 21, 0),
    text: ['Ryssland har invaderat. Explosioner i Stockholm, Göteborg, Malmö, Köpenhamn. Kommunikationsinfrastrukturen skadad. Totalförsvaret mobiliserat.'],
    userName: 'Centralen',
  }, {
    time: new Date(2013, 6, 22, 0, 2, 0),
    text: ['Kärnvapenexplosioner bekräftade i Stockholm, Göteborg, Malmö, Köpenhamn.'],
    userName: 'Centralen',
  }, {
    time: new Date(2014, 4, 14, 0, 0, 0),
    text: ['Tidfunktion trasig i systemet. Har ej tillgång till tekniker. Tappat kontakt med andra centraler.'],
    userName: 'Centralen',
  }, {
    time: new Date(2016, 1, 5, 0, 0, 0),
    text: ['Spridning av dödlig sjukdom. Leder till feber, utslag under armarna, hosta. Rekommenderar att undvika kontakt med andra människor.'],
    userName: 'Centralen',
  }, {
    time: new Date(2016, 1, 19, 0, 0, 0),
    text: ['Rosen är röd och nu är jag död.'],
    userName: 'Centralen',
  }, {
    time: new Date(2016, 1, 24, 0, 0, 0),
    text: ['HUVUDCENTRALEN HAR VARIT INAKTIV I 5 DAGAR. DETTA ÄR ETT AUTOMATISERAT MEDDELANDE'],
    userName: 'Centralen',
  }, {
    time: new Date(2044, 8, 10, 0, 0, 0),
    text: ['Test test'],
    userName: 'OKÄND SÄNDARE',
  }, {
    time: new Date(2044, 8, 10, 0, 0, 0),
    text: ['trst test med namn'],
    userName: 'Värnhem',
  }, {
    time: new Date(2044, 8, 10, 0, 0, 0),
    text: ['Östbacken online. tidstämpeln verkar inte fungera. kommer försöka hämta gamla meddelanden'],
    userName: 'Östbacken',
  }, {
    time: new Date(2044, 9, 30, 12, 7, 0),
    text: ['Rifall är inkopplat. Jag fick igång tidstämpeln och har lyckats hämta några gamla meddelanden från "Centralen"'],
    userName: 'Rifall',
  }],
  options: { printable: false },
  shouldScroll: true,
});
<|endoftext|>


<commit_before>
<commit_msg>Update moves.js<commit_after>'use strict';

exports.BattleMovedex = {
  	"scald": {
  	  inherit: true,
	  	onModifyMove: function (power, user) {
	  		if (user.template.id === 'simipour') return move.secondaries[i].chance = 100;
	    },
  	},
};
<|endoftext|>


<commit_before><commit_msg>自动生成代码：修改 C++ vector 类型为 vector<string><commit_after><|endoftext|>


<commit_before>/**
 * Releases notices of console logs, and meters number of console logs.
 */

exports.version = '0.1';

exports.module = function(phantomas) {
	var cmsgs = [];

	phantomas.on('consoleLog', function(msg) {
		cmsgs.push(msg);
	});

	phantomas.on('report', function() {
		phantomas.setMetric('consoleMessages', cmsgs.length);

		if (cmsgs.length > 0) {
			phantomas.addNotice('Console Messages (' + cmsgs.length + '):');
			cmsgs.forEach(function(msg) {
				phantomas.addNotice(' ' + msg);
			});
			phantomas.addNotice();
		}
	});
};
<commit_msg>Remove notices for console logging<commit_after>/**
 * Releases notices of console logs, and meters number of console logs.
 */

exports.version = '0.1';

exports.module = function(phantomas) {
	var cmsgs = [];

	phantomas.on('consoleLog', function(msg) {
		cmsgs.push(msg);
	});

	phantomas.on('report', function() {
		phantomas.setMetric('consoleMessages', cmsgs.length);
	});
};
<|endoftext|>


<commit_before>var execSync = require('child_process').execSync;
var execAsync = require('child_process').exec;
var numeral = require('numeral');

exports.pdfmerge = function merge(conf, job, res, next) {
    if (conf.speechComments) {
        execSync("say 'PDF-Verarbeitung gestartet'");
    } else {
        console.log("pdfmerge started");
    }

};

var execSync = require('child_process').execSync;
var execAsync = require('child_process').exec;
var fs = require('fs');
var mime = require('mime');
var async = require('async');
var http = require('http');
var https = require('https');
var path = require('path');

exports.pdfmerge = function merge(conf, job, res, next) {
    var nonce = job.name + "-" + Math.floor(Math.random() * 10000000);
    if (conf.speechComments) {
        execSync("say 'PDF-Verarbeitung gestartet'");
    } else {
        console.log("pdfmerge started");
    }

    //Mkdirs
    var jobdir = conf.tmpFolder + "/job-pdf-merge-" + nonce;
    var indir = jobdir + "/in"
    fs.mkdirSync(jobdir);
    fs.mkdirSync(indir);

    //Download
    var threads = 15;
    var i = 0;
    async.eachLimit(job.files, threads, function (task, next) {
        var prefix = numeral(i).format('000');
        i++;
        var filename = path.basename(task.uri);
        var file = fs.createWriteStream(indir + "/" + prefix + "-" + task.folder + "-" + filename);
        if ((task.uri.startsWith("https"))) {
            var request = https.get(task.uri, function (response) {
                response.pipe(file);
                file.on('finish', function () {
                    file.close();
                    next();
                });
            });
        } else {
            var request = http.get(task.uri, function (response) {
                response.pipe(file);
                file.on('finish', function () {
                    file.close();
                    next();
                });
            });
        }
    }, function () {
        console.log(job.files.length + ' downloads finished');
        //Zip the results
        var zipCmd = "pdftk *.pdf cat output ../out.pdf"
        execAsync(zipCmd, {
            "cwd": indir
        }, function (error, stdout, stderr) {

            if (error) {
                console.log("ERROR");
                console.log(error);
            } else {
                //return the result
                var filepath = jobdir + "/out.pdf";
                fs.readFile(filepath, function (err, data) {
                    if (err) {
                        res.writeHead(500);
                        res.end(":--( : " + err);
                        next(err);
                        return;
                    }

                    res.contentType = mime.lookup(filepath);
                    res.writeHead(200, {
                        "Content-Disposition": "attachment;filename=" + job.name + ".pdf"
                    });
                    res.end(data);
                    return next();
                });
            }
        });
    });
}<commit_msg>working on #2: eliminate console.logs<commit_after>var execSync = require('child_process').execSync;
var execAsync = require('child_process').exec;
var numeral = require('numeral');

exports.pdfmerge = function merge(conf, job, res, next) {
    if (conf.speechComments) {
        execSync("say 'PDF-Verarbeitung gestartet'");
    } else {
        console.log("pdfmerge started");
    }

};

var execSync = require('child_process').execSync;
var execAsync = require('child_process').exec;
var fs = require('fs');
var mime = require('mime');
var async = require('async');
var http = require('http');
var https = require('https');
var path = require('path');

exports.pdfmerge = function merge(conf, job, res, next) {
    var nonce = job.name + "-" + Math.floor(Math.random() * 10000000);
    if (conf.speechComments) {
        execSync("say 'PDF-Verarbeitung gestartet'");
    } else {
        //console.log("pdfmerge started");
    }

    //Mkdirs
    var jobdir = conf.tmpFolder + "/job-pdf-merge-" + nonce;
    var indir = jobdir + "/in"
    fs.mkdirSync(jobdir);
    fs.mkdirSync(indir);

    //Download
    var threads = 15;
    var i = 0;
    async.eachLimit(job.files, threads, function (task, next) {
        var prefix = numeral(i).format('000');
        i++;
        var filename = path.basename(task.uri);
        var file = fs.createWriteStream(indir + "/" + prefix + "-" + task.folder + "-" + filename);
        if ((task.uri.startsWith("https"))) {
            var request = https.get(task.uri, function (response) {
                response.pipe(file);
                file.on('finish', function () {
                    file.close();
                    next();
                });
            });
        } else {
            var request = http.get(task.uri, function (response) {
                response.pipe(file);
                file.on('finish', function () {
                    file.close();
                    next();
                });
            });
        }
    }, function () {
        //console.log(job.files.length + ' downloads finished');
        //Zip the results
        var zipCmd = "pdftk *.pdf cat output ../out.pdf"
        execAsync(zipCmd, {
            "cwd": indir
        }, function (error, stdout, stderr) {

            if (error) {
                console.log("ERROR");
                console.log(error);
            } else {
                //return the result
                var filepath = jobdir + "/out.pdf";
                fs.readFile(filepath, function (err, data) {
                    if (err) {
                        res.writeHead(500);
                        res.end(":--( : " + err);
                        next(err);
                        return;
                    }

                    res.contentType = mime.lookup(filepath);
                    res.writeHead(200, {
                        "Content-Disposition": "attachment;filename=" + job.name + ".pdf"
                    });
                    res.end(data);
                    return next();
                });
            }
        });
    });
}<|endoftext|>


<commit_before>/**
 * Project info config object
 *
 * All params optional unless
 * otherwise noted
 *
 * @params {
 *  string  name               (required) The built theme dirname and the theme text-domain
 *  string  prettyName         (required) The theme name as shown in the theme selector admin
 *  string  themeURI           The theme's URI
 *  string  description        A short description of the theme
 *  string  parentTheme        If this is a child theme, then put the parent
 *                             theme's directory name here
 *  string  version            The theme's version
 *  string  author             The theme's author
 *  string  authorURI          The theme author's URI
 *  string  license            The theme's license
 *  string  licenseURI         The theme license's URI
 *  array   tags               Keywords that could be associated with the theme
 * }
 */
module.exports = {
	name: 'usine',
	prettyName: 'Usine',
	themeURI: 'https://github.com/usine/wp-usine',
	githubThemeURI: 'https://github.com/usine/wp-usine',
	releaseAsset: 'true',
	description: 'The 2016 theme for usine.ch. Built by Mehdi Lahlou',
	version: '1.3.1',
	author: 'Mehdi Lahlou <mehdi.lahlou@free.fr>',
	authorURI: 'https://github.com/medfreeman',
	license: 'GPLv2 or later'
};
<commit_msg>project version bump to 1.3.2<commit_after>/**
 * Project info config object
 *
 * All params optional unless
 * otherwise noted
 *
 * @params {
 *  string  name               (required) The built theme dirname and the theme text-domain
 *  string  prettyName         (required) The theme name as shown in the theme selector admin
 *  string  themeURI           The theme's URI
 *  string  description        A short description of the theme
 *  string  parentTheme        If this is a child theme, then put the parent
 *                             theme's directory name here
 *  string  version            The theme's version
 *  string  author             The theme's author
 *  string  authorURI          The theme author's URI
 *  string  license            The theme's license
 *  string  licenseURI         The theme license's URI
 *  array   tags               Keywords that could be associated with the theme
 * }
 */
module.exports = {
	name: 'usine',
	prettyName: 'Usine',
	themeURI: 'https://github.com/usine/wp-usine',
	githubThemeURI: 'https://github.com/usine/wp-usine',
	releaseAsset: 'true',
	description: 'The 2016 theme for usine.ch. Built by Mehdi Lahlou',
	version: '1.3.2',
	author: 'Mehdi Lahlou <mehdi.lahlou@free.fr>',
	authorURI: 'https://github.com/medfreeman',
	license: 'GPLv2 or later'
};
<|endoftext|>


<commit_before>/* global _ */

/*
 * Complex scripted dashboard
 * This script generates a dashboard object that Grafana can load. It also takes a number of user
 * supplied URL parameters (int ARGS variable)
 *
 * Return a dashboard object, or a function
 *
 * For async scripts, return a function, this function must take a single callback function as argument,
 * call this callback function with the dashboard object (look at scripted_async.js for an example)
 */

// accessable variables in this scope
var window, document, ARGS, $, jQuery, moment, kbn;

// Setup some variables
var dashboard;

// All url parameters are available via the ARGS object
var ARGS;

// Intialize a skeleton with nothing but a rows array and service object
dashboard = {
  rows : [],
};

// Set default time
// time can be overriden in the url using from/to parameteres, but this is
// handled automatically in grafana core during dashboard initialization
dashboard.time = {
  from: "now-6h",
  to: "now"
};

// InfluxDB setup
var influxUser = 'root';
var influxPass = 'root';
var influxDB = 'graphite';

if(!_.isUndefined(ARGS.host)) {
  var host = ARGS.host;
}

if(!_.isUndefined(ARGS.metric)) {
  var displayMetric = ARGS.metric;
}

// Set a title
dashboard.title = 'Scripted Dashboard for ' + host;

// function to get series from influxdb
var getHostSeries = function (host) {
  var query_url = window.location.protocol + '//'+ window.location.host +
                   ':8086/db/' + influxDB + '/series?u=' + influxUser + '&p=' + influxPass +
                   '&q=list series /\.' + host + '\./';
  var res = [];
  var req = new XMLHttpRequest();
  req.open('GET', query_url, false);
  req.send();
  var obj = JSON.parse(req.responseText)[0].points;
  obj.forEach(function (a) {
    res.push(a[1]);
  });
  return res;
};

// function to generate target object
var targetGen = function (series, alias, interval, column, apply) {
  return {
    'series': series,
    'alias': alias,
    'column': (column === undefined) ? 'value' : column,
    'interval': (interval === undefined) ? '1m' : interval,
    'function': (apply === undefined) ? 'mean' : apply,
  };
};

var targetsGen = function (series, span, interval, grapghConf) {
  var targets = [];
  var aliasColors = {};
  for (var match in grapghConf) {
    for (var i = 0; i < series.length; i++) {
      var s = series[i];
      if (s.lastIndexOf(match) === s.length - match.length) {
        var alias = s.split('.')[2] + '.' + match;
        var column = grapghConf[match].column;
        var apply = grapghConf[match].apply;
        targets.push(targetGen(s, alias, interval, column, apply));
        aliasColors[alias] = grapghConf[match].color;
      }
    }
  }
  return {
    'targets': targets,
    'aliasColors': aliasColors,
  };
};

var panelFactory = function (gConf) {
  return function (series, span, interval) {
    span = (span === undefined) ? 12 : span;
    interval = (interval === undefined) ? '1m' : interval;
    var result = {};
    var graph = gConf.graph;
    var targets = targetsGen(series, span, interval, graph);
    var panel = {
      'title': 'Default Title',
      'type': 'graphite',
      'span': span,
      'y_formats': [ 'none' ],
      'grid': { 'max': null, 'min': null },
      'lines': true,
      'fill': 1,
      'linewidth': 1,
      'nullPointMode': 'null',
      'targets': targets.targets,
      'aliasColors': targets.aliasColors,
    };

    if (('title' in gConf.panel) && (gConf.panel.title.match('@metric'))) {
      result = $.extend(result, panel, gConf.panel,
          { 'title': gConf.panel.title.replace('@metric', series[0].split('.')[2]) });
    } else {
      result = $.extend(result, panel, gConf.panel);
    }

    return result;
 };
};

var gCpu = {
  'graph': {
    'system': { 'color': '#EAB839' },
    'user': { 'color': '#508642' },
    'idle': { 'color': '#303030' },
    'wait': { 'color': '#890F02' },
    'steal': { 'color': '#E24D42'},
    'nice': { 'color': '#9400D3' },
    'softirq': {'color': '#E9967A' },
    'interrupt': { 'color': '#1E90FF' },
  },
  'panel': {
    'title': 'CPU',
    'y_formats': [ 'percent' ],
    'grid': { 'max': null, 'min': 0 },
    'lines': false,
    'bars': true,
    'stack': true,
    'legend': { 'show': true },
    'percentage': true,
  },
};

var gMemory = {
  'graph': {
    'used': { 'color': '#1F78C1' },
    'cached': { 'color': '#EF843C' },
    'buffered': { 'color': '#CCA300' },
    'free': { 'color': '#629E51' },
  },
  'panel': {
    'title': 'Memory',
    'y_formats': [ 'bytes' ],
    'grid': { 'max': null, 'min': 0 },
    'stack': true,
  },
};

var gLoad = {
  'graph': {
    'midterm': { 'color': '#7B68EE' },
  },
  'panel': {
    'title': 'Load Average',
    'grid': { 'max': null, 'min': 0 },
  },
};

var gSwap = {
  'graph': {
    'used': { 'color': '#1F78C1' },
    'cached': { 'color': '#EAB839' },
    'free': { 'color': '#508642' },
  },
  'panel': {
    'title': 'Swap',
    'y_formats': [ 'bytes' ],
    'grid': { 'max': null, 'min': 0, 'leftMin': 0 },
    'stack': true,
  },
};

var gNetworkTraffic = {
  'graph': {
    'octets.rx': { 'color': '#447EBC' },
    'octets.tx': { 'color': '#508642', 'column': 'value*-1' },
  },
  'panel': {
    'title': 'Network Traffic on @metric',
    'y_formats': [ 'bytes' ],
  },
};

var gNetworkPackets = {
  'graph': {
    'packets.rx': { 'color': '#447EBC' },
    'packets.tx': { 'color': '#508642', 'column': 'value*-1' },
  },
  'panel': {
    'title': 'Network Packets on @metric',
  },
};

var gDiskDf = {
  'graph': {
    'complex-used': { 'color': '#447EBC' },
    'complex-reserved': { 'color': '#EAB839' },
    'complex-free': { 'color': '#508642' },
  },
  'panel': {
    'title': 'Disk space for @metric',
    'y_formats': [ 'bytes' ],
    'grid': { 'max': null, 'min': 0, 'leftMin': 0 },
    'stack': true,
  },
};

var gDiskIO = {
  'graph': {
    'ops.write': { 'color': '#447EBC' },
    'ops.read': { 'color': '#508642', 'column': 'value*-1' },
  },
  'panel': {
    'title': 'Disk IO for @metric',
  },
};

var gPsState = {
  'graph': {
    'sleeping': { 'color': '#EAB839', 'apply': 'max' },
    'running': { 'color': '#508642', 'apply': 'max' },
    'stopped': { 'color': '#E9967A', 'apply': 'max' },
    'blocked': { 'color': '#890F02', 'apply': 'max' },
    'zombies': { 'color': '#E24D42', 'apply': 'max' },
    'paging': { 'color': '#9400D3', 'apply': 'max' },
  },
  'panel': {
    'title': 'Processes State',
    'y_formats': [ 'short' ],
    'grid': { 'max': null, 'min': 0 },
  },
};

var gPsForks = {
  'graph': {
    'fork_rate': { 'color': '#81BEF7', 'apply': 'max' },
  },
  'panel': {
    'title': 'Processes Fork Rate',
    'y_formats': [ 'short' ],
    'grid': { 'max': null, 'min': 0 },
  },
};

// Redis plugin used: https://github.com/powdahound/redis-collectd-plugin
var gRedisMemory = {
  'graph': {
    'used_memory': { 'color': '#447EBC' },
  },
  'panel': {
    'title': 'Redis Memomy',
    'y_formats': [ 'bytes' ],
  },
};

var gMemcachedMemory = {
  'graph': {
    'cache.used': { 'color': '#447EBC' },
    'cache.free': { 'color': '#508642' },
  },
  'panel': {
    'title': 'Memcached Memomy',
    'y_formats': [ 'bytes' ],
    'stack': true,
  },
};

var gMemcachedConns = {
  'graph': {
    'connections-current': { 'color': '#447EBC' },
  },
  'panel': {
    'title': 'Memcached Connections',
    'grid': { 'max': null, 'min': 0, 'leftMin': 0 },
  },
};

var gMemcachedItems = {
  'graph': {
    'items-current': { 'color': '#447EBC' },
  },
  'panel': {
    'title': 'Memcached Items',
    'grid': { 'max': null, 'min': 0, 'leftMin': 0 },
  },
};

var gMemcachedCommands = {
  'graph': {
    'command-flush': { 'color': '#447EBC' },
    'command-get': { 'color': '#508642' },
    'command-set': { 'color': '#E9967A' },
    'command-touch': { 'color': '#890F02' },
  },
  'panel': {
    'title': 'Memcached Commands',
    'grid': { 'max': null, 'min': 0, 'leftMin': 0 },
  },
};

var setupRow = function (title, panels) {
  return {
    'title': title,
    'height': '250px',
    'panels': panels,
    'grid': { 'max': null, 'min': 0 },
  };
};

var supportedDashs = {
  'cpu': {
    'func': [ panelFactory(gCpu) ],
  },
  'load': {
    'func': [ panelFactory(gLoad) ],
  },
  'memory': {
    'func': [ panelFactory(gMemory) ],
  },
  'swap': {
    'func': [ panelFactory(gSwap) ],
  },
  'interface': {
    'func': [ panelFactory(gNetworkTraffic),
              panelFactory(gNetworkPackets),
            ],
    'multi': true,
  },
  'df': {
    'func': [ panelFactory(gDiskDf) ],
    'multi': true,
  },
  'disk': {
    'func': [ panelFactory(gDiskIO) ],
    'multi': true,
    'regexp': /\d$/
  },
  'processes': {
    'func': [ panelFactory(gPsState),
              panelFactory(gPsForks),
            ],
  },
  'redis' : {
    'func': [ panelFactory(gRedisMemory),
            ],
  },
  'memcache' : {
    'func': [ panelFactory(gMemcachedMemory),
              panelFactory(gMemcachedConns),
              panelFactory(gMemcachedItems),
              panelFactory(gMemcachedCommands),
            ],
  },
};

var showDashs = {};

if (displayMetric) {
  displayMetric.split(',').forEach(function (metric) {
    if (metric in supportedDashs) {
      showDashs[metric] = supportedDashs[metric];
    }
  });
} else {
  showDashs = supportedDashs;
}

var getExtendedMetrics = function (series, prefix) {
  var metricsExt = [];
  var postfix = '';
  for (var i = 0; i < series.length; i++) {
    if (series[i].indexOf(prefix) === 0) {
      postfix = series[i].slice(prefix.length);
      postfix = postfix.slice(0, postfix.indexOf('.'));
      if (metricsExt.indexOf(postfix) === -1) {
        metricsExt.push(postfix);
      }
    }
  }
  return metricsExt;
};

var pfx = 'collectd.' + host;
var postfix = '';
var hostSeries = getHostSeries(host);

// Skip empty Dashboard setup if there are no series.
if (hostSeries.length === 0) {
  return dashboard;
}

for (var metric in showDashs) {
  var matchedSeries = [];
  var pfxMetric = pfx + '.' + metric;
  for (var i = 0; i < hostSeries.length; i++) {
    if ((hostSeries[i].indexOf(pfxMetric) === 0) &&
        (!('regexp' in showDashs[metric]) ||
         ('regexp' in showDashs[metric] &&
          showDashs[metric].regexp.test(hostSeries[i].split('.')[2])))) {
      matchedSeries.push(hostSeries[i]);
    }
  }
  if (matchedSeries.length === 0) {
    continue;
  }
  if (showDashs[metric].multi) {
    metricsExt = getExtendedMetrics(matchedSeries, pfx + '.');
    if (metricsExt.length > 1) {
      for (var k = 0; k < metricsExt.length; k++) {
        var metricExt = metricsExt[k];
        var rematchedSeries = [];
        var repfxMetric = pfx + '.' + metricExt + '.';
        for (var i = 0; i < matchedSeries.length; i++) {
          if (matchedSeries[i].indexOf(repfxMetric) === 0) {
            rematchedSeries.push(matchedSeries[i]);
          }
        }
        for (var j = 0; j < showDashs[metric].func.length; j++) {
          metricFunc = showDashs[metric].func[j];
          dashboard.rows.push(setupRow(metricExt.toUpperCase, [metricFunc(rematchedSeries, 12, '1m')]));
        }
      }
     continue;
    }
  }
  for (var j = 0; j < showDashs[metric].func.length; j++) {
    metricFunc = showDashs[metric].func[j];
    dashboard.rows.push(setupRow(metric.toUpperCase, [metricFunc(matchedSeries, 12, '1m')]));
  }
}

return dashboard;
<commit_msg>Added Redis commands dash.<commit_after>/* global _ */

/*
 * Complex scripted dashboard
 * This script generates a dashboard object that Grafana can load. It also takes a number of user
 * supplied URL parameters (int ARGS variable)
 *
 * Return a dashboard object, or a function
 *
 * For async scripts, return a function, this function must take a single callback function as argument,
 * call this callback function with the dashboard object (look at scripted_async.js for an example)
 */

// accessable variables in this scope
var window, document, ARGS, $, jQuery, moment, kbn;

// Setup some variables
var dashboard;

// All url parameters are available via the ARGS object
var ARGS;

// Intialize a skeleton with nothing but a rows array and service object
dashboard = {
  rows : [],
};

// Set default time
// time can be overriden in the url using from/to parameteres, but this is
// handled automatically in grafana core during dashboard initialization
dashboard.time = {
  from: "now-6h",
  to: "now"
};

// InfluxDB setup
var influxUser = 'root';
var influxPass = 'root';
var influxDB = 'graphite';

if(!_.isUndefined(ARGS.host)) {
  var host = ARGS.host;
}

if(!_.isUndefined(ARGS.metric)) {
  var displayMetric = ARGS.metric;
}

// Set a title
dashboard.title = 'Scripted Dashboard for ' + host;

// function to get series from influxdb
var getHostSeries = function (host) {
  var query_url = window.location.protocol + '//'+ window.location.host +
                   ':8086/db/' + influxDB + '/series?u=' + influxUser + '&p=' + influxPass +
                   '&q=list series /\.' + host + '\./';
  var res = [];
  var req = new XMLHttpRequest();
  req.open('GET', query_url, false);
  req.send();
  var obj = JSON.parse(req.responseText)[0].points;
  obj.forEach(function (a) {
    res.push(a[1]);
  });
  return res;
};

// function to generate target object
var targetGen = function (series, alias, interval, column, apply) {
  return {
    'series': series,
    'alias': alias,
    'column': (column === undefined) ? 'value' : column,
    'interval': (interval === undefined) ? '1m' : interval,
    'function': (apply === undefined) ? 'mean' : apply,
  };
};

var targetsGen = function (series, span, interval, grapghConf) {
  var targets = [];
  var aliasColors = {};
  for (var match in grapghConf) {
    for (var i = 0; i < series.length; i++) {
      var s = series[i];
      if (s.lastIndexOf(match) === s.length - match.length) {
        var alias = s.split('.')[2] + '.' + match;
        var column = grapghConf[match].column;
        var apply = grapghConf[match].apply;
        targets.push(targetGen(s, alias, interval, column, apply));
        aliasColors[alias] = grapghConf[match].color;
      }
    }
  }
  return {
    'targets': targets,
    'aliasColors': aliasColors,
  };
};

var panelFactory = function (gConf) {
  return function (series, span, interval) {
    span = (span === undefined) ? 12 : span;
    interval = (interval === undefined) ? '1m' : interval;
    var result = {};
    var graph = gConf.graph;
    var targets = targetsGen(series, span, interval, graph);
    var panel = {
      'title': 'Default Title',
      'type': 'graphite',
      'span': span,
      'y_formats': [ 'none' ],
      'grid': { 'max': null, 'min': null },
      'lines': true,
      'fill': 1,
      'linewidth': 1,
      'nullPointMode': 'null',
      'targets': targets.targets,
      'aliasColors': targets.aliasColors,
    };

    if (('title' in gConf.panel) && (gConf.panel.title.match('@metric'))) {
      result = $.extend(result, panel, gConf.panel,
          { 'title': gConf.panel.title.replace('@metric', series[0].split('.')[2]) });
    } else {
      result = $.extend(result, panel, gConf.panel);
    }

    return result;
 };
};

var gCpu = {
  'graph': {
    'system': { 'color': '#EAB839' },
    'user': { 'color': '#508642' },
    'idle': { 'color': '#303030' },
    'wait': { 'color': '#890F02' },
    'steal': { 'color': '#E24D42'},
    'nice': { 'color': '#9400D3' },
    'softirq': {'color': '#E9967A' },
    'interrupt': { 'color': '#1E90FF' },
  },
  'panel': {
    'title': 'CPU',
    'y_formats': [ 'percent' ],
    'grid': { 'max': null, 'min': 0 },
    'lines': false,
    'bars': true,
    'stack': true,
    'legend': { 'show': true },
    'percentage': true,
  },
};

var gMemory = {
  'graph': {
    'used': { 'color': '#1F78C1' },
    'cached': { 'color': '#EF843C' },
    'buffered': { 'color': '#CCA300' },
    'free': { 'color': '#629E51' },
  },
  'panel': {
    'title': 'Memory',
    'y_formats': [ 'bytes' ],
    'grid': { 'max': null, 'min': 0 },
    'stack': true,
  },
};

var gLoad = {
  'graph': {
    'midterm': { 'color': '#7B68EE' },
  },
  'panel': {
    'title': 'Load Average',
    'grid': { 'max': null, 'min': 0 },
  },
};

var gSwap = {
  'graph': {
    'used': { 'color': '#1F78C1' },
    'cached': { 'color': '#EAB839' },
    'free': { 'color': '#508642' },
  },
  'panel': {
    'title': 'Swap',
    'y_formats': [ 'bytes' ],
    'grid': { 'max': null, 'min': 0, 'leftMin': 0 },
    'stack': true,
  },
};

var gNetworkTraffic = {
  'graph': {
    'octets.rx': { 'color': '#447EBC' },
    'octets.tx': { 'color': '#508642', 'column': 'value*-1' },
  },
  'panel': {
    'title': 'Network Traffic on @metric',
    'y_formats': [ 'bytes' ],
  },
};

var gNetworkPackets = {
  'graph': {
    'packets.rx': { 'color': '#447EBC' },
    'packets.tx': { 'color': '#508642', 'column': 'value*-1' },
  },
  'panel': {
    'title': 'Network Packets on @metric',
  },
};

var gDiskDf = {
  'graph': {
    'complex-used': { 'color': '#447EBC' },
    'complex-reserved': { 'color': '#EAB839' },
    'complex-free': { 'color': '#508642' },
  },
  'panel': {
    'title': 'Disk space for @metric',
    'y_formats': [ 'bytes' ],
    'grid': { 'max': null, 'min': 0, 'leftMin': 0 },
    'stack': true,
  },
};

var gDiskIO = {
  'graph': {
    'ops.write': { 'color': '#447EBC' },
    'ops.read': { 'color': '#508642', 'column': 'value*-1' },
  },
  'panel': {
    'title': 'Disk IO for @metric',
  },
};

var gPsState = {
  'graph': {
    'sleeping': { 'color': '#EAB839', 'apply': 'max' },
    'running': { 'color': '#508642', 'apply': 'max' },
    'stopped': { 'color': '#E9967A', 'apply': 'max' },
    'blocked': { 'color': '#890F02', 'apply': 'max' },
    'zombies': { 'color': '#E24D42', 'apply': 'max' },
    'paging': { 'color': '#9400D3', 'apply': 'max' },
  },
  'panel': {
    'title': 'Processes State',
    'y_formats': [ 'short' ],
    'grid': { 'max': null, 'min': 0 },
  },
};

var gPsForks = {
  'graph': {
    'fork_rate': { 'color': '#81BEF7', 'apply': 'max' },
  },
  'panel': {
    'title': 'Processes Fork Rate',
    'y_formats': [ 'short' ],
    'grid': { 'max': null, 'min': 0 },
  },
};

// Redis plugin used: https://github.com/powdahound/redis-collectd-plugin
var gRedisMemory = {
  'graph': {
    'used_memory': { 'color': '#447EBC' },
  },
  'panel': {
    'title': 'Redis Memomy',
    'y_formats': [ 'bytes' ],
    'grid': { 'max': null, 'min': 0, 'leftMin': 0 },
  },
};

var gRedisCommands = {
  'graph': {
    'commands_processed': { 'color': '#447EBC', 'apply': 'max' },
  },
  'panel': {
    'title': 'Redis Commands',
    'y_formats': [ 'none' ],
    'grid': { 'max': null, 'min': 0, 'leftMin': 0 },
  },
};

var gMemcachedMemory = {
  'graph': {
    'cache.used': { 'color': '#447EBC' },
    'cache.free': { 'color': '#508642' },
  },
  'panel': {
    'title': 'Memcached Memomy',
    'y_formats': [ 'bytes' ],
    'stack': true,
  },
};

var gMemcachedConns = {
  'graph': {
    'connections-current': { 'color': '#447EBC' },
  },
  'panel': {
    'title': 'Memcached Connections',
    'grid': { 'max': null, 'min': 0, 'leftMin': 0 },
  },
};

var gMemcachedItems = {
  'graph': {
    'items-current': { 'color': '#447EBC' },
  },
  'panel': {
    'title': 'Memcached Items',
    'grid': { 'max': null, 'min': 0, 'leftMin': 0 },
  },
};

var gMemcachedCommands = {
  'graph': {
    'command-flush': { 'color': '#447EBC' },
    'command-get': { 'color': '#508642' },
    'command-set': { 'color': '#E9967A' },
    'command-touch': { 'color': '#890F02' },
  },
  'panel': {
    'title': 'Memcached Commands',
    'grid': { 'max': null, 'min': 0, 'leftMin': 0 },
  },
};

var setupRow = function (title, panels) {
  return {
    'title': title,
    'height': '250px',
    'panels': panels,
    'grid': { 'max': null, 'min': 0 },
  };
};

var supportedDashs = {
  'cpu': {
    'func': [ panelFactory(gCpu) ],
  },
  'load': {
    'func': [ panelFactory(gLoad) ],
  },
  'memory': {
    'func': [ panelFactory(gMemory) ],
  },
  'swap': {
    'func': [ panelFactory(gSwap) ],
  },
  'interface': {
    'func': [ panelFactory(gNetworkTraffic),
              panelFactory(gNetworkPackets),
            ],
    'multi': true,
  },
  'df': {
    'func': [ panelFactory(gDiskDf) ],
    'multi': true,
  },
  'disk': {
    'func': [ panelFactory(gDiskIO) ],
    'multi': true,
    'regexp': /\d$/
  },
  'processes': {
    'func': [ panelFactory(gPsState),
              panelFactory(gPsForks),
            ],
  },
  'redis' : {
    'func': [ panelFactory(gRedisMemory),
              panelFactory(gRedisCommands),
            ],
  },
  'memcache' : {
    'func': [ panelFactory(gMemcachedMemory),
              panelFactory(gMemcachedConns),
              panelFactory(gMemcachedItems),
              panelFactory(gMemcachedCommands),
            ],
  },
};

var showDashs = {};

if (displayMetric) {
  displayMetric.split(',').forEach(function (metric) {
    if (metric in supportedDashs) {
      showDashs[metric] = supportedDashs[metric];
    }
  });
} else {
  showDashs = supportedDashs;
}

var getExtendedMetrics = function (series, prefix) {
  var metricsExt = [];
  var postfix = '';
  for (var i = 0; i < series.length; i++) {
    if (series[i].indexOf(prefix) === 0) {
      postfix = series[i].slice(prefix.length);
      postfix = postfix.slice(0, postfix.indexOf('.'));
      if (metricsExt.indexOf(postfix) === -1) {
        metricsExt.push(postfix);
      }
    }
  }
  return metricsExt;
};

var pfx = 'collectd.' + host;
var postfix = '';
var hostSeries = getHostSeries(host);

// Skip empty Dashboard setup if there are no series.
if (hostSeries.length === 0) {
  return dashboard;
}

for (var metric in showDashs) {
  var matchedSeries = [];
  var pfxMetric = pfx + '.' + metric;
  for (var i = 0; i < hostSeries.length; i++) {
    if ((hostSeries[i].indexOf(pfxMetric) === 0) &&
        (!('regexp' in showDashs[metric]) ||
         ('regexp' in showDashs[metric] &&
          showDashs[metric].regexp.test(hostSeries[i].split('.')[2])))) {
      matchedSeries.push(hostSeries[i]);
    }
  }
  if (matchedSeries.length === 0) {
    continue;
  }
  if (showDashs[metric].multi) {
    metricsExt = getExtendedMetrics(matchedSeries, pfx + '.');
    if (metricsExt.length > 1) {
      for (var k = 0; k < metricsExt.length; k++) {
        var metricExt = metricsExt[k];
        var rematchedSeries = [];
        var repfxMetric = pfx + '.' + metricExt + '.';
        for (var i = 0; i < matchedSeries.length; i++) {
          if (matchedSeries[i].indexOf(repfxMetric) === 0) {
            rematchedSeries.push(matchedSeries[i]);
          }
        }
        for (var j = 0; j < showDashs[metric].func.length; j++) {
          metricFunc = showDashs[metric].func[j];
          dashboard.rows.push(setupRow(metricExt.toUpperCase, [metricFunc(rematchedSeries, 12, '1m')]));
        }
      }
     continue;
    }
  }
  for (var j = 0; j < showDashs[metric].func.length; j++) {
    metricFunc = showDashs[metric].func[j];
    dashboard.rows.push(setupRow(metric.toUpperCase, [metricFunc(matchedSeries, 12, '1m')]));
  }
}

return dashboard;
<|endoftext|>


<commit_before>// Copyright 2017-2020, University of Colorado Boulder

/**
 * Help section for explaining how to use a keyboard to change a combo box.
 *
 * @author Michael Kauzmann (PhET Interactive Simulations)
 */

import merge from '../../../../phet-core/js/merge.js';
import StringUtils from '../../../../phetcommon/js/util/StringUtils.js';
import sceneryPhet from '../../sceneryPhet.js';
import sceneryPhetStrings from '../../sceneryPhetStrings.js';
import ArrowKeyNode from '../ArrowKeyNode.js';
import EnterKeyNode from '../EnterKeyNode.js';
import EscapeKeyNode from '../EscapeKeyNode.js';
import SpaceKeyNode from '../SpaceKeyNode.js';
import KeyboardHelpIconFactory from './KeyboardHelpIconFactory.js';
import KeyboardHelpSection from './KeyboardHelpSection.js';

class ComboBoxKeyboardHelpSection extends KeyboardHelpSection {

  /**
   * @param {string} thingAsTitle - the item being changed by the combo box, capitalized as a title
   * @param thingAsLowerCaseSingular - the item being changed by the combo box, lower case as used in a sentence.
   * @param thingAsLowerCasePlural - plural version of thingAsLowerCaseSingular
   * @param {Object} [options]
   */
  constructor( thingAsTitle, thingAsLowerCaseSingular, thingAsLowerCasePlural, options ) {

    options = merge( {
      a11yContentTagName: 'ol', // ordered list
      vBoxOptions: {
        spacing: 8 // A bit tighter so that it looks like one set of instructions
      }
    }, options );

    // convencience funtion for all the filling in done below
    const fillIn = stringPattern => StringUtils.fillIn( stringPattern, {
      thingTitle: thingAsTitle,
      thingPlural: thingAsLowerCasePlural,
      thingSingular: thingAsLowerCaseSingular
    } );

    const popUpList = KeyboardHelpSection.labelWithIcon( fillIn( sceneryPhetStrings.keyboardHelpDialog.comboBox.popUpListPattern ),
      KeyboardHelpIconFactory.iconOrIcon( new SpaceKeyNode(), new EnterKeyNode() ),
      fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.comboBox.popUpListPatternDescription ) );

    const moveThrough = KeyboardHelpSection.labelWithIcon( fillIn( sceneryPhetStrings.keyboardHelpDialog.comboBox.moveThroughPattern ),
      KeyboardHelpIconFactory.iconRow( [ new ArrowKeyNode( 'up' ), new ArrowKeyNode( 'down' ) ] ),
      fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.comboBox.moveThroughPatternDescription ) );

    const chooseNew = KeyboardHelpSection.labelWithIcon( fillIn( sceneryPhetStrings.keyboardHelpDialog.comboBox.chooseNewPattern ),
      new EnterKeyNode(),
      fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.comboBox.chooseNewPatternDescription ) );

    const closeWithoutChanging = KeyboardHelpSection.labelWithIcon( sceneryPhetStrings.keyboardHelpDialog.comboBox.closeWithoutChanging,
      new EscapeKeyNode(),
      sceneryPhetStrings.a11y.keyboardHelpDialog.comboBox.closeWithoutChangingDescription );

    // order the rows of content
    super( fillIn( sceneryPhetStrings.keyboardHelpDialog.comboBox.stepsToChangePattern ),
      [ popUpList, moveThrough, chooseNew, closeWithoutChanging ], options );
  }
}

sceneryPhet.register( 'ComboBoxKeyboardHelpSection', ComboBoxKeyboardHelpSection );
export default ComboBoxKeyboardHelpSection;<commit_msg>update copyright dates from daily grunt work<commit_after>// Copyright 2020, University of Colorado Boulder

/**
 * Help section for explaining how to use a keyboard to change a combo box.
 *
 * @author Michael Kauzmann (PhET Interactive Simulations)
 */

import merge from '../../../../phet-core/js/merge.js';
import StringUtils from '../../../../phetcommon/js/util/StringUtils.js';
import sceneryPhet from '../../sceneryPhet.js';
import sceneryPhetStrings from '../../sceneryPhetStrings.js';
import ArrowKeyNode from '../ArrowKeyNode.js';
import EnterKeyNode from '../EnterKeyNode.js';
import EscapeKeyNode from '../EscapeKeyNode.js';
import SpaceKeyNode from '../SpaceKeyNode.js';
import KeyboardHelpIconFactory from './KeyboardHelpIconFactory.js';
import KeyboardHelpSection from './KeyboardHelpSection.js';

class ComboBoxKeyboardHelpSection extends KeyboardHelpSection {

  /**
   * @param {string} thingAsTitle - the item being changed by the combo box, capitalized as a title
   * @param thingAsLowerCaseSingular - the item being changed by the combo box, lower case as used in a sentence.
   * @param thingAsLowerCasePlural - plural version of thingAsLowerCaseSingular
   * @param {Object} [options]
   */
  constructor( thingAsTitle, thingAsLowerCaseSingular, thingAsLowerCasePlural, options ) {

    options = merge( {
      a11yContentTagName: 'ol', // ordered list
      vBoxOptions: {
        spacing: 8 // A bit tighter so that it looks like one set of instructions
      }
    }, options );

    // convencience funtion for all the filling in done below
    const fillIn = stringPattern => StringUtils.fillIn( stringPattern, {
      thingTitle: thingAsTitle,
      thingPlural: thingAsLowerCasePlural,
      thingSingular: thingAsLowerCaseSingular
    } );

    const popUpList = KeyboardHelpSection.labelWithIcon( fillIn( sceneryPhetStrings.keyboardHelpDialog.comboBox.popUpListPattern ),
      KeyboardHelpIconFactory.iconOrIcon( new SpaceKeyNode(), new EnterKeyNode() ),
      fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.comboBox.popUpListPatternDescription ) );

    const moveThrough = KeyboardHelpSection.labelWithIcon( fillIn( sceneryPhetStrings.keyboardHelpDialog.comboBox.moveThroughPattern ),
      KeyboardHelpIconFactory.iconRow( [ new ArrowKeyNode( 'up' ), new ArrowKeyNode( 'down' ) ] ),
      fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.comboBox.moveThroughPatternDescription ) );

    const chooseNew = KeyboardHelpSection.labelWithIcon( fillIn( sceneryPhetStrings.keyboardHelpDialog.comboBox.chooseNewPattern ),
      new EnterKeyNode(),
      fillIn( sceneryPhetStrings.a11y.keyboardHelpDialog.comboBox.chooseNewPatternDescription ) );

    const closeWithoutChanging = KeyboardHelpSection.labelWithIcon( sceneryPhetStrings.keyboardHelpDialog.comboBox.closeWithoutChanging,
      new EscapeKeyNode(),
      sceneryPhetStrings.a11y.keyboardHelpDialog.comboBox.closeWithoutChangingDescription );

    // order the rows of content
    super( fillIn( sceneryPhetStrings.keyboardHelpDialog.comboBox.stepsToChangePattern ),
      [ popUpList, moveThrough, chooseNew, closeWithoutChanging ], options );
  }
}

sceneryPhet.register( 'ComboBoxKeyboardHelpSection', ComboBoxKeyboardHelpSection );
export default ComboBoxKeyboardHelpSection;<|endoftext|>


<commit_before>import { PeerTypes, PeerTypePrefixes } from '../constants/ActorAppConstants';

import ActorClient from './ActorClient';

export default {
  peerToString(peer) {
    const { id, type } = peer;

    switch (type) {
      case PeerTypes.USER:
        return PeerTypePrefixes.USER + id;
      case PeerTypes.GROUP:
        return PeerTypePrefixes.GROUP + id;
      default:
        console.error('Unknown peer type: { type: %s, id: %s }', type, id);
    }
  },

  stringToPeer(str) {
    const type = str.charAt(0);
    const id = parseInt(str.substring(1), 10);

    switch (type) {
      case PeerTypePrefixes.USER:
        return ActorClient.getUserPeer(id);
      case PeerTypePrefixes.GROUP:
        return ActorClient.getGroupPeer(id);
      default:
      console.error('Unknown peer type: { type: %s, id: %s }', type, id);
    }
  },

  hasPeer(peer) {
    try {
      switch (peer.type) {
        case PeerTypes.USER:
          return ActorClient.getUser(peer.id);
        case PeerTypes.GROUP:
          return ActorClient.getGroup(peer.id);
      }
    } catch (e) {
      console.error(e);
    }

    return false;
  },

  equals(peer1, peer2) {
    return peer1 && peer2 && peer1.id === peer2.id && peer1.type === peer2.type;
  }
};
<commit_msg>fix(web): peer utils equal method return only boolean.<commit_after>import { PeerTypes, PeerTypePrefixes } from '../constants/ActorAppConstants';

import ActorClient from './ActorClient';

export default {
  peerToString(peer) {
    const { id, type } = peer;

    switch (type) {
      case PeerTypes.USER:
        return PeerTypePrefixes.USER + id;
      case PeerTypes.GROUP:
        return PeerTypePrefixes.GROUP + id;
      default:
        console.error('Unknown peer type: { type: %s, id: %s }', type, id);
    }
  },

  stringToPeer(str) {
    const type = str.charAt(0);
    const id = parseInt(str.substring(1), 10);

    switch (type) {
      case PeerTypePrefixes.USER:
        return ActorClient.getUserPeer(id);
      case PeerTypePrefixes.GROUP:
        return ActorClient.getGroupPeer(id);
      default:
      console.error('Unknown peer type: { type: %s, id: %s }', type, id);
    }
  },

  hasPeer(peer) {
    try {
      switch (peer.type) {
        case PeerTypes.USER:
          return ActorClient.getUser(peer.id);
        case PeerTypes.GROUP:
          return ActorClient.getGroup(peer.id);
      }
    } catch (e) {
      console.error(e);
    }

    return false;
  },

  equals(peer1, peer2) {
    return Boolean(peer1 && peer2) && peer1.id === peer2.id && peer1.type === peer2.type;
  }
};
<|endoftext|>


<commit_before><commit_msg>space<commit_after><|endoftext|>


<commit_before>/* jshint strict: false */

// //////////////////////////////////////////////////////////////////////////////
// / @brief database version check
// /
// / @file
// /
// / Checks if the database needs to be upgraded.
// /
// / DISCLAIMER
// /
// / Copyright 2014 triAGENS GmbH, Cologne, Germany
// /
// / Licensed under the Apache License, Version 2.0 (the "License")
// / you may not use this file except in compliance with the License.
// / You may obtain a copy of the License at
// /
// /     http://www.apache.org/licenses/LICENSE-2.0
// /
// / Unless required by applicable law or agreed to in writing, software
// / distributed under the License is distributed on an "AS IS" BASIS,
// / WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// / See the License for the specific language governing permissions and
// / limitations under the License.
// /
// / Copyright holder is triAGENS GmbH, Cologne, Germany
// /
// / @author Dr. Frank Celler
// / @author Copyright 2014, triAGENS GmbH, Cologne, Germany
// //////////////////////////////////////////////////////////////////////////////

var cluster = require('@arangodb/cluster');
var fs = require('fs');
var db = require('@arangodb').db;
var console = require('console');

// //////////////////////////////////////////////////////////////////////////////
// / @brief logger
// //////////////////////////////////////////////////////////////////////////////

var logger = {
  info: function (msg) {
    console.log("In database '%s': %s", db._name(), msg);
  },

  error: function (msg) {
    console.error("In database '%s': %s", db._name(), msg);
  },

  log: function (msg) {
    this.info(msg);
  }
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief CURRENT_VERSION
// //////////////////////////////////////////////////////////////////////////////

exports.CURRENT_VERSION = (function () {
  var v = db._version().replace(/-[a-zA-Z0-9_\-]*$/g, '').split('.');

  var major = parseFloat(v[0], 10) || 0;
  var minor = parseFloat(v[1], 10) || 0;
  var patch = parseFloat(v[2], 10) || 0;

  return (((major * 100) + minor) * 100) + patch;
}());

// //////////////////////////////////////////////////////////////////////////////
// / @brief VERSION_MATCH
// //////////////////////////////////////////////////////////////////////////////

exports.VERSION_MATCH = 1;

// //////////////////////////////////////////////////////////////////////////////
// / @brief DOWNGRADE
// //////////////////////////////////////////////////////////////////////////////

exports.DOWNGRADE_NEEDED = 2;

// //////////////////////////////////////////////////////////////////////////////
// / @brief UPGRADE
// //////////////////////////////////////////////////////////////////////////////

exports.UPGRADE_NEEDED = 3;

// //////////////////////////////////////////////////////////////////////////////
// / @brief IS_CLUSTER
// //////////////////////////////////////////////////////////////////////////////

exports.IS_CLUSTER = -1;

// //////////////////////////////////////////////////////////////////////////////
// / @brief CANNOT_PARSE_VERSION_FILE
// //////////////////////////////////////////////////////////////////////////////

exports.CANNOT_PARSE_VERSION_FILE = -2;

// //////////////////////////////////////////////////////////////////////////////
// / @brief CANNOT_READ_VERSION_FILE
// //////////////////////////////////////////////////////////////////////////////

exports.CANNOT_READ_VERSION_FILE = -3;

// //////////////////////////////////////////////////////////////////////////////
// / @brief NO_VERSION_FILE
// //////////////////////////////////////////////////////////////////////////////

exports.NO_VERSION_FILE = -4;

// //////////////////////////////////////////////////////////////////////////////
// / @brief NO_SERVER_VERSION
// //////////////////////////////////////////////////////////////////////////////

exports.NO_SERVER_VERSION = -5;

// //////////////////////////////////////////////////////////////////////////////
// / @brief checks the version
// //////////////////////////////////////////////////////////////////////////////

exports.databaseVersion = function () {
  if (cluster.isCoordinator()) {
    console.debug('skip on corrdinator');

    return {
      result: exports.IS_CLUSTER
    };
  }

  // path to the VERSION file
  var versionFile = db._path() + '/VERSION';
  var lastVersion = null;

  // VERSION file exists, read its contents
  if (fs.exists(versionFile)) {
    var versionInfo = fs.read(versionFile);
    console.debug('found version file: ' + versionInfo);

    if (versionInfo !== '') {
      var versionValues = JSON.parse(versionInfo);

      if (versionValues && versionValues.version && !isNaN(versionValues.version)) {
        lastVersion = parseFloat(versionValues.version);
      } else {
        logger.error("Cannot parse VERSION file '" + versionFile + "': '" + versionInfo + "'");
        return {
          result: exports.CANNOT_PARSE_VERSION_FILE
        };
      }
    } else {
      logger.error("Cannot read VERSION file: '" + versionFile + "'");
      return {
        result: exports.CANNOT_READ_VERSION_FILE
      };
    }
  } else {
    console.debug('version file (' + versionFile + ') not found');

    return {
      result: exports.NO_VERSION_FILE
    };
  }

  // extract server version
  var currentVersion = exports.CURRENT_VERSION;

  // version match!
  if (Math.floor(lastVersion / 100) === Math.floor(currentVersion / 100)) {
    console.debug('version match: last version ' + lastVersion +
      ', current version ' + currentVersion);

    return {
      result: exports.VERSION_MATCH,
      serverVersion: currentVersion,
      databaseVersion: lastVersion
    };
  }

  // downgrade??
  if (lastVersion > currentVersion) {
    console.debug('downgrade: last version ' + lastVersion +
      ', current version ' + currentVersion);

    return {
      result: exports.DOWNGRADE_NEEDED,
      serverVersion: currentVersion,
      databaseVersion: lastVersion
    };
  }

  // upgrade
  if (lastVersion < currentVersion) {
    console.debug('upgrade: last version ' + lastVersion +
      ', current version ' + currentVersion);

    return {
      result: exports.UPGRADE_NEEDED,
      serverVersion: currentVersion,
      databaseVersion: lastVersion
    };
  }

  console.error('should not happen: last version ' + lastVersion +
    ', current version ' + currentVersion);

  return {
    result: exports.NO_VERSION_FILE
  };
};
<commit_msg>fix path to version file<commit_after>/* jshint strict: false */

// //////////////////////////////////////////////////////////////////////////////
// / @brief database version check
// /
// / @file
// /
// / Checks if the database needs to be upgraded.
// /
// / DISCLAIMER
// /
// / Copyright 2014 triAGENS GmbH, Cologne, Germany
// /
// / Licensed under the Apache License, Version 2.0 (the "License")
// / you may not use this file except in compliance with the License.
// / You may obtain a copy of the License at
// /
// /     http://www.apache.org/licenses/LICENSE-2.0
// /
// / Unless required by applicable law or agreed to in writing, software
// / distributed under the License is distributed on an "AS IS" BASIS,
// / WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// / See the License for the specific language governing permissions and
// / limitations under the License.
// /
// / Copyright holder is triAGENS GmbH, Cologne, Germany
// /
// / @author Dr. Frank Celler
// / @author Copyright 2014, triAGENS GmbH, Cologne, Germany
// //////////////////////////////////////////////////////////////////////////////

var cluster = require('@arangodb/cluster');
var fs = require('fs');
var db = require('@arangodb').db;
var console = require('console');

// //////////////////////////////////////////////////////////////////////////////
// / @brief logger
// //////////////////////////////////////////////////////////////////////////////

var logger = {
  info: function (msg) {
    console.log("In database '%s': %s", db._name(), msg);
  },

  error: function (msg) {
    console.error("In database '%s': %s", db._name(), msg);
  },

  log: function (msg) {
    this.info(msg);
  }
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief CURRENT_VERSION
// //////////////////////////////////////////////////////////////////////////////

exports.CURRENT_VERSION = (function () {
  var v = db._version().replace(/-[a-zA-Z0-9_\-]*$/g, '').split('.');

  var major = parseFloat(v[0], 10) || 0;
  var minor = parseFloat(v[1], 10) || 0;
  var patch = parseFloat(v[2], 10) || 0;

  return (((major * 100) + minor) * 100) + patch;
}());

// //////////////////////////////////////////////////////////////////////////////
// / @brief VERSION_MATCH
// //////////////////////////////////////////////////////////////////////////////

exports.VERSION_MATCH = 1;

// //////////////////////////////////////////////////////////////////////////////
// / @brief DOWNGRADE
// //////////////////////////////////////////////////////////////////////////////

exports.DOWNGRADE_NEEDED = 2;

// //////////////////////////////////////////////////////////////////////////////
// / @brief UPGRADE
// //////////////////////////////////////////////////////////////////////////////

exports.UPGRADE_NEEDED = 3;

// //////////////////////////////////////////////////////////////////////////////
// / @brief IS_CLUSTER
// //////////////////////////////////////////////////////////////////////////////

exports.IS_CLUSTER = -1;

// //////////////////////////////////////////////////////////////////////////////
// / @brief CANNOT_PARSE_VERSION_FILE
// //////////////////////////////////////////////////////////////////////////////

exports.CANNOT_PARSE_VERSION_FILE = -2;

// //////////////////////////////////////////////////////////////////////////////
// / @brief CANNOT_READ_VERSION_FILE
// //////////////////////////////////////////////////////////////////////////////

exports.CANNOT_READ_VERSION_FILE = -3;

// //////////////////////////////////////////////////////////////////////////////
// / @brief NO_VERSION_FILE
// //////////////////////////////////////////////////////////////////////////////

exports.NO_VERSION_FILE = -4;

// //////////////////////////////////////////////////////////////////////////////
// / @brief NO_SERVER_VERSION
// //////////////////////////////////////////////////////////////////////////////

exports.NO_SERVER_VERSION = -5;

// //////////////////////////////////////////////////////////////////////////////
// / @brief checks the version
// //////////////////////////////////////////////////////////////////////////////

exports.databaseVersion = function () {
  if (cluster.isCoordinator()) {
    console.debug('skip on corrdinator');

    return {
      result: exports.IS_CLUSTER
    };
  }

  // path to the VERSION file
  let versionFile = db._versionFilename();
  var lastVersion = null;

  // VERSION file exists, read its contents
  if (fs.exists(versionFile)) {
    var versionInfo = fs.read(versionFile);
    console.debug('found version file: ' + versionInfo);

    if (versionInfo !== '') {
      var versionValues = JSON.parse(versionInfo);

      if (versionValues && versionValues.version && !isNaN(versionValues.version)) {
        lastVersion = parseFloat(versionValues.version);
      } else {
        logger.error("Cannot parse VERSION file '" + versionFile + "': '" + versionInfo + "'");
        return {
          result: exports.CANNOT_PARSE_VERSION_FILE
        };
      }
    } else {
      logger.error("Cannot read VERSION file: '" + versionFile + "'");
      return {
        result: exports.CANNOT_READ_VERSION_FILE
      };
    }
  } else {
    console.debug('version file (' + versionFile + ') not found');

    return {
      result: exports.NO_VERSION_FILE
    };
  }

  // extract server version
  var currentVersion = exports.CURRENT_VERSION;

  // version match!
  if (Math.floor(lastVersion / 100) === Math.floor(currentVersion / 100)) {
    console.debug('version match: last version ' + lastVersion +
      ', current version ' + currentVersion);

    return {
      result: exports.VERSION_MATCH,
      serverVersion: currentVersion,
      databaseVersion: lastVersion
    };
  }

  // downgrade??
  if (lastVersion > currentVersion) {
    console.debug('downgrade: last version ' + lastVersion +
      ', current version ' + currentVersion);

    return {
      result: exports.DOWNGRADE_NEEDED,
      serverVersion: currentVersion,
      databaseVersion: lastVersion
    };
  }

  // upgrade
  if (lastVersion < currentVersion) {
    console.debug('upgrade: last version ' + lastVersion +
      ', current version ' + currentVersion);

    return {
      result: exports.UPGRADE_NEEDED,
      serverVersion: currentVersion,
      databaseVersion: lastVersion
    };
  }

  console.error('should not happen: last version ' + lastVersion +
    ', current version ' + currentVersion);

  return {
    result: exports.NO_VERSION_FILE
  };
};
<|endoftext|>


<commit_before>import Ember from 'ember';

let cachedRequireEntries;
let cachedScriptTags;
let cachedLinkTags;

/**
 * Determines whether an array contains the provided item.
 *
 * @param {Array} array
 * @param {Any} item
 * @return {Boolean}
 */
function has(array, item) {
  return array.indexOf(item) !== -1;
}

/**
 * Removes a DOM Node from the document.
 *
 * @param {Node} node
 * @return {Void}
 */
function removeNode(node) {
  node.parentNode.removeChild(node);
}

/**
 * Converts an iterable object into an actual Array.
 *
 * @param {Iterable} iterable
 * @return {Array}
 */
function toArray(iterable) {
  return Array.prototype.slice.call(iterable);
}

/**
 * Returns all of the HTML Elements matching a given selector as an array.
 *
 * @param {String} selector
 * @return {Array<HTMLElement>}
 */
function getAll(selector) {
  const htmlCollection = document.querySelectorAll(selector);
  return toArray(htmlCollection);
}

/**
 * Deletes an entry from require's list of modules.
 *
 * @param {String} entry
 * @return {Void}
 */
function resetRequireEntry(entry) {
  delete self.requirejs.entries[entry];
}

/**
 * Compares two arrays, if they're different, invokes a callback for each
 * entry that does not appear in the initial array.
 *
 * @param {Array} initial
 * @param {Array} current
 * @param {Function} diffHandler
 * @return {Void}
 */
function compareAndIterate(initial, current, diffHandler) {
  if (initial.length < current.length) {
    for (let i = 0; i < current.length; i++) {
      let entry = current[i];
      if (!has(initial, entry)) {
        diffHandler(entry);
      }
    }
  }
}

/**
 * Gets the current loaded asset state including scripts, links, and require
 * modules.
 *
 * @return {Object}
 */
export function getLoadedAssetState() {
  return {
    requireEntries: Object.keys(self.requirejs.entries),
    scripts: getAll('script'),
    links: getAll('link')
  };
}

/**
 * Caches the current loaded asset state with regards to links, scripts, and JS
 * modules currently present.
 *
 * @return {Void}
 */
export function cacheLoadedAssetState() {
  ({
    requireEntries: cachedRequireEntries,
    scripts: cachedScriptTags,
    links: cachedLinkTags
  } = getLoadedAssetState());
}

/**
 * Restores the loaded asset state to the previous cached value with regards to
 * links, scripts, and JS modules.
 *
 * @return {Void}
 */
export function resetLoadedAssetState() {
  const {
    requireEntries: currentRequireEntries,
    scripts: currentScriptTags,
    links: currentLinkTags
  } = getLoadedAssetState();

  compareAndIterate(cachedRequireEntries, currentRequireEntries, resetRequireEntry);
  compareAndIterate(cachedScriptTags, currentScriptTags, removeNode);
  compareAndIterate(cachedLinkTags, currentLinkTags, removeNode);
}
<commit_msg>Removes ember import<commit_after>let cachedRequireEntries;
let cachedScriptTags;
let cachedLinkTags;

/**
 * Determines whether an array contains the provided item.
 *
 * @param {Array} array
 * @param {Any} item
 * @return {Boolean}
 */
function has(array, item) {
  return array.indexOf(item) !== -1;
}

/**
 * Removes a DOM Node from the document.
 *
 * @param {Node} node
 * @return {Void}
 */
function removeNode(node) {
  node.parentNode.removeChild(node);
}

/**
 * Converts an iterable object into an actual Array.
 *
 * @param {Iterable} iterable
 * @return {Array}
 */
function toArray(iterable) {
  return Array.prototype.slice.call(iterable);
}

/**
 * Returns all of the HTML Elements matching a given selector as an array.
 *
 * @param {String} selector
 * @return {Array<HTMLElement>}
 */
function getAll(selector) {
  const htmlCollection = document.querySelectorAll(selector);
  return toArray(htmlCollection);
}

/**
 * Deletes an entry from require's list of modules.
 *
 * @param {String} entry
 * @return {Void}
 */
function resetRequireEntry(entry) {
  delete self.requirejs.entries[entry];
}

/**
 * Compares two arrays, if they're different, invokes a callback for each
 * entry that does not appear in the initial array.
 *
 * @param {Array} initial
 * @param {Array} current
 * @param {Function} diffHandler
 * @return {Void}
 */
function compareAndIterate(initial, current, diffHandler) {
  if (initial.length < current.length) {
    for (let i = 0; i < current.length; i++) {
      let entry = current[i];
      if (!has(initial, entry)) {
        diffHandler(entry);
      }
    }
  }
}

/**
 * Gets the current loaded asset state including scripts, links, and require
 * modules.
 *
 * @return {Object}
 */
export function getLoadedAssetState() {
  return {
    requireEntries: Object.keys(self.requirejs.entries),
    scripts: getAll('script'),
    links: getAll('link')
  };
}

/**
 * Caches the current loaded asset state with regards to links, scripts, and JS
 * modules currently present.
 *
 * @return {Void}
 */
export function cacheLoadedAssetState() {
  ({
    requireEntries: cachedRequireEntries,
    scripts: cachedScriptTags,
    links: cachedLinkTags
  } = getLoadedAssetState());
}

/**
 * Restores the loaded asset state to the previous cached value with regards to
 * links, scripts, and JS modules.
 *
 * @return {Void}
 */
export function resetLoadedAssetState() {
  const {
    requireEntries: currentRequireEntries,
    scripts: currentScriptTags,
    links: currentLinkTags
  } = getLoadedAssetState();

  compareAndIterate(cachedRequireEntries, currentRequireEntries, resetRequireEntry);
  compareAndIterate(cachedScriptTags, currentScriptTags, removeNode);
  compareAndIterate(cachedLinkTags, currentLinkTags, removeNode);
}
<|endoftext|>


<commit_before><commit_msg>bugfix: handle undefined return messages<commit_after><|endoftext|>


<commit_before><commit_msg>remove unused routes<commit_after><|endoftext|>


<commit_before><commit_msg>Renamed getUser.<commit_after><|endoftext|>


<commit_before><commit_msg>Better reporting in fusion<commit_after><|endoftext|>


<commit_before><commit_msg>created new URL for bola chat room on hipcha<commit_after><|endoftext|>


<commit_before><commit_msg>Always use bulk ajax auth for pusher (#1286)<commit_after><|endoftext|>