<commit_before>/*
 *   Copyright 2014-2015 Guy Bedford (http://guybedford.com)
 *
 *   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.
 */

var config = require('../config');
var PackageName = require('./package-name');
var path = require('path');
var extend = require('../common').extend;
var hasProperties = require('../common').hasProperties;
var registryCache = require('../package').registryCache;
var Promise = require('rsvp').Promise;
var ui = require('../ui');
var fs = require('graceful-fs');
var asp = require('rsvp').denodeify;
var readJSON = require('../common').readJSON;
var alphabetize = require('../common').alphabetize;
var globalConfig = require('../global-config');
var processDeps = require('../package').processDeps;

var isWindows = process.platform.match(/^win/);
var winRegEx = /\\/g;
function winPath(path) {
  if (!isWindows)
    return path;
  return path.replace(winRegEx, '/');
}

/*
 * Package.json Configuration Class
 *
 * main
 * registry
 * dependencies
 * configFile
 * baseURL
 * lib
 * dist
 * packages
 * format
 * map
 * buildConfig
 *
 */
function PackageJSON(fileName) {
  this.fileName = fileName;
}

PackageJSON.prototype.read = function(prompts) {
  if (this.read_)
    throw "Package.json file already read";

  this.read_ = true;
  var self = this;
  var pjson;

  return readJSON(this.fileName)
  .then(function(_pjson) {
    self.originalPjson = _pjson;

    self.jspmPrefix = true;
    if (_pjson.registry && !_pjson.jspm)
      self.jspmPrefix = false;

    // derive the jspm config from the 'jspm' property in the package.json
    // also sets the registry property if dependencies are jspm-prefixed
    pjson = config.derivePackageConfig(_pjson);

    prompts = prompts || (!_pjson.jspm && !_pjson.registry);

    if (prompts)
      return doInitPrompts(pjson, self.fileName, self.jspmPrefix)
      .then(function(prefixed) {
        self.jspmPrefix = prefixed;
      });
  })
  .then(function() {
    self.dir = path.dirname(self.fileName);

    // populate defaults as we go
    var defaults = self.defaults = {};

    self.registry = pjson.registry || globalConfig.config.registry;
    self.dependencies = {};
    // only read dependencies when combined with a registry property
    self.dependencies = processDeps(pjson.dependencies, self.registry);

    defaults.baseURL = self.dir;
    self.baseURL = pjson.directories && pjson.directories.baseURL && path.resolve(self.dir, pjson.directories.baseURL) || defaults.baseURL;

    defaults.lib = path.resolve(self.baseURL, '.');
    defaults.dist = path.resolve(self.baseURL, 'dist');
    defaults.packages = path.resolve(self.baseURL, 'jspm_packages');

    defaults.main = defaults.lib + '/index';
    self.main = pjson.main || defaults.main;

    self.lib = pjson.directories && pjson.directories.lib && path.resolve(self.dir, pjson.directories.lib) || defaults.lib;
    self.dist = pjson.directories && pjson.directories.dist && path.resolve(self.dir, pjson.directories.dist) || defaults.dist;
    // NB can remove jspmPackages suport in time
    self.packages = pjson.directories && pjson.directories.packages && path.resolve(self.dir, pjson.directories.packages)
      || pjson.directories && pjson.directories.jspmPackages && path.resolve(self.dir, pjson.directories.jspmPackages) || defaults.packages;

    defaults.configFile = path.resolve(self.baseURL, 'config.js');
    self.configFile = pjson.configFile && path.resolve(self.dir, pjson.configFile) || defaults.configFile;

    self.format = pjson.format;
    self.map = extend({}, pjson.map || {});

    // NB remove when nodelibs no longer built this way
    self.useJSExtensions = pjson.useJSExtensions;

    self.buildConfig = extend({}, pjson.buildConfig || {});

    return prompts;
  });
}

PackageJSON.prototype.write = function() {
  var pjson = this.jspmPrefix ? {} : this.originalPjson;

  if (!this.jspmPrefix) {
    delete pjson.jspm;
    pjson.registry = this.registry || globalConfig.config.registry;
  }
  else if (this.registry != 'jspm') {
    pjson.registry = this.registry;
  }

  var defaults = this.defaults;

  // only set properties that differ from the defaults
  if (this.main != defaults.main)
    pjson.main = this.main;

  if (this.format)
    pjson.format = this.format;

  var directories = {};
  if (this.baseURL != defaults.baseURL)
    directories.baseURL = this.baseURL;
  if (this.lib != defaults.lib)
    directories.lib = this.lib;
  if (this.dist != defaults.dist)
    directories.dist = this.dist;
  if (this.packages != defaults.packages)
    directories.packages = this.packages;

  if (hasProperties(directories)) {
    for (var d in directories) {
      directories[d] = winPath(path.relative(this.dir, directories[d]));
      if (!directories[d])
        directories[d] = '.';
    }
    pjson.directories = extend(pjson.directories || {}, directories);
    pjson.directories = alphabetize(pjson.directories);
  }

  if (this.configFile != defaults.configFile)
    pjson.configFile = winPath(path.relative(this.dir, this.configFile));

  pjson.map = alphabetize(this.map);
  if (!hasProperties(pjson.map))
    delete pjson.map;

  pjson.dependencies = {};
  var depValue;
  for (var d in this.dependencies) {
    var dep = this.dependencies[d];
    if (!dep)
      continue;
    if (dep.endpoint == 'jspm') {
      if (d == dep.package)
        depValue = dep.version;
      else
        depValue = dep.exactPackage;
    }
    // name is exactly as in registry
    else if (registryCache[d] == dep.name)
        depValue = dep.version;
    else
      depValue = dep.exactName;

    pjson.dependencies[d] = depValue;
  }
  pjson.dependencies = alphabetize(pjson.dependencies);
  if (!hasProperties(pjson.dependencies))
    delete pjson.dependencies;

  pjson.buildConfig = this.buildConfig;
  if (!hasProperties(pjson.buildConfig))
    delete pjson.buildConfig;

  // dedupe jspm properties against base properties
  if (this.jspmPrefix) {
    for (var p in pjson) {
      if (this.originalPjson[p] === pjson[p])
        delete pjson[p];
    }
    this.originalPjson.jspm = pjson;
  }

  // NB check that the file hasn't changed since we opened it and if so, prompt
  return asp(fs.writeFile)(this.fileName, JSON.stringify(this.originalPjson, null, 2) + '\n');
}

// can take an existing non-jspm package.json
function doInitPrompts(pjson, pjsonPath, prefixed) {
  var baseDir = path.dirname(pjsonPath);
  var base;

  pjson.directories = pjson.directories || {};

  return Promise.resolve()
  .then(function() {
    return ui.confirm('Would you like jspm to prefix the jspm package.json properties under %jspm%?', prefixed);
  })
  .then(function(prefix) {
    prefixed = prefix;
    return ui.input('Enter server baseURL (public folder path)', pjson.directories.baseURL || './');
  })
  .then(function(baseURL) {
    base = path.relative(process.cwd(), path.resolve(baseURL));
    baseURL = path.relative(baseDir, path.resolve(baseURL));
    if (!base)
      base = '.';
    base += path.sep;
    if (baseURL)
      pjson.directories.baseURL = baseURL;
    return ui.input('Enter project code folder', pjson.directories.lib || base);
  })
  .then(function(lib) {
    pjson.directories.lib = path.relative(baseDir, path.resolve(lib));
    if (!pjson.directories.lib)
      pjson.directories.lib = '.';
    return ui.input('Enter jspm packages folder', pjson.directories.packages || base + 'jspm_packages');
  })
  .then(function(packages) {
    pjson.directories.packages = path.relative(baseDir, path.resolve(packages));
    return ui.input('Enter config file path', pjson.configFile || base + 'config.js');
  })
  .then(function(configFile) {
    pjson.configFile = path.relative(baseDir, path.resolve(configFile))
    return prefixed;
  });
}

module.exports = PackageJSON;
<commit_msg>carefully preserve jspm package.json directories<commit_after>/*
 *   Copyright 2014-2015 Guy Bedford (http://guybedford.com)
 *
 *   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.
 */

var config = require('../config');
var PackageName = require('./package-name');
var path = require('path');
var extend = require('../common').extend;
var hasProperties = require('../common').hasProperties;
var registryCache = require('../package').registryCache;
var Promise = require('rsvp').Promise;
var ui = require('../ui');
var fs = require('graceful-fs');
var asp = require('rsvp').denodeify;
var readJSON = require('../common').readJSON;
var alphabetize = require('../common').alphabetize;
var globalConfig = require('../global-config');
var processDeps = require('../package').processDeps;

var isWindows = process.platform.match(/^win/);
var winRegEx = /\\/g;
function winPath(path) {
  if (!isWindows)
    return path;
  return path.replace(winRegEx, '/');
}

/*
 * Package.json Configuration Class
 *
 * main
 * registry
 * dependencies
 * configFile
 * baseURL
 * lib
 * dist
 * packages
 * format
 * map
 * buildConfig
 *
 */
function PackageJSON(fileName) {
  this.fileName = fileName;
}

PackageJSON.prototype.read = function(prompts) {
  if (this.read_)
    throw "Package.json file already read";

  this.read_ = true;
  var self = this;
  var pjson;

  return readJSON(this.fileName)
  .then(function(_pjson) {
    self.originalPjson = _pjson;

    self.jspmPrefix = true;
    if (_pjson.registry && !_pjson.jspm)
      self.jspmPrefix = false;

    // derive the jspm config from the 'jspm' property in the package.json
    // also sets the registry property if dependencies are jspm-prefixed
    pjson = config.derivePackageConfig(_pjson);

    self.pjson = pjson;

    prompts = prompts || (!_pjson.jspm && !_pjson.registry);

    if (prompts)
      return doInitPrompts(pjson, self.fileName, self.jspmPrefix)
      .then(function(prefixed) {
        self.jspmPrefix = prefixed;
      });
  })
  .then(function() {
    self.dir = path.dirname(self.fileName);

    // populate defaults as we go
    var defaults = self.defaults = {};

    self.registry = pjson.registry || globalConfig.config.registry;
    self.dependencies = {};
    // only read dependencies when combined with a registry property
    self.dependencies = processDeps(pjson.dependencies, self.registry);

    defaults.baseURL = self.dir;
    self.baseURL = pjson.directories && pjson.directories.baseURL && path.resolve(self.dir, pjson.directories.baseURL) || defaults.baseURL;

    defaults.packages = path.resolve(self.baseURL, 'jspm_packages');

    defaults.main = path.join(self.baseURL, 'index');
    self.main = pjson.main || defaults.main;

    // NB can remove jspmPackages suport in time
    self.packages = pjson.directories && pjson.directories.packages && path.resolve(self.dir, pjson.directories.packages)
      || pjson.directories && pjson.directories.jspmPackages && path.resolve(self.dir, pjson.directories.jspmPackages) || defaults.packages;

    defaults.configFile = path.resolve(self.baseURL, 'config.js');
    self.configFile = pjson.configFile && path.resolve(self.dir, pjson.configFile) || defaults.configFile;

    self.format = pjson.format;
    self.map = extend({}, pjson.map || {});

    // NB remove when nodelibs no longer built this way
    self.useJSExtensions = pjson.useJSExtensions;

    self.buildConfig = extend({}, pjson.buildConfig || {});

    return prompts;
  });
}

PackageJSON.prototype.write = function() {
  var pjson = this.jspmPrefix ? {} : this.originalPjson;

  if (!this.jspmPrefix) {
    delete pjson.jspm;
    pjson.registry = this.registry || globalConfig.config.registry;
  }
  else if (this.registry != 'jspm') {
    pjson.registry = this.registry;
  }

  var defaults = this.defaults;

  // only set properties that differ from the defaults
  if (this.main != defaults.main)
    pjson.main = this.main;

  if (this.format)
    pjson.format = this.format;

  var directories = {};
  if (this.baseURL != defaults.baseURL)
    directories.baseURL = this.baseURL;
  if (this.packages != defaults.packages)
    directories.packages = this.packages;

  if (hasProperties(directories)) {
    for (var d in directories) {
      directories[d] = winPath(path.relative(this.dir, directories[d]));
      if (!directories[d])
        directories[d] = '.';
    }
  }
  pjson.directories = extend(pjson.directories || {}, this.pjson.directories || {});
  pjson.directories = alphabetize(pjson.directories);

  if (!hasProperties(pjson.directories))
    delete pjson.directories;

  if (this.configFile != defaults.configFile)
    pjson.configFile = winPath(path.relative(this.dir, this.configFile));

  pjson.map = alphabetize(this.map);
  if (!hasProperties(pjson.map))
    delete pjson.map;

  pjson.dependencies = {};
  var depValue;
  for (var d in this.dependencies) {
    var dep = this.dependencies[d];
    if (!dep)
      continue;
    if (dep.endpoint == 'jspm') {
      if (d == dep.package)
        depValue = dep.version;
      else
        depValue = dep.exactPackage;
    }
    // name is exactly as in registry
    else if (registryCache[d] == dep.name)
        depValue = dep.version;
    else
      depValue = dep.exactName;

    pjson.dependencies[d] = depValue;
  }
  pjson.dependencies = alphabetize(pjson.dependencies);
  if (!hasProperties(pjson.dependencies))
    delete pjson.dependencies;

  pjson.buildConfig = this.buildConfig;
  if (!hasProperties(pjson.buildConfig))
    delete pjson.buildConfig;

  // dedupe jspm properties against base properties
  if (this.jspmPrefix) {
    for (var p in pjson) {
      if (this.originalPjson[p] === pjson[p])
        delete pjson[p];
    }
    this.originalPjson.jspm = pjson;
  }

  // NB check that the file hasn't changed since we opened it and if so, prompt
  return asp(fs.writeFile)(this.fileName, JSON.stringify(this.originalPjson, null, 2) + '\n');
}

// can take an existing non-jspm package.json
function doInitPrompts(pjson, pjsonPath, prefixed) {
  var baseDir = path.dirname(pjsonPath);
  var base;

  pjson.directories = pjson.directories || {};

  return Promise.resolve()
  .then(function() {
    return ui.confirm('Would you like jspm to prefix the jspm package.json properties under %jspm%?', prefixed);
  })
  .then(function(prefix) {
    prefixed = prefix;
    return ui.input('Enter server baseURL (public folder path)', pjson.directories.baseURL || './');
  })
  .then(function(baseURL) {
    base = path.relative(process.cwd(), path.resolve(baseURL));
    baseURL = path.relative(baseDir, path.resolve(baseURL));
    if (!base)
      base = '.';
    base += path.sep;
    if (baseURL)
      pjson.directories.baseURL = baseURL;
    return ui.input('Enter project code folder', pjson.directories.lib || base);
  })
  .then(function(lib) {
    pjson.directories.lib = path.relative(baseDir, path.resolve(lib));
    if (!pjson.directories.lib)
      pjson.directories.lib = '.';
    return ui.input('Enter jspm packages folder', pjson.directories.packages || base + 'jspm_packages');
  })
  .then(function(packages) {
    pjson.directories.packages = path.relative(baseDir, path.resolve(packages));
    return ui.input('Enter config file path', pjson.configFile || base + 'config.js');
  })
  .then(function(configFile) {
    pjson.configFile = path.relative(baseDir, path.resolve(configFile))
    return prefixed;
  });
}

module.exports = PackageJSON;
<|endoftext|>


<commit_before>'use strict';

var module = angular.module('app.directives', []);

module.directive('aceEditor',
    function (editor) {
        return {
            restrict:'A',
            scope: {
                sync: "="
            },
            link:function (scope, element) {
                editor.rebind(element[0]);

                scope.$watch('sync', function(newValue, oldValue) {
                    if(newValue !== oldValue) {
                        newValue ? $('.ace_gutter').removeClass('inactive') : $('.ace_gutter').addClass('inactive');
                    }
                }, true);
            }
        };
    });

module.directive('html5VideoPlayer',
    function (video) {
        return {
            restrict:'A',
            link:function (scope, element) {
                video.bindVideoPlayer(element[0]);
            }
        };
    });

module.directive('star',
    function () {
        return {
            restrict:'E',
            replace:true,
            scope:{
                val:'=value',
                // Value bound to
                eventFn:'&click'
                // Optional expression evaluated on click
            },
            link:function (scope, element) {
                element.bind('click',
                    function () {
                        scope.$apply(function () {
                            scope.val = !scope.val;
                        });
                        scope.$eval(scope.eventFn, scope.val);
                    });
            },
            template:''
        }
    });

module.directive('alert',
    function ($rootScope, analytics) {
        return {
            restrict:'E',
            replace:true,
            link:function (scope, element) {
                $rootScope.$on('error',
                    function (event, data) {
                        scope.$apply(function () {
                            analytics.pushAnalytics('Error', data.message);
                            scope.message = data.message;
                            $(element).show();
                        });
                    });
                scope.close = function () {
                    $(element).hide();
                };
            },
            template:'
' +
                '  ×' +
                '  {{message}}' +
                '
'
        }
    });

module.directive('playPauseVideoHtml5', function(video) {
    return {
        link: function(scope, element, attrs) {
            scope.$watch(attrs.playPauseVideoHtml5, function(newValue, oldValue) {
                if(newValue != oldValue && video.player) {
                    newValue ? video.player.play() : video.player.pause();
                }
            });
        }
    }
});

module.directive('playPauseVideoYoutube', function(youtubePlayerApi) {
    return {
        link: function(scope, element, attrs) {
            scope.$watch(attrs.playPauseVideoYoutube, function(newValue, oldValue) {
                if(newValue != oldValue && youtubePlayerApi.player) {
                    newValue ? youtubePlayerApi.player.playVideo() : youtubePlayerApi.player.pauseVideo();
                }
            });
        }
    }
});

module.directive('bootstrapTooltip', function(youtubePlayerApi) {
    return {
        restrict:'A',
        link: function(scope, element) {
            $(element).tooltip();
        }
    }
});

module.directive('bootstrapSwitch', function() {
    return {
        restrict:'E',
        scope: {
            property: "="
        },
        link: function(scope, element) {
            $(element).bootstrapSwitch();

            scope.$watch('property', function () {
                if(scope.property !== undefined)
                    $(element).bootstrapSwitch('setState', scope.property);
            });

            $(element).on('switch-change', function (e, data) {
                scope.property = data.value;
                scope.$apply();
            });
        },
        replace: true,
        template: '
\n    <input type="checkbox" />\n
'

    }
});<commit_msg>Conditional $apply<commit_after>'use strict';

var module = angular.module('app.directives', []);

module.directive('aceEditor',
    function (editor) {
        return {
            restrict:'A',
            scope: {
                sync: "="
            },
            link:function (scope, element) {
                editor.rebind(element[0]);

                scope.$watch('sync', function(newValue, oldValue) {
                    if(newValue !== oldValue) {
                        newValue ? $('.ace_gutter').removeClass('inactive') : $('.ace_gutter').addClass('inactive');
                    }
                }, true);
            }
        };
    });

module.directive('html5VideoPlayer',
    function (video) {
        return {
            restrict:'A',
            link:function (scope, element) {
                video.bindVideoPlayer(element[0]);
            }
        };
    });

module.directive('star',
    function () {
        return {
            restrict:'E',
            replace:true,
            scope:{
                val:'=value',
                // Value bound to
                eventFn:'&click'
                // Optional expression evaluated on click
            },
            link:function (scope, element) {
                element.bind('click',
                    function () {
                        scope.$apply(function () {
                            scope.val = !scope.val;
                        });
                        scope.$eval(scope.eventFn, scope.val);
                    });
            },
            template:''
        }
    });

module.directive('alert',
    function ($rootScope, analytics) {
        return {
            restrict:'E',
            replace:true,
            link:function (scope, element) {
                $rootScope.$on('error',
                    function (event, data) {
                        scope.$apply(function () {
                            analytics.pushAnalytics('Error', data.message);
                            scope.message = data.message;
                            $(element).show();
                        });
                    });
                scope.close = function () {
                    $(element).hide();
                };
            },
            template:'
' +
                '  ×' +
                '  {{message}}' +
                '
'
        }
    });

module.directive('playPauseVideoHtml5', function(video) {
    return {
        link: function(scope, element, attrs) {
            scope.$watch(attrs.playPauseVideoHtml5, function(newValue, oldValue) {
                if(newValue != oldValue && video.player) {
                    newValue ? video.player.play() : video.player.pause();
                }
            });
        }
    }
});

module.directive('playPauseVideoYoutube', function(youtubePlayerApi) {
    return {
        link: function(scope, element, attrs) {
            scope.$watch(attrs.playPauseVideoYoutube, function(newValue, oldValue) {
                if(newValue != oldValue && youtubePlayerApi.player) {
                    newValue ? youtubePlayerApi.player.playVideo() : youtubePlayerApi.player.pauseVideo();
                }
            });
        }
    }
});

module.directive('bootstrapTooltip', function(youtubePlayerApi) {
    return {
        restrict:'A',
        link: function(scope, element) {
            $(element).tooltip();
        }
    }
});

module.directive('bootstrapSwitch', function($rootScope) {
    return {
        restrict:'E',
        scope: {
            property: "="
        },
        link: function(scope, element) {
            $(element).bootstrapSwitch();

            scope.$watch('property', function () {
                if(scope.property !== undefined)
                    $(element).bootstrapSwitch('setState', scope.property);
            });

            $(element).on('switch-change', function (e, data) {
                scope.property = data.value;
                $rootScope.$$phase || $rootScope.$apply();
            });
        },
        replace: true,
        template: '
\n    <input type="checkbox" />\n
'

    }
});<|endoftext|>


<commit_before>function babelWebV2() {
    let babelDesc = {};
    let current = "unknown";

    let routers = {};
    let nodes = [];
    let links = [];
    let metrics = [];

    let addrToRouterId;

    let initEnd = false;
    let lostUpdate = false;

    let svg, color, width, height, simulation, vis, koef = 1;

    const palette = {
        "gray": "#777",
        "lightGray": "#ddd",
        "blue": "#03f",
        "violet": "#c0f",
        "pink": "#f69",
        "green": "#4d4",
        "lightGreen": "#8e8",
        "yellow": "#ff0",
        "orange": "#f18973",
        "red": "#f30"
    };

    const colors = {
        installed: palette.green,
        uninstalled: palette.lightGreen,
        unreachable: palette.lightGray,
        wiredLink: palette.yellow,
        losslessWireless: palette.orange,
        unreachableNeighbour: palette.red,
        current: palette.pink,
        neighbour: palette.violet,
        other: palette.blue,
        selected: palette.blue,
        route: palette.gray
    };

    function connect(socketWarper) {
        socketWarper.socket = new WebSocket(`ws${location.protocol == 'https:' ? 's' : ''}://${location.href.replace(/http.*\:\/\//, '')}ws`)

        socketWarper.socket.onerror = console.error;

        socketWarper.socket.onopen = function(event) {
            d3.selectAll("body").select("#state")
                .text("Connected").style("background-color", "green");
        }

        socketWarper.socket.onclose = function(event) {
            d3.selectAll("body").select("#state")
                .text("Disconnected").style("background-color", "red");
        }

        socketWarper.socket.onmessage = convertJSON;
        redraw();
    }

    function convertJSON(event) {
        let data = JSON.parse(event.data);

        if (!'router' in data) {
            throw "No router in update";
        }

        if (current === "unknown")
            current = data.router;

        if (!(data.router in babelDesc))
            babelDesc[data.router] = {
                "self": {
                    "name": data.name,
                    "id": data.router
                },
                "interface": {},
                "neighbour": {},
                "route": {},
                "xroute": {},
            };
        babelDesc[data.router].self.name = data.name;
        babelDesc[data.router][data.table][data.id] = {};
        if (data.action === "flush")
            delete babelDesc[data.router][data.table][data.id];
        else {
            for (let key in data.data) {
                babelDesc[data.router][data.table][data.id][key] =
                    data.data[key];
            }
        }

        updateSwitch();
        if (data.router === current)
            updateCurrent(current);
    }

    function isEmpty() {
        for (t in babelDesc[current]) {
            if (t == "self")
                continue;
            for (i in babelDesc[current][t])
                return metrics.length <= 1;
        }
        return true;
    }

    function updateSwitch() {
        let options = d3.select("#nodes").selectAll("option")
            .data(d3.keys(babelDesc), function(d) {
                return d;
            });
        options.enter().append("option")
            .attr("value", function(d) {
                return d;
            })
            .text(function(d) {
                return babelDesc[d].self.name;
            });
        options.exit().remove();
        d3.selectAll("#nodes option").sort(function(x, y) {
            if (x === "unknown")
                return -1;
            else
                return babelDesc[x].self.name
                    .localeCompare(babelDesc[y].self.name);
        });

        let sel = document.getElementById("nodes");
        for (let i, j = 0; i = sel.options[j]; j++) {
            if (i.value == current) {
                sel.selectedIndex = j;
                break;
            }
        }
    }

    function updateCurrent(newCurrent) {
        if (!initEnd) {
            lostUpdate = true;
            return;
        }

        if (current != newCurrent) {
            oneToOne();
            routers = {};
        }

        current = newCurrent;
        updateTable("neighbour");
        updateTable("route");
        updateTable("xroute");
        recomputeNetwork();
        redraw();
    }

    function zoomOut(factor) {
        koef /= factor;

        if (koef == 1)
            d3.select("#oto").attr("disabled", true);
        else
            d3.select("#oto").attr("disabled", null);

        redraw();
    }

    function zoomIn(factor) {
        zoomOut(1 / factor);
    }

    function oneToOne() {
        zoomOut(koef);
    }

    function initGraph() {
        width = 600;
        height = 400;

        vis = d3.select("#fig")
            .insert("svg:svg", ".legend")
            .attr("width", width)
            .attr("height", height)
            .attr("stroke-width", "1.5px");

        svg = d3.select("svg");
        width = +svg.attr("width");
        height = +svg.attr("height");
        color = d3.scaleOrdinal(d3.schemeCategory20);

        simulation = d3.forceSimulation()
            .force("link", d3.forceLink())
            .force("charge", d3.forceManyBody().strength(-500))
            .on("tick", ticked);

        initEnd = true;
        if (lostUpdate) {
            updateCurrent(current);
            lostUpdate = false;
        }
    }

    function recomputeNetwork() {
        if (typeof routers[current] == 'undefined') {
            routers[current] = {
                id: current,
                metric: 0,
                fx: width / 2,
                fy: height / 2,
                fixed: true
            };
        }

        function first(array, f) {
            let i = 0,
                n = array.length,
                a = array[0],
                b;
            while (++i < n) {
                if (f.call(array, a, b = array[i]) > 0) {
                    a = b;
                }
            }
            return a;
        }

        function insertKey(arr, obj) {
            for (let i = 0; i < arr.length; i++) {
                if (arr[i].key == obj.key) return arr;
            }
            arr.push(obj);
            return arr;
        }

        for (let r in routers) {
            routers[r].metric = undefined;
        }
        routers[current].metric = 0;

        let neighToRouterMetric = {};
        for (let route in babelDesc[current].route) {
            let r = babelDesc[current].route[route];
            let metric = r.metric;
            let refmetric = r.refmetric;

            if (!routers[r.id]) {
                routers[r.id] = {
                    id: r.id,
                    metric: metric,
                    via: r.via
                };
            } else {
                if (routers[r.id].metric == undefined ||
                    metric < routers[r.id].metric) {
                    routers[r.id].metric = metric;
                    routers[r.id].via = r.via;
                }
            }

            if (!neighToRouterMetric[r.via])
                neighToRouterMetric[r.via] = {};
            if (!neighToRouterMetric[r.via][r.id])
                neighToRouterMetric[r.via][r.id] = {
                    refmetric: refmetric
                };
            else
                neighToRouterMetric[r.via][r.id].refmetric =
                Math.min(neighToRouterMetric[r.via][r.id].refmetric, refmetric);
        }

        addrToRouterId = {};
        for (let n in neighToRouterMetric) {
            addrToRouterId[n] =
                first(d3.entries(neighToRouterMetric[n]),
                    function(a, b) {
                        return a.value.refmetric - b.value.refmetric;
                    }).key;
        }

        nodes = [];
        metrics = [];
        for (let r in routers) {
            if (routers[r].metric == undefined)
                delete routers[r];
            else {
                nodes.push(routers[r]);
                metrics.push({
                    source: routers[current],
                    target: routers[r],
                    metric: routers[r].metric,
                });
            }
        }
        for (let n in neighToRouterMetric)
            for (let id in neighToRouterMetric[n])
                metrics.push({
                    source: routers[addrToRouterId[n]],
                    target: routers[id],
                    metric: neighToRouterMetric[n][id].refmetric
                });

        links = [];
        for (let r_key in babelDesc[current].route) {
            let r = babelDesc[current].route[r_key];
            if (r.metric == 65535)
                continue;

            insertKey(links, {
                key: normalizeId(r.id + r.via + r.installed),
                path: [routers[current],
                    routers[addrToRouterId[r.via]],
                    routers[r.id]
                ],
                installed: r.installed
            });
        }
    }

    function redraw() {
        function isNeighbour(id) {
            for (let n in babelDesc[current].neighbour)
                if (addrToRouterId[babelDesc[current].neighbour[n].address] ==
                    id)
                    return true;
            return false;
        }

        if (isEmpty()) {
            d3.select("#oto").attr("disabled", true);
            d3.select("#zin").attr("disabled", true);
            d3.select("#zout").attr("disabled", true);
        } else {
            // It's not an error that there is no #oto (I hope so)
            d3.select("#zin").attr("disabled", null);
            d3.select("#zout").attr("disabled", null);
        }

        simulation.force("link")
            .links(metrics)
            .strength(1)
            .distance(function(d) {
                return d.metric * koef;
            });

        let node = vis.selectAll("circle.node")
            .data(nodes);
        node.enter().append("svg:circle")
            .attr("class", "node")
            .attr("r", 5)
            .attr("stroke", "white")
            .attr("id", function(d) {
                return "node-" + normalizeId(d.id);
            })
            .call(d3.drag()
                .on("start", dragstarted)
                .on("drag", dragged)
                .on("end", dragended))
            .append("svg:title");
        node.exit().remove();
        vis.selectAll("circle.node")
            .style("fill", function(d) {
                return (d.id == current) ?
                    colors.current : (isNeighbour(d.id) ?
                        colors.neighbour : colors.other);
            })
            .each(function(d) {
                d3.select(this).select("title")
                    .text(
                        nodeName(d.id) +
                        " [" + d.id + "]" +
                        " (metric: " + d.metric + ")");
            });

        function nodeName(id) {
            let name = (babelDesc[id] && babelDesc[id].self.name) || "unknown";
            return name;
        }

        let route_path = d3.line()
            .x(function(d) {
                if (typeof d == 'undefined') return null;
                else return d.x;
            })
            .y(function(d) {
                if (typeof d == 'undefined') return null;
                else return d.y;
            })
            .curve();

        let link = vis.selectAll("path.route")
            .data(links);
        link.enter().insert("svg:path", "circle.node")
            .attr("class", "route")
            .attr("stroke", colors.route)
            .attr("fill", "none")
            .attr("id", function(d) {
                return "link-" + d.key;
            })
            .attr("d", function(d) {
                return route_path(d.path);
            });
        link.exit().remove();

        simulation.alpha(1).restart();
        simulation.nodes(nodes);
    }

    function ticked() {

        vis.selectAll("circle.node")
            .attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; });

        let route_path = d3.line()
            .x(function(d) {
                if (typeof d == 'undefined') return null;
                else return d.x;
            })
            .y(function(d) {
                if (typeof d == 'undefined') return null;
                else return d.y;
            })
            .curve(d3.curveLinear);

        let show_all = d3.select("#show_all").property("checked");
        vis.selectAll("path.route")
            .attr("display", function(d) {
                return (d.installed && d.metric != 65535) || show_all ?
                    "inline" : "none";
            })
            .attr("opacity", function(d) {
                return d.installed ? "1" : "0.3";
            })
            .attr("stroke", colors.route)
            .attr("stroke-dasharray", function(d) {
                return d.installed ? "none" : "5,2";
            })
            .attr("d", function(d) {
                return route_path(d.path);
            });
    }

    function dragstarted(d) {
        if (d.id == current)
            return;
        if (!d3.event.active)
            simulation.alphaTarget(0.3).restart();
        d.fx = d.x;
        d.fy = d.y;
    }

    function dragged(d) {
        if (d.id == current)
            return;
        d.fx = d3.event.x;
        d.fy = d3.event.y;
    }

    function dragended(d) {
        if (d.id == current)
            return;
        if (!d3.event.active)
            simulation.alphaTarget(0);
        d.fx = null;
        d.fy = null;
    }

    function normalizeId(s) {
        let allowedChars = "0123456789abcdef";
        let res = "";
        for (let i = 0; i < s.length; i++) {
            let c = s.charAt(i);
            if (allowedChars.indexOf(c) != -1)
                res += c;
        }
        return res;
    }

    function updateRow(d, name, headers) {
        let tr = d3.select(this);

        let costColor = d3.scaleLog()
            .domain([0, 96, 256, 65535])
            .range([colors.wiredLink,
                colors.wiredLink,
                colors.losslessWireless,
                colors.unreachableNeighbour
            ])
            .interpolate(d3.interpolateHcl);

        if (name == "route")
            tr.style("background-color",
                (d.value.metric == 65535 ? colors.unreachable :
                    d.value.installed ? colors.installed :
                    colors.uninstalled));
        else if (name == "neighbour")
            tr.style("background-color", costColor(d.value.rxcost));

        let row = tr.selectAll("td")
            .data(headers.map(function(h) {
                if (h == "reach") {
                    s = d.value[h].toString(16);
                    for (; s.length < 4;)
                        s = "0" + s;
                    return s;
                }
                return d.value[h];
            }));
        row.text(function(d) { return d; });
        row.enter().append("td").text(function(d) { return d; });
    }

    function updateTable(name) {
        let table = d3.select("#" + name);
        table.select("tr.loading").remove();
        let headers = [];
        table.selectAll("th").each(function() {
            headers.push(d3.select(this).text());
        });
        let rows = table.select("tbody").selectAll("tr")
            .data(d3.entries(babelDesc[current][name]), function(d) {
                if (typeof d == 'undefined') return null;
                else return d.key;
            });
        rows.enter().append("tr")
            .attr("id", function(d) {
                return name + "-" + normalizeId(d.key);
            });
        rows.exit().remove();
        table.select("tbody")
            .selectAll("tr")
            .each(function(d) {
                updateRow.call(this, d, name, headers);
            });
    }

    babelWebV2.connect = connect;
    babelWebV2.initGraph = initGraph;
    babelWebV2.updateCurrent = updateCurrent;
    babelWebV2.redraw = redraw;
    babelWebV2.zoomIn = zoomIn;
    babelWebV2.zoomOut = zoomOut;
    babelWebV2.oneToOne = oneToOne;

    return babelWebV2;
}
<commit_msg>Add forgotten semicolons.<commit_after>function babelWebV2() {
    let babelDesc = {};
    let current = "unknown";

    let routers = {};
    let nodes = [];
    let links = [];
    let metrics = [];

    let addrToRouterId;

    let initEnd = false;
    let lostUpdate = false;

    let svg, color, width, height, simulation, vis, koef = 1;

    const palette = {
        "gray": "#777",
        "lightGray": "#ddd",
        "blue": "#03f",
        "violet": "#c0f",
        "pink": "#f69",
        "green": "#4d4",
        "lightGreen": "#8e8",
        "yellow": "#ff0",
        "orange": "#f18973",
        "red": "#f30"
    };

    const colors = {
        installed: palette.green,
        uninstalled: palette.lightGreen,
        unreachable: palette.lightGray,
        wiredLink: palette.yellow,
        losslessWireless: palette.orange,
        unreachableNeighbour: palette.red,
        current: palette.pink,
        neighbour: palette.violet,
        other: palette.blue,
        selected: palette.blue,
        route: palette.gray
    };

    function connect(socketWarper) {
        socketWarper.socket = new WebSocket(`ws${location.protocol == 'https:' ? 's' : ''}://${location.href.replace(/http.*\:\/\//, '')}ws`);

        socketWarper.socket.onerror = console.error;

        socketWarper.socket.onopen = function(event) {
            d3.selectAll("body").select("#state")
                .text("Connected").style("background-color", "green");
        };

        socketWarper.socket.onclose = function(event) {
            d3.selectAll("body").select("#state")
                .text("Disconnected").style("background-color", "red");
        };

        socketWarper.socket.onmessage = convertJSON;
        redraw();
    }

    function convertJSON(event) {
        let data = JSON.parse(event.data);

        if (!'router' in data) {
            throw "No router in update";
        }

        if (current === "unknown")
            current = data.router;

        if (!(data.router in babelDesc))
            babelDesc[data.router] = {
                "self": {
                    "name": data.name,
                    "id": data.router
                },
                "interface": {},
                "neighbour": {},
                "route": {},
                "xroute": {},
            };
        babelDesc[data.router].self.name = data.name;
        babelDesc[data.router][data.table][data.id] = {};
        if (data.action === "flush")
            delete babelDesc[data.router][data.table][data.id];
        else {
            for (let key in data.data) {
                babelDesc[data.router][data.table][data.id][key] =
                    data.data[key];
            }
        }

        updateSwitch();
        if (data.router === current)
            updateCurrent(current);
    }

    function isEmpty() {
        for (t in babelDesc[current]) {
            if (t == "self")
                continue;
            for (i in babelDesc[current][t])
                return metrics.length <= 1;
        }
        return true;
    }

    function updateSwitch() {
        let options = d3.select("#nodes").selectAll("option")
            .data(d3.keys(babelDesc), function(d) {
                return d;
            });
        options.enter().append("option")
            .attr("value", function(d) {
                return d;
            })
            .text(function(d) {
                return babelDesc[d].self.name;
            });
        options.exit().remove();
        d3.selectAll("#nodes option").sort(function(x, y) {
            if (x === "unknown")
                return -1;
            else
                return babelDesc[x].self.name
                    .localeCompare(babelDesc[y].self.name);
        });

        let sel = document.getElementById("nodes");
        for (let i, j = 0; i = sel.options[j]; j++) {
            if (i.value == current) {
                sel.selectedIndex = j;
                break;
            }
        }
    }

    function updateCurrent(newCurrent) {
        if (!initEnd) {
            lostUpdate = true;
            return;
        }

        if (current != newCurrent) {
            oneToOne();
            routers = {};
        }

        current = newCurrent;
        updateTable("neighbour");
        updateTable("route");
        updateTable("xroute");
        recomputeNetwork();
        redraw();
    }

    function zoomOut(factor) {
        koef /= factor;

        if (koef == 1)
            d3.select("#oto").attr("disabled", true);
        else
            d3.select("#oto").attr("disabled", null);

        redraw();
    }

    function zoomIn(factor) {
        zoomOut(1 / factor);
    }

    function oneToOne() {
        zoomOut(koef);
    }

    function initGraph() {
        width = 600;
        height = 400;

        vis = d3.select("#fig")
            .insert("svg:svg", ".legend")
            .attr("width", width)
            .attr("height", height)
            .attr("stroke-width", "1.5px");

        svg = d3.select("svg");
        width = +svg.attr("width");
        height = +svg.attr("height");
        color = d3.scaleOrdinal(d3.schemeCategory20);

        simulation = d3.forceSimulation()
            .force("link", d3.forceLink())
            .force("charge", d3.forceManyBody().strength(-500))
            .on("tick", ticked);

        initEnd = true;
        if (lostUpdate) {
            updateCurrent(current);
            lostUpdate = false;
        }
    }

    function recomputeNetwork() {
        if (typeof routers[current] == 'undefined') {
            routers[current] = {
                id: current,
                metric: 0,
                fx: width / 2,
                fy: height / 2,
                fixed: true
            };
        }

        function first(array, f) {
            let i = 0,
                n = array.length,
                a = array[0],
                b;
            while (++i < n) {
                if (f.call(array, a, b = array[i]) > 0) {
                    a = b;
                }
            }
            return a;
        }

        function insertKey(arr, obj) {
            for (let i = 0; i < arr.length; i++) {
                if (arr[i].key == obj.key) return arr;
            }
            arr.push(obj);
            return arr;
        }

        for (let r in routers) {
            routers[r].metric = undefined;
        }
        routers[current].metric = 0;

        let neighToRouterMetric = {};
        for (let route in babelDesc[current].route) {
            let r = babelDesc[current].route[route];
            let metric = r.metric;
            let refmetric = r.refmetric;

            if (!routers[r.id]) {
                routers[r.id] = {
                    id: r.id,
                    metric: metric,
                    via: r.via
                };
            } else {
                if (routers[r.id].metric == undefined ||
                    metric < routers[r.id].metric) {
                    routers[r.id].metric = metric;
                    routers[r.id].via = r.via;
                }
            }

            if (!neighToRouterMetric[r.via])
                neighToRouterMetric[r.via] = {};
            if (!neighToRouterMetric[r.via][r.id])
                neighToRouterMetric[r.via][r.id] = {
                    refmetric: refmetric
                };
            else
                neighToRouterMetric[r.via][r.id].refmetric =
                Math.min(neighToRouterMetric[r.via][r.id].refmetric, refmetric);
        }

        addrToRouterId = {};
        for (let n in neighToRouterMetric) {
            addrToRouterId[n] =
                first(d3.entries(neighToRouterMetric[n]),
                    function(a, b) {
                        return a.value.refmetric - b.value.refmetric;
                    }).key;
        }

        nodes = [];
        metrics = [];
        for (let r in routers) {
            if (routers[r].metric == undefined)
                delete routers[r];
            else {
                nodes.push(routers[r]);
                metrics.push({
                    source: routers[current],
                    target: routers[r],
                    metric: routers[r].metric,
                });
            }
        }
        for (let n in neighToRouterMetric)
            for (let id in neighToRouterMetric[n])
                metrics.push({
                    source: routers[addrToRouterId[n]],
                    target: routers[id],
                    metric: neighToRouterMetric[n][id].refmetric
                });

        links = [];
        for (let r_key in babelDesc[current].route) {
            let r = babelDesc[current].route[r_key];
            if (r.metric == 65535)
                continue;

            insertKey(links, {
                key: normalizeId(r.id + r.via + r.installed),
                path: [routers[current],
                    routers[addrToRouterId[r.via]],
                    routers[r.id]
                ],
                installed: r.installed
            });
        }
    }

    function redraw() {
        function isNeighbour(id) {
            for (let n in babelDesc[current].neighbour)
                if (addrToRouterId[babelDesc[current].neighbour[n].address] ==
                    id)
                    return true;
            return false;
        }

        if (isEmpty()) {
            d3.select("#oto").attr("disabled", true);
            d3.select("#zin").attr("disabled", true);
            d3.select("#zout").attr("disabled", true);
        } else {
            // It's not an error that there is no #oto (I hope so)
            d3.select("#zin").attr("disabled", null);
            d3.select("#zout").attr("disabled", null);
        }

        simulation.force("link")
            .links(metrics)
            .strength(1)
            .distance(function(d) {
                return d.metric * koef;
            });

        let node = vis.selectAll("circle.node")
            .data(nodes);
        node.enter().append("svg:circle")
            .attr("class", "node")
            .attr("r", 5)
            .attr("stroke", "white")
            .attr("id", function(d) {
                return "node-" + normalizeId(d.id);
            })
            .call(d3.drag()
                .on("start", dragstarted)
                .on("drag", dragged)
                .on("end", dragended))
            .append("svg:title");
        node.exit().remove();
        vis.selectAll("circle.node")
            .style("fill", function(d) {
                return (d.id == current) ?
                    colors.current : (isNeighbour(d.id) ?
                        colors.neighbour : colors.other);
            })
            .each(function(d) {
                d3.select(this).select("title")
                    .text(
                        nodeName(d.id) +
                        " [" + d.id + "]" +
                        " (metric: " + d.metric + ")");
            });

        function nodeName(id) {
            let name = (babelDesc[id] && babelDesc[id].self.name) || "unknown";
            return name;
        }

        let route_path = d3.line()
            .x(function(d) {
                if (typeof d == 'undefined') return null;
                else return d.x;
            })
            .y(function(d) {
                if (typeof d == 'undefined') return null;
                else return d.y;
            })
            .curve();

        let link = vis.selectAll("path.route")
            .data(links);
        link.enter().insert("svg:path", "circle.node")
            .attr("class", "route")
            .attr("stroke", colors.route)
            .attr("fill", "none")
            .attr("id", function(d) {
                return "link-" + d.key;
            })
            .attr("d", function(d) {
                return route_path(d.path);
            });
        link.exit().remove();

        simulation.alpha(1).restart();
        simulation.nodes(nodes);
    }

    function ticked() {

        vis.selectAll("circle.node")
            .attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; });

        let route_path = d3.line()
            .x(function(d) {
                if (typeof d == 'undefined') return null;
                else return d.x;
            })
            .y(function(d) {
                if (typeof d == 'undefined') return null;
                else return d.y;
            })
            .curve(d3.curveLinear);

        let show_all = d3.select("#show_all").property("checked");
        vis.selectAll("path.route")
            .attr("display", function(d) {
                return (d.installed && d.metric != 65535) || show_all ?
                    "inline" : "none";
            })
            .attr("opacity", function(d) {
                return d.installed ? "1" : "0.3";
            })
            .attr("stroke", colors.route)
            .attr("stroke-dasharray", function(d) {
                return d.installed ? "none" : "5,2";
            })
            .attr("d", function(d) {
                return route_path(d.path);
            });
    }

    function dragstarted(d) {
        if (d.id == current)
            return;
        if (!d3.event.active)
            simulation.alphaTarget(0.3).restart();
        d.fx = d.x;
        d.fy = d.y;
    }

    function dragged(d) {
        if (d.id == current)
            return;
        d.fx = d3.event.x;
        d.fy = d3.event.y;
    }

    function dragended(d) {
        if (d.id == current)
            return;
        if (!d3.event.active)
            simulation.alphaTarget(0);
        d.fx = null;
        d.fy = null;
    }

    function normalizeId(s) {
        let allowedChars = "0123456789abcdef";
        let res = "";
        for (let i = 0; i < s.length; i++) {
            let c = s.charAt(i);
            if (allowedChars.indexOf(c) != -1)
                res += c;
        }
        return res;
    }

    function updateRow(d, name, headers) {
        let tr = d3.select(this);

        let costColor = d3.scaleLog()
            .domain([0, 96, 256, 65535])
            .range([colors.wiredLink,
                colors.wiredLink,
                colors.losslessWireless,
                colors.unreachableNeighbour
            ])
            .interpolate(d3.interpolateHcl);

        if (name == "route")
            tr.style("background-color",
                (d.value.metric == 65535 ? colors.unreachable :
                    d.value.installed ? colors.installed :
                    colors.uninstalled));
        else if (name == "neighbour")
            tr.style("background-color", costColor(d.value.rxcost));

        let row = tr.selectAll("td")
            .data(headers.map(function(h) {
                if (h == "reach") {
                    s = d.value[h].toString(16);
                    for (; s.length < 4;)
                        s = "0" + s;
                    return s;
                }
                return d.value[h];
            }));
        row.text(function(d) { return d; });
        row.enter().append("td").text(function(d) { return d; });
    }

    function updateTable(name) {
        let table = d3.select("#" + name);
        table.select("tr.loading").remove();
        let headers = [];
        table.selectAll("th").each(function() {
            headers.push(d3.select(this).text());
        });
        let rows = table.select("tbody").selectAll("tr")
            .data(d3.entries(babelDesc[current][name]), function(d) {
                if (typeof d == 'undefined') return null;
                else return d.key;
            });
        rows.enter().append("tr")
            .attr("id", function(d) {
                return name + "-" + normalizeId(d.key);
            });
        rows.exit().remove();
        table.select("tbody")
            .selectAll("tr")
            .each(function(d) {
                updateRow.call(this, d, name, headers);
            });
    }

    babelWebV2.connect = connect;
    babelWebV2.initGraph = initGraph;
    babelWebV2.updateCurrent = updateCurrent;
    babelWebV2.redraw = redraw;
    babelWebV2.zoomIn = zoomIn;
    babelWebV2.zoomOut = zoomOut;
    babelWebV2.oneToOne = oneToOne;

    return babelWebV2;
}
<|endoftext|>


<commit_before>/**
 * Support file for Libravatar
 * @source: https://code.launchpad.net/libravatar
 *
 * @licstart
 * Copyright (C) 2011, 2012, 2013 Francois Marier <francois@libravatar.org>
 *
 * The JavaScript code in this page is free software: you can
 * redistribute it and/or modify it under the terms of the GNU Affero
 * General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. The code is distributed 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.
 *
 * As an additional permission under GNU AGPL version 3 section 7, you
 * may distribute non-source (e.g., minimized or compacted) forms of
 * that code without the copy of the GNU AGPL normally required by
 * section 4, provided you include this license notice and a URL
 * through which recipients can access the Corresponding Source.
 * @licend
 */

"use strict";

// Autofocus the right field on forms
if (document.forms.login) {
    if (document.forms.login.username) {
        document.forms.login.username.focus();
    } else if (document.forms.login.openid_identifier) {
        document.forms.login.openid_identifier.focus();
    }
} else if (document.forms.addemail) {
    document.forms.addemail.email.focus();
} else if (document.forms.addopenid) {
    document.forms.addopenid.openid.focus();
} else if (document.forms.changepassword) {
    document.forms.changepassword.old_password.focus();
} else if (document.forms.deleteaccount) {
    if (document.forms.deleteaccount.password) {
        document.forms.deleteaccount.password.focus();
    }
} else if (document.forms.lookup) {
    if (document.forms.lookup.email) {
        document.forms.lookup.email.focus();
    } else if (document.forms.lookup.domain) {
        document.forms.lookup.domain.focus();
    }
} else if (document.forms.newaccount) {
    document.forms.newaccount.username.focus();
} else if (document.forms.reset) {
    document.forms.reset.email.focus();
}

var is_addemail = false;
if ($('#form-addemail').length > 0) {
    is_addemail = true;
}
var email_requested = false;

var browserid_user = $('#browserid-user').text();
if (browserid_user === '') {
    browserid_user = null;
}

if (!LOGGED_IN_PAGE) {
    var LOGGED_IN_PAGE = '/account/profile/';
}
if (!LOGGED_OUT_PAGE) {
    var LOGGED_OUT_PAGE = '/account/logout/';
}

if (navigator.id) {
    // Show BrowserID option and make links clickable
    $('#browserid-option').show();
    var browserid_link = $('#browserid-link');
    browserid_link.attr('href', '#');
    browserid_link.bind('click', browserid_login);
    var logout_link = $('#logout-link');
    if (browserid_user && !is_addemail) {
        logout_link.attr('href', '#');
        logout_link.bind('click', function () {
            browserid_logout(false);
        });
    }

    // Silent logouts for operations that clear the browserid_user session variable
    $('#deleteaccount-button').bind('click', function () {
        browserid_logout(true);
    });
    $('#remove-browserid-user').bind('click', function () {
        browserid_logout(true);
    });

    var post_url = '/account/login_browserid/';
    if (is_addemail) {
        post_url = '/account/add_browserid/';
    }

    navigator.id.watch({
        loggedInUser: browserid_user,
        onlogin: function (assertion) {
            if (assertion && (!is_addemail || email_requested)) {
                $.post(post_url, {assertion: assertion}, function (data) {
                    if (data.success === true) {
                        if (data.user !== browserid_user) {
                            window.location = LOGGED_IN_PAGE;
                        }
                    } else {
                        alert(data.error);
                        browserid_logout(true);
                    }
                });
            }
        },
        onlogout: function () {
            if (browserid_user) {
                window.location = LOGGED_OUT_PAGE;
            }
        }
    });
}

// For main BrowserID functionality
function browserid_login() {
    email_requested = true;
    navigator.id.request({siteLogo: '/img/logo.png',
                          siteName: $('#site-name').text()});
}
function browserid_logout(silent) {
    if (silent) {
        // make sure onlogout doesn't redirect
        browserid_user = null;
    }
    navigator.id.logout();
}
<commit_msg>Specify a background color for the Persona dialog (bug #1202483)<commit_after>/**
 * Support file for Libravatar
 * @source: https://code.launchpad.net/libravatar
 *
 * @licstart
 * Copyright (C) 2011, 2012, 2013 Francois Marier <francois@libravatar.org>
 *
 * The JavaScript code in this page is free software: you can
 * redistribute it and/or modify it under the terms of the GNU Affero
 * General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. The code is distributed 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.
 *
 * As an additional permission under GNU AGPL version 3 section 7, you
 * may distribute non-source (e.g., minimized or compacted) forms of
 * that code without the copy of the GNU AGPL normally required by
 * section 4, provided you include this license notice and a URL
 * through which recipients can access the Corresponding Source.
 * @licend
 */

"use strict";

// Autofocus the right field on forms
if (document.forms.login) {
    if (document.forms.login.username) {
        document.forms.login.username.focus();
    } else if (document.forms.login.openid_identifier) {
        document.forms.login.openid_identifier.focus();
    }
} else if (document.forms.addemail) {
    document.forms.addemail.email.focus();
} else if (document.forms.addopenid) {
    document.forms.addopenid.openid.focus();
} else if (document.forms.changepassword) {
    document.forms.changepassword.old_password.focus();
} else if (document.forms.deleteaccount) {
    if (document.forms.deleteaccount.password) {
        document.forms.deleteaccount.password.focus();
    }
} else if (document.forms.lookup) {
    if (document.forms.lookup.email) {
        document.forms.lookup.email.focus();
    } else if (document.forms.lookup.domain) {
        document.forms.lookup.domain.focus();
    }
} else if (document.forms.newaccount) {
    document.forms.newaccount.username.focus();
} else if (document.forms.reset) {
    document.forms.reset.email.focus();
}

var is_addemail = false;
if ($('#form-addemail').length > 0) {
    is_addemail = true;
}
var email_requested = false;

var browserid_user = $('#browserid-user').text();
if (browserid_user === '') {
    browserid_user = null;
}

if (!LOGGED_IN_PAGE) {
    var LOGGED_IN_PAGE = '/account/profile/';
}
if (!LOGGED_OUT_PAGE) {
    var LOGGED_OUT_PAGE = '/account/logout/';
}

if (navigator.id) {
    // Show BrowserID option and make links clickable
    $('#browserid-option').show();
    var browserid_link = $('#browserid-link');
    browserid_link.attr('href', '#');
    browserid_link.bind('click', browserid_login);
    var logout_link = $('#logout-link');
    if (browserid_user && !is_addemail) {
        logout_link.attr('href', '#');
        logout_link.bind('click', function () {
            browserid_logout(false);
        });
    }

    // Silent logouts for operations that clear the browserid_user session variable
    $('#deleteaccount-button').bind('click', function () {
        browserid_logout(true);
    });
    $('#remove-browserid-user').bind('click', function () {
        browserid_logout(true);
    });

    var post_url = '/account/login_browserid/';
    if (is_addemail) {
        post_url = '/account/add_browserid/';
    }

    navigator.id.watch({
        loggedInUser: browserid_user,
        onlogin: function (assertion) {
            if (assertion && (!is_addemail || email_requested)) {
                $.post(post_url, {assertion: assertion}, function (data) {
                    if (data.success === true) {
                        if (data.user !== browserid_user) {
                            window.location = LOGGED_IN_PAGE;
                        }
                    } else {
                        alert(data.error);
                        browserid_logout(true);
                    }
                });
            }
        },
        onlogout: function () {
            if (browserid_user) {
                window.location = LOGGED_OUT_PAGE;
            }
        }
    });
}

// For main BrowserID functionality
function browserid_login() {
    email_requested = true;
    navigator.id.request({siteLogo: '/img/logo.png',
                          backgroundColor: '#fa711f',
                          siteName: $('#site-name').text()});
}
function browserid_logout(silent) {
    if (silent) {
        // make sure onlogout doesn't redirect
        browserid_user = null;
    }
    navigator.id.logout();
}
<|endoftext|>


<commit_before>'use strict';

var Graph = Graph || {};

Graph.globals = (function(){
	var screenWidth = null;
	var screenHeight = null;
	var smallBlockDim = null;
	var largeBlockDim = null;

    var smallBlockStrokeWidth = null;
    var largeBlockStrokeWidth = null;
    var gridStrokeWidth = null;
    var axisStrokeWidth = null;

	(function __init(){
		smallBlockDim = 10;
		largeBlockDim = 100;

        smallBlockStrokeWidth = 1;
        largeBlockStrokeWidth = 1.5;
        gridStrokeWidth = 2;
        axisStrokeWidth = 2.5;
	})();

	var callables = {
		setScreenDim: function($window){
			screenWidth = $window.width();
			screenHeight = $window.height();
		},

		getScreenDim: function(){
			return {
				screenWidth: screenWidth,
				screenHeight: screenHeight
			}
		},

		setBlockDim: function(blockDim){
			if (blockDim.hasOwnProperty('smallBlockDim') && blockDim.smallBlockDim !== null){
				smallBlockDim = blockDim.smallBlockDim;
			}
			if (blockDim.hasOwnProperty('largeBlockDim') && blockDim.largeBlockDim !== null){
				largeBlockDim = blockDim.largeBlockDim;
			}
		},

		getBlockDim: function(){
			return {
				smallBlockDim: smallBlockDim,
				largeBlockDim: largeBlockDim
			}
		},

        getStrokeWidth: function(){
            return {
                smallBlock: smallBlockStrokeWidth,
                largeBlock: largeBlockStrokeWidth,
                grid: gridStrokeWidth,
                axis: axisStrokeWidth
            }
        },

		createPathString: function(dim){
			return 'M ' + dim + ' 0 L 0 0 0 ' + dim
		},

		getPathAxisX: function(){
			var startY = Math.ceil((parseFloat(screenHeight) / 2) / largeBlockDim);

			return 'M 0 ' + (startY * largeBlockDim) + ' H ' + screenWidth;
		},

		getPathAxisY: function(){
			console.log(screenWidth)
			var startX = parseInt((parseFloat(screenWidth) / 2) / largeBlockDim);
			console.log(startX);
			return 'M ' + (startX * largeBlockDim) + ' 0 V ' + screenHeight;
		}

	}

	return callables;
})();
<commit_msg>Stroke width for grid and axis reduced to look clutter free.<commit_after>'use strict';

var Graph = Graph || {};

Graph.globals = (function(){
	var screenWidth = null;
	var screenHeight = null;
	var smallBlockDim = null;
	var largeBlockDim = null;

    var smallBlockStrokeWidth = null;
    var largeBlockStrokeWidth = null;
    var gridStrokeWidth = null;
    var axisStrokeWidth = null;

	(function __init(){
		smallBlockDim = 10;
		largeBlockDim = 100;

        smallBlockStrokeWidth = 0.2;
        largeBlockStrokeWidth = 0.5;
        gridStrokeWidth = 2;
        axisStrokeWidth = 1;
	})();

	var callables = {
		setScreenDim: function($window){
			screenWidth = $window.width();
			screenHeight = $window.height();
		},

		getScreenDim: function(){
			return {
				screenWidth: screenWidth,
				screenHeight: screenHeight
			}
		},

		setBlockDim: function(blockDim){
			if (blockDim.hasOwnProperty('smallBlockDim') && blockDim.smallBlockDim !== null){
				smallBlockDim = blockDim.smallBlockDim;
			}
			if (blockDim.hasOwnProperty('largeBlockDim') && blockDim.largeBlockDim !== null){
				largeBlockDim = blockDim.largeBlockDim;
			}
		},

		getBlockDim: function(){
			return {
				smallBlockDim: smallBlockDim,
				largeBlockDim: largeBlockDim
			}
		},

        getStrokeWidth: function(){
            return {
                smallBlock: smallBlockStrokeWidth,
                largeBlock: largeBlockStrokeWidth,
                grid: gridStrokeWidth,
                axis: axisStrokeWidth
            }
        },

		createPathString: function(dim){
			return 'M ' + dim + ' 0 L 0 0 0 ' + dim
		},

		getPathAxisX: function(){
			var startY = Math.ceil((parseFloat(screenHeight) / 2) / largeBlockDim);

			return 'M 0 ' + (startY * largeBlockDim) + ' H ' + screenWidth;
		},

		getPathAxisY: function(){
			console.log(screenWidth)
			var startX = parseInt((parseFloat(screenWidth) / 2) / largeBlockDim);
			console.log(startX);
			return 'M ' + (startX * largeBlockDim) + ' 0 V ' + screenHeight;
		}

	}

	return callables;
})();
<|endoftext|>


<commit_before>function sockets(){
    var socket = new WebSocket("ws://localhost:8765");
    window.frequency = 1;
    window.height = 0;
    window.width = 0;
    var hero = {};
    window.heroId = '';
    var units = [];

    socket.onopen = function(event) {
        console.log("Connected.");
    };

    socket.onclose = function(event) {
        if (event.wasClean) {
            console.log('Connection closed');
        } else {
            console.log('disconnection');
        }
            console.log('code: ' + event.code + ' reason: ' + event.reason);
    };

    socket.onmessage = function(event) {
        var answer = JSON.parse(event.data);
        console.log(answer);
        //if (answer.id)
        //    document.cookie = "hero_id=" + answer.id;
        if (answer.hasOwnProperty('frequency')) {
            frequency = answer.frequency;
            height = answer.field.height;
            width = answer.field.width;
            heroId = answer.id;
        }
        else if (units.length == 0) {
            units = answer;
            hero = units[heroId];
            restart(hero, units);
        }
        //else if (answer.hasOwnProperty('update')){
        //    unitUpdate(answer['update']);
        //}
        else {
            units = answer;
            hero = units[heroId];
            unitsUpdate(hero, units);
        }
    };

    socket.onerror = function(error) {
        console.log("Error " + error.message);
    };
}

<commit_msg>Set parameters for game field from server<commit_after>function sockets(){
    var socket = new WebSocket("ws://localhost:8765");
    window.frequency = 1;
    window.height = 0;
    window.width = 0;
    var hero = {};
    window.heroId = '';
    var units = [];

    socket.onopen = function(event) {
        console.log("Connected.");
    };

    socket.onclose = function(event) {
        if (event.wasClean) {
            console.log('Connection closed');
        } else {
            console.log('disconnection');
        }
            console.log('code: ' + event.code + ' reason: ' + event.reason);
    };

    socket.onmessage = function(event) {
        var answer = JSON.parse(event.data);
        console.log(answer);
        //if (answer.id)
        //    document.cookie = "hero_id=" + answer.id;
        if (answer.hasOwnProperty('frequency')) {
            frequency = answer.frequency;
            height = answer.field.height;
            width = answer.field.width;
            document.getElementById('gameCanvas').width=width;
            document.getElementById('gameCanvas').height=height;
            heroId = answer.id;
        }
        else if (units.length == 0) {
            units = answer;
            hero = units[heroId];
            restart(hero, units);
        }
        //else if (answer.hasOwnProperty('update')){
        //    unitUpdate(answer['update']);
        //}
        else {
            units = answer;
            hero = units[heroId];
            unitsUpdate(hero, units);
        }
    };

    socket.onerror = function(error) {
        console.log("Error " + error.message);
    };
}

<|endoftext|>


<commit_before>angular.module('qmsk.e2.tally', [
        'qmsk.e2.web',
        'ngResource',
        'ngRoute',
        'ngWebSocket',
        'luegg.directives',
        'jsonFormatter',
])

.config(function($routeProvider) {
    $routeProvider
        .when('/sources', {
            templateUrl: '/static/qmsk.e2/tally-sources.html',
            controller: 'SourcesCtrl',
            reloadOnSearch: false,
        })

        .when('/tally', {
            templateUrl: '/static/qmsk.e2/tally.html',
            controller: 'TallyCtrl',
            reloadOnSearch: false,
        })
        .otherwise({
            redirectTo: '/tally',
        });
})

.factory('Sources', function($http) {
    return $http.get('/api/sources').then(
        function success(r) {
            return r.data;
        }
    );
})

.factory('Tally', function($http) {
    return $http.get('/api/tally').then(
        function success(r) {
            return r.data;
        }
    );
})

.controller('HeaderCtrl', function($scope, $location, httpState) {
    $scope.state = httpState;

    $scope.isActive = function(prefix) {
        return $location.path().startsWith(prefix);
    };
})

.controller('SourcesCtrl', function($scope, Sources) {
    Sources.then(function(sources){
        $scope.sources = sources;
    });
})

.controller('TallyCtrl', function($scope, Tally) {
    Tally.then(function(tally){
        $scope.tally = tally;
    });
})

<commit_msg>tally web: use /api/events tally instead of REST /api/tally<commit_after>angular.module('qmsk.e2.tally', [
        'qmsk.e2.web',
        'ngResource',
        'ngRoute',
        'ngWebSocket',
        'luegg.directives',
        'jsonFormatter',
])

.config(function($routeProvider) {
    $routeProvider
        .when('/sources', {
            templateUrl: '/static/qmsk.e2/tally-sources.html',
            controller: 'SourcesCtrl',
            reloadOnSearch: false,
        })

        .when('/tally', {
            templateUrl: '/static/qmsk.e2/tally.html',
            controller: 'TallyCtrl',
            reloadOnSearch: false,
        })
        .otherwise({
            redirectTo: '/tally',
        });
})

.factory('Sources', function($http) {
    return $http.get('/api/sources').then(
        function success(r) {
            return r.data;
        }
    );
})

.factory('Tally', function($http) {
    return $http.get('/api/tally').then(
        function success(r) {
            return r.data;
        }
    );
})

.controller('HeaderCtrl', function($scope, $location, httpState) {
    $scope.state = httpState;

    $scope.isActive = function(prefix) {
        return $location.path().startsWith(prefix);
    };
})

.controller('SourcesCtrl', function($scope, Sources) {
    Sources.then(function(sources){
        $scope.sources = sources;
    });
})

.controller('TallyCtrl', function($scope, Events) {
    $scope.$on('qmsk.e2.event', function($e, event){
        $scope.tally = Events.state.tally;
    });
})
<|endoftext|>


<commit_before>/* global introJs */
$(document).ready(function() {
    var $btnToggleProviers = $('.btn-toggle-providers');
    var $btnHideProviers = $('.btn-hide-providers');
    var $btnLogin = $('.btn-login');
    var $loginProviders = $('.login-providers');
    var $school = $('.school');
    var $systems = $('.system');
    var $modals = $('.modal');
    var $pwRecoveryModal = $('.pwrecovery-modal');
    var $modalForm = $('.modal-form');

    var loadSystems = function(schoolId) {
        $systems.empty();
        $.getJSON('/login/systems/' + schoolId, function(systems) {
            systems.forEach(function(system) {
                var systemAlias = system.alias ? ' (' + system.alias + ')' : '';
                let selected;
                if(localStorage.getItem('loginSystem') == system._id) {
                    selected = true;
                }
                $systems.append('<option ' + (selected ? 'selected': '') + ' value="' + system._id + '">' + system.type + systemAlias + '</option>');
            });
            $systems.trigger('chosen:updated');
        });
    };

    $btnToggleProviers.on('click', function(e) {
        e.preventDefault();
        $btnToggleProviers.hide();
        $loginProviders.show();
    });

    $btnHideProviers.on('click', function(e) {
        e.preventDefault();
        $btnToggleProviers.show();
        $loginProviders.hide();
        $school.val('');
        $school.trigger('chosen:updated');
        $systems.val('');
        $systems.trigger('chosen:updated');
    });

    $btnLogin.on('click', function(e) {
        localStorage.setItem('loginSchool', $school.val());
        localStorage.setItem('loginSystem', $systems.val());
    });

    $school.on('change', function() {
        const id = $(this).val();
        loadSystems( id );
        $school.find("option").not("[value='"+id+"']").removeAttr('selected');
        $school.find("option[value='"+id+"']").attr('selected',true);
        $school.trigger('chosen:updated');
    });

    $('.submit-pwrecovery').on('click', function(e) {
        e.preventDefault();
        populateModalForm($pwRecoveryModal, {
            title: 'Passwort Zurücksetzen',
            closeLabel: 'Abbrechen',
            submitLabel: 'Abschicken'
        });
        $pwRecoveryModal.appendTo('body').modal('show');
    });

    $modals.find('.close, .btn-close').on('click', function() {
        $modals.modal('hide');
    });

    // if stored login system - use that
    if(localStorage.getItem('loginSchool')) {
        $btnToggleProviers.hide();
        $loginProviders.show();
        $school.val(localStorage.getItem('loginSchool'));
        $school.trigger('chosen:updated');
        $school.trigger('change');
    }

});

window.startIntro = function startIntro() {
    introJs()
    .setOptions({
        nextLabel: "Weiter",
        prevLabel: "Zurück",
        doneLabel: "Nächste Seite",
        skipLabel: "Überspringen"
    })
    .start()
    .oncomplete(function() {
        localStorage.setItem('Tutorial', true);
        document.querySelector("#loginarea > div > div > form:nth-child(3) > div > input").click();
    })
}<commit_msg>disable sw on logout of client user<commit_after>/* global introJs */
$(document).ready(function() {
    var $btnToggleProviers = $('.btn-toggle-providers');
    var $btnHideProviers = $('.btn-hide-providers');
    var $btnLogin = $('.btn-login');
    var $loginProviders = $('.login-providers');
    var $school = $('.school');
    var $systems = $('.system');
    var $modals = $('.modal');
    var $pwRecoveryModal = $('.pwrecovery-modal');
    var $modalForm = $('.modal-form');

    var loadSystems = function(schoolId) {
        $systems.empty();
        $.getJSON('/login/systems/' + schoolId, function(systems) {
            systems.forEach(function(system) {
                var systemAlias = system.alias ? ' (' + system.alias + ')' : '';
                let selected;
                if(localStorage.getItem('loginSystem') == system._id) {
                    selected = true;
                }
                $systems.append('<option ' + (selected ? 'selected': '') + ' value="' + system._id + '">' + system.type + systemAlias + '</option>');
            });
            $systems.trigger('chosen:updated');
        });
    };

    $btnToggleProviers.on('click', function(e) {
        e.preventDefault();
        $btnToggleProviers.hide();
        $loginProviders.show();
    });

    $btnHideProviers.on('click', function(e) {
        e.preventDefault();
        $btnToggleProviers.show();
        $loginProviders.hide();
        $school.val('');
        $school.trigger('chosen:updated');
        $systems.val('');
        $systems.trigger('chosen:updated');
    });

    $btnLogin.on('click', function(e) {
        localStorage.setItem('loginSchool', $school.val());
        localStorage.setItem('loginSystem', $systems.val());
    });

    $school.on('change', function() {
        const id = $(this).val();
        loadSystems( id );
        $school.find("option").not("[value='"+id+"']").removeAttr('selected');
        $school.find("option[value='"+id+"']").attr('selected',true);
        $school.trigger('chosen:updated');
    });

    $('.submit-pwrecovery').on('click', function(e) {
        e.preventDefault();
        populateModalForm($pwRecoveryModal, {
            title: 'Passwort Zurücksetzen',
            closeLabel: 'Abbrechen',
            submitLabel: 'Abschicken'
        });
        $pwRecoveryModal.appendTo('body').modal('show');
    });

    $modals.find('.close, .btn-close').on('click', function() {
        $modals.modal('hide');
    });

    // if stored login system - use that
    if(localStorage.getItem('loginSchool')) {
        $btnToggleProviers.hide();
        $loginProviders.show();
        $school.val(localStorage.getItem('loginSchool'));
        $school.trigger('chosen:updated');
        $school.trigger('change');
    }

});

window.startIntro = function startIntro() {
    introJs()
    .setOptions({
        nextLabel: "Weiter",
        prevLabel: "Zurück",
        doneLabel: "Nächste Seite",
        skipLabel: "Überspringen"
    })
    .start()
    .oncomplete(function() {
        localStorage.setItem('Tutorial', true);
        document.querySelector("#loginarea > div > div > form:nth-child(3) > div > input").click();
    })
}

if ('serviceWorker' in navigator){
    navigator.serviceWorker.getRegistrations().then(function(registrations) {
        for(let registration of registrations) {
            if(registration.active && registration.active.scriptURL.endsWith('/sw.js')){
                registration.unregister();
            }
        }
    });
}
<|endoftext|>