<commit_before>var Mode = require('./Mode');

function Teams() {
    Mode.apply(this, Array.prototype.slice.call(arguments));

    this.ID = 0;
    this.name = "Teams";
    this.decayMod = 1.5;
    this.packetLB = 50;
    this.haveTeams = true;
    this.colorFuzziness = 32;

    // Special
    this.teamAmount = 3; // Amount of teams. Having more than 3 teams will cause the leaderboard to work incorrectly (client issue).
    this.colors = [
        {'r': 223, 'g': 0, 'b': 0},
        {'r': 0, 'g': 223, 'b': 0},
        {'r': 0, 'g': 0, 'b': 223},
    ]; // Make sure you add extra colors here if you wish to increase the team amount [Default colors are: Red, Green, Blue]
    this.nodes = []; // Teams
}

module.exports = Teams;
Teams.prototype = new Mode();

//Gamemode Specific Functions

Teams.prototype.fuzzColorComponent = function(component) {
    component += Math.random() * this.colorFuzziness >> 0;
    return component;
};

Teams.prototype.getTeamColor = function(team) {
    var color = this.colors[team];
    return {
        r: this.fuzzColorComponent(color.r),
        b: this.fuzzColorComponent(color.b),
        g: this.fuzzColorComponent(color.g)
    };
};

// Override

Teams.prototype.onPlayerSpawn = function(gameServer,player) {
    // Random color based on team
    player.color = this.getTeamColor(player.team);
    // Spawn player
    gameServer.spawnPlayer(player);
};

Teams.prototype.onServerInit = function(gameServer) {
    // Set up teams
    for (var i = 0; i < this.teamAmount; i++) {
        this.nodes[i] = [];
    }
};

Teams.prototype.onPlayerInit = function(player) {
    // Get random team
    player.team = Math.floor(Math.random() * this.teamAmount);
};

Teams.prototype.onCellAdd = function(cell) {
    // Add to team list
    this.nodes[cell.owner.getTeam()].push(cell);
};

Teams.prototype.onCellRemove = function(cell) {
    // Remove from team list
    var index = this.nodes[cell.owner.getTeam()].indexOf(cell);
    if (index != -1) {
        this.nodes[cell.owner.getTeam()].splice(index, 1);
    }
};

Teams.prototype.onCellMove = function(x1,y1,cell) {
    var team = cell.owner.getTeam();
    var r = cell.getSize();

    // Find team
    for (var i = 0; i < cell.owner.visibleNodes.length;i++) {
        // Only collide with player cells
        var check = cell.owner.visibleNodes[i];

        if ((check.getType() != 0) || (cell.owner == check.owner)){
            continue;
        }

        // Collision with teammates
        if (check.owner.getTeam() == team) {
            // Check if in collision range
            var collisionDist = check.getSize() + r; // Minimum distance between the 2 cells
            if (cell.simpleCollide(check, collisionDist)) {
                // Skip
                continue;
            }

            // First collision check passed... now more precise checking
            dist = cell.getDist(cell.position.x,cell.position.y,check.position.x,check.position.y);

            // Calculations
            if (dist < collisionDist) { // Collided
                // The moving cell pushes the colliding cell
                var newDeltaY = check.position.y - y1;
                var newDeltaX = check.position.x - x1;
                var newAngle = Math.atan2(newDeltaX,newDeltaY);

                var move = collisionDist - dist;

                check.position.x = check.position.x + ( move * Math.sin(newAngle) ) >> 0;
                check.position.y = check.position.y + ( move * Math.cos(newAngle) ) >> 0;
            }
        }
    }
};

Teams.prototype.updateLB = function(gameServer) {
    var total = 0;
    var teamMass = [];
    // Get mass
    for (var i = 0; i < this.teamAmount; i++) {
        // Set starting mass
        teamMass[i] = 0;

        // Loop through cells
        for (var j = 0; j < this.nodes[i].length;j++) {
            var cell = this.nodes[i][j];

            if (!cell) {
                continue;
            }

            teamMass[i] += cell.mass;
            total += cell.mass;
        }
    }
    // Calc percentage
    for (var i = 0; i < this.teamAmount; i++) {
        // No players
        if (total <= 0) {
            continue;
        }

        gameServer.leaderboard[i] = teamMass[i]/total;
    }
};

<commit_msg>Fix crash with "boardreset" in Teams mode<commit_after>var Mode = require('./Mode');

function Teams() {
    Mode.apply(this, Array.prototype.slice.call(arguments));

    this.ID = 1;
    this.name = "Teams";
    this.decayMod = 1.5;
    this.packetLB = 50;
    this.haveTeams = true;
    this.colorFuzziness = 32;

    // Special
    this.teamAmount = 3; // Amount of teams. Having more than 3 teams will cause the leaderboard to work incorrectly (client issue).
    this.colors = [
        {'r': 223, 'g': 0, 'b': 0},
        {'r': 0, 'g': 223, 'b': 0},
        {'r': 0, 'g': 0, 'b': 223},
    ]; // Make sure you add extra colors here if you wish to increase the team amount [Default colors are: Red, Green, Blue]
    this.nodes = []; // Teams
}

module.exports = Teams;
Teams.prototype = new Mode();

//Gamemode Specific Functions

Teams.prototype.fuzzColorComponent = function(component) {
    component += Math.random() * this.colorFuzziness >> 0;
    return component;
};

Teams.prototype.getTeamColor = function(team) {
    var color = this.colors[team];
    return {
        r: this.fuzzColorComponent(color.r),
        b: this.fuzzColorComponent(color.b),
        g: this.fuzzColorComponent(color.g)
    };
};

// Override

Teams.prototype.onPlayerSpawn = function(gameServer,player) {
    // Random color based on team
    player.color = this.getTeamColor(player.team);
    // Spawn player
    gameServer.spawnPlayer(player);
};

Teams.prototype.onServerInit = function(gameServer) {
    // Set up teams
    for (var i = 0; i < this.teamAmount; i++) {
        this.nodes[i] = [];
    }
};

Teams.prototype.onPlayerInit = function(player) {
    // Get random team
    player.team = Math.floor(Math.random() * this.teamAmount);
};

Teams.prototype.onCellAdd = function(cell) {
    // Add to team list
    this.nodes[cell.owner.getTeam()].push(cell);
};

Teams.prototype.onCellRemove = function(cell) {
    // Remove from team list
    var index = this.nodes[cell.owner.getTeam()].indexOf(cell);
    if (index != -1) {
        this.nodes[cell.owner.getTeam()].splice(index, 1);
    }
};

Teams.prototype.onCellMove = function(x1,y1,cell) {
    var team = cell.owner.getTeam();
    var r = cell.getSize();

    // Find team
    for (var i = 0; i < cell.owner.visibleNodes.length;i++) {
        // Only collide with player cells
        var check = cell.owner.visibleNodes[i];

        if ((check.getType() != 0) || (cell.owner == check.owner)){
            continue;
        }

        // Collision with teammates
        if (check.owner.getTeam() == team) {
            // Check if in collision range
            var collisionDist = check.getSize() + r; // Minimum distance between the 2 cells
            if (cell.simpleCollide(check, collisionDist)) {
                // Skip
                continue;
            }

            // First collision check passed... now more precise checking
            dist = cell.getDist(cell.position.x,cell.position.y,check.position.x,check.position.y);

            // Calculations
            if (dist < collisionDist) { // Collided
                // The moving cell pushes the colliding cell
                var newDeltaY = check.position.y - y1;
                var newDeltaX = check.position.x - x1;
                var newAngle = Math.atan2(newDeltaX,newDeltaY);

                var move = collisionDist - dist;

                check.position.x = check.position.x + ( move * Math.sin(newAngle) ) >> 0;
                check.position.y = check.position.y + ( move * Math.cos(newAngle) ) >> 0;
            }
        }
    }
};

Teams.prototype.updateLB = function(gameServer) {
    var total = 0;
    var teamMass = [];
    // Get mass
    for (var i = 0; i < this.teamAmount; i++) {
        // Set starting mass
        teamMass[i] = 0;

        // Loop through cells
        for (var j = 0; j < this.nodes[i].length;j++) {
            var cell = this.nodes[i][j];

            if (!cell) {
                continue;
            }

            teamMass[i] += cell.mass;
            total += cell.mass;
        }
    }
    // Calc percentage
    for (var i = 0; i < this.teamAmount; i++) {
        // No players
        if (total <= 0) {
            continue;
        }

        gameServer.leaderboard[i] = teamMass[i]/total;
    }
};

<|endoftext|>


<commit_before>//
// GROUNDCREW VIEWER<->SERVER COMMUNICATIONS
//
// To communicate with the server, the viewer polls a file every 20s
// at http://[SERVER]/data/this10.js, which contains all events from
// the last few minutes.  The server returns javascript which calls a
// limited set of four functions: {item,event,city,idea}, defined at
// the bottom of this file.  These functions, when called, add or update
// entries in an in-browser, in-memory database which is used to draw
// them map and fill out the UI.
//

Ajax = {
  interval: 20 * 1000,
  timer: null,

  uuid: function() {
    return agent_tag + '_' + new Date().getTime();
  },

  init: function() {
    $("body").bind("ajaxSend", function(){
      clearTimeout(Ajax.timer);
      $(this).addClass('refresh');
    }).bind("ajaxComplete", function(){
      Ajax.schedule_autoload();
      $(this).removeClass('refresh');
    });

    $.ajaxSetup({
      error: function(req, textStatus, errorThrown){
        if (req.status == 404) return;
        if (errorThrown){ throw errorThrown;  }
        if (req.responseText) $.facebox(req.responseText);
      }
    });

    EventDb.new_events_are_new = true;
  },

  schedule_autoload: function(){
    if (Ajax.timer) clearTimeout(Ajax.timer);
    Ajax.timer = setTimeout(Ajax.autoload, Ajax.interval);
  },

  autoload: function(){
    $.getScript('/data/this10.js');
  },

  fetch: function(url, options, after){
    $.getJSON(url, options, function(obj){
      if (obj.error){ alert("Note: " + obj.error); return; }
      if (after) after(obj);
    });
  }

};

// item - an item on the map
function item(city_id, tag, title, thumb_url, lat, lng, atags, latch, comm, req, json_etc){
  var parts = tag.split('__');
  return Resource.add_or_update($.extend({
    id: Number(parts[1]),
    item_tag: tag,
    title: title,
    thumb_url: thumb_url,
    city_id: city_id,
    lat: lat,
    lng: lng,
    atags: atags,
    latch: latch,
    comm: comm,
    req: req
  }, json_etc));
}

var cities = {};
var city_locs = {};

// city - a city in which there is groundcrew activity
function city(id, title, lat, lng, agent_count){
  var parts = title.split(', ');
  cities[id] = parts[0];
  city_locs[id] = [lat, lng];
}

// idea - a template for a gathering
function idea(tag, title, atags, ltypes, json_etc){
  var parts = tag.split('__');
  Resource.add_or_update($.extend({
    id: Number(parts[1]),
    item_tag: tag,
    title: title,
    atags: atags
  }, json_etc));
}

EventDb = {};
EventDb.events = [];
EventDb.seen = {};
EventDb.new_events_are_new = false;

// event - anything that happened
function event(annc_tag, created_at, atype, actor_tag, re, atags, city_id, item_tag, item_changes, json_etc){

  if (EventDb.seen[annc_tag]) return;
  EventDb.seen[annc_tag] = true;

  var event = $.extend({
    annc_tag: annc_tag,
    item_tag: item_tag,
    created_at: created_at,
    atype: atype,
    actor_tag: actor_tag,
    re: re,
    atags: atags,
    city_id: city_id
  }, json_etc);

  // handle any item changes packed in this event
  if (item_tag && item_changes) {
    var item = item_tag.resource();
    $.extend(item, item_changes);
    Resource.add_or_update(item);
  };

  // add it to the list of all events
  EventDb.events.push(event);
  if (atype == 'said') Chat.chats.push(event);
  if (atype == 'off') Agents.remove(item_tag);

  if (EventDb.new_events_are_new){
    if (atype == 'said') Chat.update();
    Notifier.did_add_new_event(event);
  }
}

// login - called to specify the operator of the viewer
function login(user_info){
  agent_tag = user_info.tag;
  person_item = agent_tag.resource();
  $.extend(person_item, user_info);
  logged_in = true;
}
<commit_msg>event() now returns the event obj<commit_after>//
// GROUNDCREW VIEWER<->SERVER COMMUNICATIONS
//
// To communicate with the server, the viewer polls a file every 20s
// at http://[SERVER]/data/this10.js, which contains all events from
// the last few minutes.  The server returns javascript which calls a
// limited set of four functions: {item,event,city,idea}, defined at
// the bottom of this file.  These functions, when called, add or update
// entries in an in-browser, in-memory database which is used to draw
// them map and fill out the UI.
//

Ajax = {
  interval: 20 * 1000,
  timer: null,

  uuid: function() {
    return agent_tag + '_' + new Date().getTime();
  },

  init: function() {
    $("body").bind("ajaxSend", function(){
      clearTimeout(Ajax.timer);
      $(this).addClass('refresh');
    }).bind("ajaxComplete", function(){
      Ajax.schedule_autoload();
      $(this).removeClass('refresh');
    });

    $.ajaxSetup({
      error: function(req, textStatus, errorThrown){
        if (req.status == 404) return;
        if (errorThrown){ throw errorThrown;  }
        if (req.responseText) $.facebox(req.responseText);
      }
    });

    EventDb.new_events_are_new = true;
  },

  schedule_autoload: function(){
    if (Ajax.timer) clearTimeout(Ajax.timer);
    Ajax.timer = setTimeout(Ajax.autoload, Ajax.interval);
  },

  autoload: function(){
    $.getScript('/data/this10.js');
  },

  fetch: function(url, options, after){
    $.getJSON(url, options, function(obj){
      if (obj.error){ alert("Note: " + obj.error); return; }
      if (after) after(obj);
    });
  }

};

// item - an item on the map
function item(city_id, tag, title, thumb_url, lat, lng, atags, latch, comm, req, json_etc){
  var parts = tag.split('__');
  return Resource.add_or_update($.extend({
    id: Number(parts[1]),
    item_tag: tag,
    title: title,
    thumb_url: thumb_url,
    city_id: city_id,
    lat: lat,
    lng: lng,
    atags: atags,
    latch: latch,
    comm: comm,
    req: req
  }, json_etc));
}

var cities = {};
var city_locs = {};

// city - a city in which there is groundcrew activity
function city(id, title, lat, lng, agent_count){
  var parts = title.split(', ');
  cities[id] = parts[0];
  city_locs[id] = [lat, lng];
}

// idea - a template for a gathering
function idea(tag, title, atags, ltypes, json_etc){
  var parts = tag.split('__');
  Resource.add_or_update($.extend({
    id: Number(parts[1]),
    item_tag: tag,
    title: title,
    atags: atags
  }, json_etc));
}

EventDb = {};
EventDb.events = [];
EventDb.seen = {};
EventDb.new_events_are_new = false;

// event - anything that happened
function event(annc_tag, created_at, atype, actor_tag, re, atags, city_id, item_tag, item_changes, json_etc){

  if (EventDb.seen[annc_tag]) return;
  EventDb.seen[annc_tag] = true;

  var event = $.extend({
    annc_tag: annc_tag,
    item_tag: item_tag,
    created_at: created_at,
    atype: atype,
    actor_tag: actor_tag,
    re: re,
    atags: atags,
    city_id: city_id
  }, json_etc);

  // handle any item changes packed in this event
  if (item_tag && item_changes) {
    var item = item_tag.resource();
    $.extend(item, item_changes);
    Resource.add_or_update(item);
  };

  // add it to the list of all events
  EventDb.events.push(event);
  if (atype == 'said') Chat.chats.push(event);
  if (atype == 'off') Agents.remove(item_tag);
  if (EventDb.new_events_are_new){
    if (atype == 'said') Chat.update();
    Notifier.did_add_new_event(event);
  }

  return event;
}

// login - called to specify the operator of the viewer
function login(user_info){
  agent_tag = user_info.tag;
  person_item = agent_tag.resource();
  $.extend(person_item, user_info);
  logged_in = true;
}
<|endoftext|>


<commit_before>//
// GROUNDCREW VIEWER<->SERVER COMMUNICATIONS
//
// To communicate with the server, the viewer polls a file every 20s
// at http://[SERVER]/data/this10.js, which contains all events from
// the last few minutes.  The server returns javascript which calls a
// limited set of four functions: {item,event,city,idea}, defined at
// the bottom of this file.  These functions, when called, add or update
// entries in an in-browser, in-memory database which is used to draw
// them map and fill out the UI.
//

Ajax = {
  interval: 20 * 1000,
  timer: null,

  uuid: function() {
    return agent_tag + '_' + new Date().getTime();
  },

  init: function() {
    $("body").bind("ajaxSend", function(){
      clearTimeout(Ajax.timer);
      $(this).addClass('refresh');
    }).bind("ajaxComplete", function(){
      Ajax.schedule_autoload();
      $(this).removeClass('refresh');
    });

    $.ajaxSetup({
      error: function(req, textStatus, errorThrown){
        if (req.status == 404) return;
        if (errorThrown){ throw errorThrown;  }
        if (req.responseText) $.facebox(req.responseText);
      }
    });

    EventDb.new_events_are_new = true;
  },

  schedule_autoload: function(){
    if (Ajax.timer) clearTimeout(Ajax.timer);
    Ajax.timer = setTimeout(Ajax.autoload, Ajax.interval);
  },

  autoload: function(){
    $.getScript('/data/this10.js');
  },

  fetch: function(url, options, after){
    $.getJSON(url, options, function(obj){
      if (obj.error){ alert("Note: " + obj.error); return; }
      if (after) after(obj);
    });
  }

};

// item - an item on the map
function item(city_id, tag, title, thumb_url, lat, lng, atags, latch, comm, req, json_etc){
  var parts = tag.split('__');
  return Resource.add_or_update($.extend({
    id: Number(parts[1]),
    item_tag: tag,
    title: title,
    thumb_url: thumb_url,
    city_id: city_id,
    lat: lat,
    lng: lng,
    atags: atags,
    latch: latch,
    comm: comm,
    req: req
  }, json_etc));
}

var cities = {};
var city_locs = {};

// city - a city in which there is groundcrew activity
function city(id, title, lat, lng, agent_count){
  var parts = title.split(', ');
  cities[id] = parts[0];
  city_locs[id] = [lat, lng];
}

// idea - a template for a gathering
function idea(tag, title, atags, ltypes, json_etc){
  var parts = tag.split('__');
  Resource.add_or_update($.extend({
    id: Number(parts[1]),
    item_tag: tag,
    title: title,
    atags: atags
  }, json_etc));
}

EventDb = {};
EventDb.events = [];
EventDb.seen = {};
EventDb.new_events_are_new = false;

// event - anything that happened
function event(annc_tag, created_at, atype, actor_tag, re, atags, city_id, item_tag, item_changes, json_etc){

  if (EventDb.seen[annc_tag]) return;
  EventDb.seen[annc_tag] = true;

  var event = $.extend({
    annc_tag: annc_tag,
    item_tag: item_tag,
    created_at: created_at,
    atype: atype,
    actor_tag: actor_tag,
    re: re,
    atags: atags,
    city_id: city_id
  }, json_etc);

  // handle any item changes packed in this event
  if (item_tag && item_changes) {
    var item = item_tag.resource();
    $.extend(item, item_changes);
    Resource.add_or_update(item);
  };

  // add it to the list of all events
  EventDb.events.push(event);
  if (atype == 'said') Chat.chats.push(event);
  if (atype == 'off') Agents.remove(item_tag);

  if (EventDb.new_events_are_new){
    if (atype == 'said') Chat.update();
    Notifier.did_add_new_event(event);
  }
}

// login - called to specify the operator of the viewer
function login(user_info){
  agent_tag = user_info.tag;
  person_item = agent_tag.resource();
  $.extend(person_item, user_info);
  logged_in = true;
}
<commit_msg>schedule autoload at the end of Ajax class.<commit_after>//
// GROUNDCREW VIEWER<->SERVER COMMUNICATIONS
//
// To communicate with the server, the viewer polls a file every 20s
// at http://[SERVER]/data/this10.js, which contains all events from
// the last few minutes.  The server returns javascript which calls a
// limited set of four functions: {item,event,city,idea}, defined at
// the bottom of this file.  These functions, when called, add or update
// entries in an in-browser, in-memory database which is used to draw
// them map and fill out the UI.
//

Ajax = {
  interval: 20 * 1000,
  timer: null,

  uuid: function() {
    return agent_tag + '_' + new Date().getTime();
  },

  init: function() {
    $("body").bind("ajaxSend", function(){
      clearTimeout(Ajax.timer);
      $(this).addClass('refresh');
    }).bind("ajaxComplete", function(){
      Ajax.schedule_autoload();
      $(this).removeClass('refresh');
    });

    $.ajaxSetup({
      error: function(req, textStatus, errorThrown){
        if (req.status == 404) return;
        if (errorThrown){ throw errorThrown;  }
        if (req.responseText) $.facebox(req.responseText);
      }
    });

    EventDb.new_events_are_new = true;
    Ajax.schedule_autoload();
  },

  schedule_autoload: function(){
    if (Ajax.timer) clearTimeout(Ajax.timer);
    Ajax.timer = setTimeout(Ajax.autoload, Ajax.interval);
  },

  autoload: function(){
    $.getScript('/data/this10.js');
  },

  fetch: function(url, options, after){
    $.getJSON(url, options, function(obj){
      if (obj.error){ alert("Note: " + obj.error); return; }
      if (after) after(obj);
    });
  }

};

// item - an item on the map
function item(city_id, tag, title, thumb_url, lat, lng, atags, latch, comm, req, json_etc){
  var parts = tag.split('__');
  return Resource.add_or_update($.extend({
    id: Number(parts[1]),
    item_tag: tag,
    title: title,
    thumb_url: thumb_url,
    city_id: city_id,
    lat: lat,
    lng: lng,
    atags: atags,
    latch: latch,
    comm: comm,
    req: req
  }, json_etc));
}

var cities = {};
var city_locs = {};

// city - a city in which there is groundcrew activity
function city(id, title, lat, lng, agent_count){
  var parts = title.split(', ');
  cities[id] = parts[0];
  city_locs[id] = [lat, lng];
}

// idea - a template for a gathering
function idea(tag, title, atags, ltypes, json_etc){
  var parts = tag.split('__');
  Resource.add_or_update($.extend({
    id: Number(parts[1]),
    item_tag: tag,
    title: title,
    atags: atags
  }, json_etc));
}

EventDb = {};
EventDb.events = [];
EventDb.seen = {};
EventDb.new_events_are_new = false;

// event - anything that happened
function event(annc_tag, created_at, atype, actor_tag, re, atags, city_id, item_tag, item_changes, json_etc){

  if (EventDb.seen[annc_tag]) return;
  EventDb.seen[annc_tag] = true;

  var event = $.extend({
    annc_tag: annc_tag,
    item_tag: item_tag,
    created_at: created_at,
    atype: atype,
    actor_tag: actor_tag,
    re: re,
    atags: atags,
    city_id: city_id
  }, json_etc);

  // handle any item changes packed in this event
  if (item_tag && item_changes) {
    var item = item_tag.resource();
    $.extend(item, item_changes);
    Resource.add_or_update(item);
  };

  // add it to the list of all events
  EventDb.events.push(event);
  if (atype == 'said') Chat.chats.push(event);
  if (atype == 'off') Agents.remove(item_tag);

  if (EventDb.new_events_are_new){
    if (atype == 'said') Chat.update();
    Notifier.did_add_new_event(event);
  }
}

// login - called to specify the operator of the viewer
function login(user_info){
  agent_tag = user_info.tag;
  person_item = agent_tag.resource();
  $.extend(person_item, user_info);
  logged_in = true;
}
<|endoftext|>


<commit_before>function GeoSearchResultsController($scope, $location, $routeParams, $http, $sce, chronontologySettings, $filter) {

    var _this = this;
    var popupinfo = [];

    _this.loading = false;
    _this.empty = false;

    this.$onChanges = function() {
        this.initMap();
        this.loadData();
    };

    this.loadData = function() {
        _this.loading = true;
        _this.empty = true;
        $http.get(_this.datasource, {
                headers: { 'Authorization': undefined }
        }).then(function success(geojson){
            _this.loading = false;
            _this.geojson = geojson.data;
            if (geojson.data.features.length > 0) {
                _this.empty = false;
                _this.initPlaces(geojson.data);
            } else {
                _this.empty = true;
            }
        }, function error(err) {
            console.warn(err) // TODO show error message
        });
    };

    this.initMap = function() {
        // init map
        _this.mapY = 50.1287762;
        _this.mapX = -5.4532871;
        _this.markersArea = 0;
        _this.mapZoom = 8;
        _this.baseLayer = L.tileLayer('http://{s}.tiles.mapbox.com/v3/isawnyu.map-knmctlkh/{z}/{x}/{y}.png', {
            maxZoom: 15,
            attribution: "Attribution"
        });
        _this.map = L.map("map3", {
            fullscreenControl: {pseudoFullscreen: false},
            center: [_this.mapY, _this.mapX],
            zoom: _this.mapZoom,
            layers: [_this.baseLayer]
        });
        // add scale
        L.control.scale().addTo(_this.map);
    };

    this.initPlaces = function(geojson) {

        // cluster
        _this.markers = null;
		_this.markers = L.markerClusterGroup();

        // add markers and polygons
        _this.orangeBowlIcon = L.icon({iconUrl: 'img/Icone_Boule_Orange.png', iconSize: [30, 30], iconAnchor: [15, 15]}),
        _this.marker = L.geoJson(geojson, {
          onEachFeature: _this.onEachFeature,
          pointToLayer: function (feature, latlng) {
              return L.marker(latlng, {icon: _this.orangeBowlIcon});
            }
        });
        _this.markers.addLayer(_this.marker);
        // add marker as layer
        _this.map.addLayer(_this.markers);
        // calc layer center
        _this.mapY = _this.marker.getBounds().getCenter().lat;
        _this.mapX = _this.marker.getBounds().getCenter().lng;
        // set map
        _this.map.setView([_this.mapY, _this.mapX], _this.mapZoom);
        // zoom to bounds
        _this.map.fitBounds(_this.marker.getBounds());

        if (_this.map.tap) _this.map.tap.enable();
        document.getElementById('map3').style.cursor='grab';
    }

    this.onEachFeature = function(feature, layer) {
        var popupContent = "name: " + feature.properties.names.prefName.name + "
" + "uri: " + feature.properties["@id"] + "";
		if (feature.properties && feature.properties.popupContent) {
			popupContent += feature.properties.popupContent;
		}
		layer.bindPopup(popupContent);
    };

}

angular.module('chronontology.components')
    .component('geosearchresults',{
        templateUrl: '../../partials/geo/searchResults.html',
        bindings: {
            datasource: '@datasource'
        },
        controller: GeoSearchResultsController
    });
<commit_msg>add search to GeoSearchResultsController<commit_after>function GeoSearchResultsController($scope, $location, $routeParams, $http, $sce, chronontologySettings, $filter) {

    var _this = this;
    var popupinfo = [];

    _this.loading = false;
    _this.empty = false;

    this.$onChanges = function() {
        this.initMap();
        this.loadData();
    };

    this.loadData = function() {
        _this.loading = true;
        _this.empty = true;
        $http.get(_this.datasource, {
                headers: { 'Authorization': undefined }
        }).then(function success(geojson){
            _this.loading = false;
            _this.geojson = geojson.data;
            if (geojson.data.features.length > 0) {
                _this.empty = false;
                _this.initPlaces(geojson.data);
            } else {
                _this.empty = true;
            }
        }, function error(err) {
            console.warn(err) // TODO show error message
        });
    };

    this.initMap = function() {
        // init map
        _this.mapY = 50.1287762;
        _this.mapX = -5.4532871;
        _this.markersArea = 0;
        _this.mapZoom = 8;
        _this.baseLayer = L.tileLayer('http://{s}.tiles.mapbox.com/v3/isawnyu.map-knmctlkh/{z}/{x}/{y}.png', {
            maxZoom: 15,
            attribution: "Attribution"
        });
        _this.map = L.map("map3", {
            fullscreenControl: {pseudoFullscreen: false},
            center: [_this.mapY, _this.mapX],
            zoom: _this.mapZoom,
            layers: [_this.baseLayer]
        });
        // add scale
        L.control.scale().addTo(_this.map);
    };

    this.initPlaces = function(geojson) {

        // cluster
        _this.markers = null;
		_this.markers = L.markerClusterGroup();

        // add markers and polygons
        _this.orangeBowlIcon = L.icon({iconUrl: 'img/Icone_Boule_Orange.png', iconSize: [30, 30], iconAnchor: [15, 15]}),
        _this.marker = L.geoJson(geojson, {
          onEachFeature: _this.onEachFeature,
          pointToLayer: function (feature, latlng) {
              return L.marker(latlng, {icon: _this.orangeBowlIcon, name: feature.properties.names.prefName.name});
            }
        });
        _this.markers.addLayer(_this.marker);
        // add marker as layer
        _this.map.addLayer(_this.markers);
        // init search
        _this.controlSearch = new L.Control.Search({
    		position:'topleft',
    		layer: _this.markers,
            initial: false,
            propertyName: 'name',
    		marker: false,
            zoom: 13
    	});
        _this.controlSearch.on('search:locationfound', function(e) {
    		e.layer.openPopup();
    	});
        _this.map.addControl(_this.controlSearch);
        // calc layer center
        _this.mapY = _this.marker.getBounds().getCenter().lat;
        _this.mapX = _this.marker.getBounds().getCenter().lng;
        // set map
        _this.map.setView([_this.mapY, _this.mapX], _this.mapZoom);
        // zoom to bounds
        _this.map.fitBounds(_this.marker.getBounds());

        if (_this.map.tap) _this.map.tap.enable();
        document.getElementById('map3').style.cursor='grab';
    }

    this.onEachFeature = function(feature, layer) {
        var popupContent = "name: " + feature.properties.names.prefName.name + "
" + "uri: " + feature.properties["@id"] + "";
		if (feature.properties && feature.properties.popupContent) {
			popupContent += feature.properties.popupContent;
		}
		layer.bindPopup(popupContent);
    };

}

angular.module('chronontology.components')
    .component('geosearchresults',{
        templateUrl: '../../partials/geo/searchResults.html',
        bindings: {
            datasource: '@datasource'
        },
        controller: GeoSearchResultsController
    });
<|endoftext|>


<commit_before>/**
* @license
* Copyright 2018 Google LLC. All Rights Reserved.
*
* 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.
* ==============================================================================
*/

// This tiny example illustrates how little code is necessary build /
// train / predict from a model in TensorFlow.js.  Edit this code
// and refresh the index.html to quickly explore the API.

// Tiny TFJS train / predict example.
async function myFirstTfjs() {
  // Create a simple model.
  const model = tf.sequential();
  model.add(tf.layers.dense({units: 1, inputShape: [1]}));
  // Prepare the model for training: Specify the loss and the optimizer.
  model.compile({loss: 'meanSquaredError',
                 optimizer: 'sgd',
                 useBias: 'true'});
  // Generate some synthetic data for training. (y = 2x - 1)
  const xs = tf.tensor2d([-1, 0, 1, 2, 3, 4], [6, 1]);
  const ys = tf.tensor2d([-3, -1, 1, 3, 5, 7], [6, 1]);
  // Train the model using the data.
  await model.fit(xs, ys, {epochs: 250});
  // Use the model to do inference on a data point the model hasn't seen.
  // Perform within a tf.tidy block to perform cleanup on intermediate tensors.
  tf.tidy(() => {
    // Should print approximately 39.
    document.getElementById('micro_out_div').innerText += model.predict(
        tf.tensor2d([20], [1, 1]));
  });
  // Manually clean up the memory for these variables.
  xs.dispose();
  ys.dispose();
}

myFirstTfjs();
<commit_msg>Remove 'usBias' from model.fit in the getting_started example. (#57)<commit_after>/**
* @license
* Copyright 2018 Google LLC. All Rights Reserved.
*
* 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.
* ==============================================================================
*/

// This tiny example illustrates how little code is necessary build /
// train / predict from a model in TensorFlow.js.  Edit this code
// and refresh the index.html to quickly explore the API.

// Tiny TFJS train / predict example.
async function myFirstTfjs() {
  // Create a simple model.
  const model = tf.sequential();
  model.add(tf.layers.dense({units: 1, inputShape: [1]}));

  // Prepare the model for training: Specify the loss and the optimizer.
  model.compile({
    loss: 'meanSquaredError',
    optimizer: 'sgd'
  });

  // Generate some synthetic data for training. (y = 2x - 1)
  const xs = tf.tensor2d([-1, 0, 1, 2, 3, 4], [6, 1]);
  const ys = tf.tensor2d([-3, -1, 1, 3, 5, 7], [6, 1]);

  // Train the model using the data.
  await model.fit(xs, ys, {epochs: 250});

  // Use the model to do inference on a data point the model hasn't seen.
  // Should print approximately 39.
  document.getElementById('micro_out_div').innerText +=
      model.predict(tf.tensor2d([20], [1, 1]));
}

myFirstTfjs();
<|endoftext|>


<commit_before>/* global ArangoServerState */
'use strict';

// //////////////////////////////////////////////////////////////////////////////
// / @brief Replication management
// /
// / @file
// /
// / DISCLAIMER
// /
// / Copyright 2012 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 Jan Steemann
// / @author Copyright 2013, triAGENS GmbH, Cologne, Germany
// //////////////////////////////////////////////////////////////////////////////

var internal = require('internal');
var ERRORS = internal.errors;
var endpointToURL = require('@arangodb/cluster').endpointToURL;
var request;
if (ArangoServerState.role() === 'PRIMARY') {
  request = require('@arangodb/request').clusterRequest;
} else {
  request = require('@arangodb/request').request;
}

var logger = { };
var applier = { };

// //////////////////////////////////////////////////////////////////////////////
// / @brief return the replication logger state
// //////////////////////////////////////////////////////////////////////////////

logger.state = function () {
  return internal.getStateReplicationLogger();
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief return the tick ranges provided by the replication logger
// //////////////////////////////////////////////////////////////////////////////

logger.tickRanges = function () {
  return internal.tickRangesReplicationLogger();
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief return the first tick that can be provided by the replication logger
// //////////////////////////////////////////////////////////////////////////////

logger.firstTick = function () {
  return internal.firstTickReplicationLogger();
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief starts the replication applier
// //////////////////////////////////////////////////////////////////////////////

applier.start = function (initialTick, barrierId) {
  if (initialTick === undefined) {
    return internal.startReplicationApplier();
  }

  return internal.startReplicationApplier(initialTick, barrierId);
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief shuts down the replication applier
// //////////////////////////////////////////////////////////////////////////////

applier.shutdown = applier.stop = function () {
  return internal.shutdownReplicationApplier();
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief return the replication applier state
// //////////////////////////////////////////////////////////////////////////////

applier.state = function () {
  return internal.getStateReplicationApplier();
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief stop the applier and "forget" all configuration
// //////////////////////////////////////////////////////////////////////////////

applier.forget = function () {
  return internal.forgetStateReplicationApplier();
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief returns the configuration of the replication applier
// //////////////////////////////////////////////////////////////////////////////

applier.properties = function (config) {
  if (config === undefined) {
    return internal.configureReplicationApplier();
  }

  return internal.configureReplicationApplier(config);
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief performs a one-time synchronization with a remote endpoint
// //////////////////////////////////////////////////////////////////////////////

function sync (config) {
  return internal.synchronizeReplication(config);
}

// //////////////////////////////////////////////////////////////////////////////
// / @brief performs a one-time synchronization with a remote endpoint
// //////////////////////////////////////////////////////////////////////////////

function syncCollection (collection, config) {
  config = config || { };
  config.restrictType = 'include';
  config.restrictCollections = [ collection ];
  config.includeSystem = true;
  if (!config.hasOwnProperty('verbose')) {
    config.verbose = false;
  }

  return internal.synchronizeReplication(config);
}

// //////////////////////////////////////////////////////////////////////////////
// / @brief sets up the replication (all-in-one function for initial
// / synchronization and continuous replication)
// //////////////////////////////////////////////////////////////////////////////

function setupReplication (config) {
  config = config || { };
  if (!config.hasOwnProperty('autoStart')) {
    config.autoStart = true;
  }
  if (!config.hasOwnProperty('includeSystem')) {
    config.includeSystem = true;
  }
  if (!config.hasOwnProperty('verbose')) {
    config.verbose = false;
  }
  config.keepBarrier = true;

  try {
    // stop previous instance
    applier.stop();
  } catch (err) {}
  // remove existing configuration
  applier.forget();

  // run initial sync
  var result = internal.synchronizeReplication(config);

  // store applier configuration
  applier.properties(config);

  applier.start(result.lastLogTick, result.barrierId);
  return applier.state();
}

// //////////////////////////////////////////////////////////////////////////////
// / @brief returns the server's id
// //////////////////////////////////////////////////////////////////////////////

function serverId () {
  return internal.serverId();
}

// //////////////////////////////////////////////////////////////////////////////
// / @brief finishes off a synchronization of a single collection
// / `collection` is the name of a collection on the other server that should
// / have been synchronized using syncCollection (incremental or not)
// / recently. `from` is the tick as a string of that synchronization.
// / `config` can contain the following attributes:
// /   - "endpoint": endpoint of the other server
// / If one ensures that there is a read transaction ongoing on that collection
// / on the other server, then this function is guaranteed to bring the two
// / collections in perfect sync, until that read transaction is aborted.
// //////////////////////////////////////////////////////////////////////////////

var mType = {
  REPLICATION_COLLECTION_CREATE: 2000,
  REPLICATION_COLLECTION_DROP: 2001,
  REPLICATION_COLLECTION_RENAME: 2002,
  REPLICATION_COLLECTION_CHANGE: 2003,

  REPLICATION_INDEX_CREATE: 2100,
  REPLICATION_INDEX_DROP: 2101,

  REPLICATION_TRANSACTION_START: 2200,
  REPLICATION_TRANSACTION_COMMIT: 2201,
  REPLICATION_TRANSACTION_ABORT: 2202,

  REPLICATION_MARKER_DOCUMENT: 2300,
  REPLICATION_MARKER_EDGE: 2301,
  REPLICATION_MARKER_REMOVE: 2302
};

function syncCollectionFinalize (database, collname, from, config) {
  var url = endpointToURL(config.endpoint) + '/_db/' + database +
    '/_api/replication/logger-follow?collection=' + collname + '&from=';

  var coll = require('internal').db[collname];

  var transactions = {};

  function apply (entry) {
    var todo;

    function tryPostpone (entry) {
      if (entry.tid !== '0') {
        todo = transactions[entry.tid];
        if (Array.isArray(todo)) {
          entry.tid = '0';
          todo.push(entry);
          return true;
        }
      }
      return false;
    }

    if (entry.type === mType.REPLICATION_MARKER_DOCUMENT) {
      if (tryPostpone(entry)) {
        return;
      }
      try {
        coll.insert(entry.data, {isRestore: true});
        return;
      } catch (err) {
        console.debug('syncCollectionFinalize: insert1', entry, JSON.stringify(err));
      }
      try {
        coll.replace(entry.data._key, entry.data, {isRestore: true});
      } catch (errx) {
        console.error('syncCollectionFinalize: replace1', entry, JSON.stringify(errx));
        throw errx;
      }
    } else if (entry.type === mType.REPLICATION_MARKER_EDGE) {
      if (tryPostpone(entry)) {
        return;
      }
      try {
        coll.insert(entry.data, {isRestore: true});
        return;
      } catch (err) {
        console.debug('syncCollectionFinalize: insert2', entry, JSON.stringify(err));
      }
      try {
        coll.replace(entry.data._key, entry.data, {isRestore: true});
      } catch (errx) {
        console.error('syncCollectionFinalize: replace2', entry, JSON.stringify(errx));
        throw errx;
      }
    } else if (entry.type === mType.REPLICATION_MARKER_REMOVE) {
      if (tryPostpone(entry)) {
        return;
      }
      try {
        coll.remove(entry.data._key);
      } catch (errx) {
        console.error('syncCollectionFinalize: remove', entry, JSON.stringify(errx));
        if (errx.errorNum !== ERRORS.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code) {
          throw errx;
        }
        // We swallow the NOT FOUND error here. It is possible that
        // a follower tries to synchronize to a leader with whom it
        // is already in sync. In that case there could have been a
        // synchronously replicated removal operation that has happened
        // whilst we were resynchronizing the shard. In this case, the
        // removal would have happened already.
      }
    } else if (entry.type === mType.REPLICATION_TRANSACTION_START) {
      transactions[entry.tid] = [];
    } else if (entry.type === mType.REPLICATION_TRANSACTION_COMMIT) {
      todo = transactions[entry.tid];
      if (Array.isArray(todo)) {
        for (var i = 0; i < todo.length; i++) {
          apply(todo[i]);
        }
      }
      delete transactions[entry.tid];
    } else if (entry.type === mType.REPLICATION_TRANSACTION_ABORT) {
      delete transactions[entry.tid];
    } else if (entry.type === mType.REPLICATION_INDEX_CREATE) {
      try {
        coll.ensureIndex(entry.data);
      } catch(errx) {
        console.error('syncCollectionFinalize: ensureIndex', entry, JSON.stringify(errx));
        throw errx;
      }
    } else if (entry.type === mType.REPLICATION_INDEX_DROP) {
      try {
        coll.dropIndex(entry.data.id);
      } catch(errx) {
        console.error('syncCollectionFinalize: dropIndex', entry, JSON.stringify(errx));
        throw errx;
      }
    } else if (entry.type === mType.REPLICATION_COLLECTION_CHANGE) {
      try {
        coll.properties(entry.data);
      } catch(errx) {
        console.error('syncCollectionFinalize: properties', entry, JSON.stringify(errx));
        throw errx;
      }
    } else {
      // all else, including dropping and creating the collection
      throw 'Found collection drop, create or rename marker.';
    }
  }

  while (true) {
    var chunk = request(url + from);
    if (chunk.statusCode !== 200 &&
      chunk.statusCode !== 204) {
      return {error: true, errorMessage: 'could not contact leader',
      response: chunk};
    }
    if (chunk.statusCode === 204 || chunk.body.length === 0) {
      break; // all done
    }

    var l = chunk.body.split('\n');
    l.pop();
    try {
      l = l.map(JSON.parse);
    } catch (err) {
      return {error: true, errorMessage: 'could not parse body',
              response: chunk, exception: err};
    }

    console.debug('Applying chunk:', l);
    try {
      for (var i = 0; i < l.length; i++) {
        apply(l[i]);
      }
    } catch (err2) {
      return {error: true, errorMessage: 'could not replicate body ops',
              response: chunk, exception: err2};
    }
    if (chunk.headers['x-arango-replication-checkmore'] !== 'true') {
      break; // all done
    }

    from = chunk.headers['x-arango-replication-lastincluded'];
  }
  return {error: false};
}

exports.logger = logger;
exports.applier = applier;
exports.sync = sync;
exports.syncCollection = syncCollection;
exports.setupReplication = setupReplication;
exports.serverId = serverId;
exports.syncCollectionFinalize = syncCollectionFinalize;
<commit_msg>Ignore collection markers in logger-follow output for syncCollectionFinalize.<commit_after>/* global ArangoServerState */
'use strict';

// //////////////////////////////////////////////////////////////////////////////
// / @brief Replication management
// /
// / @file
// /
// / DISCLAIMER
// /
// / Copyright 2012 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 Jan Steemann
// / @author Copyright 2013, triAGENS GmbH, Cologne, Germany
// //////////////////////////////////////////////////////////////////////////////

var internal = require('internal');
var ERRORS = internal.errors;
var endpointToURL = require('@arangodb/cluster').endpointToURL;
var request;
if (ArangoServerState.role() === 'PRIMARY') {
  request = require('@arangodb/request').clusterRequest;
} else {
  request = require('@arangodb/request').request;
}

var logger = { };
var applier = { };

// //////////////////////////////////////////////////////////////////////////////
// / @brief return the replication logger state
// //////////////////////////////////////////////////////////////////////////////

logger.state = function () {
  return internal.getStateReplicationLogger();
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief return the tick ranges provided by the replication logger
// //////////////////////////////////////////////////////////////////////////////

logger.tickRanges = function () {
  return internal.tickRangesReplicationLogger();
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief return the first tick that can be provided by the replication logger
// //////////////////////////////////////////////////////////////////////////////

logger.firstTick = function () {
  return internal.firstTickReplicationLogger();
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief starts the replication applier
// //////////////////////////////////////////////////////////////////////////////

applier.start = function (initialTick, barrierId) {
  if (initialTick === undefined) {
    return internal.startReplicationApplier();
  }

  return internal.startReplicationApplier(initialTick, barrierId);
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief shuts down the replication applier
// //////////////////////////////////////////////////////////////////////////////

applier.shutdown = applier.stop = function () {
  return internal.shutdownReplicationApplier();
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief return the replication applier state
// //////////////////////////////////////////////////////////////////////////////

applier.state = function () {
  return internal.getStateReplicationApplier();
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief stop the applier and "forget" all configuration
// //////////////////////////////////////////////////////////////////////////////

applier.forget = function () {
  return internal.forgetStateReplicationApplier();
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief returns the configuration of the replication applier
// //////////////////////////////////////////////////////////////////////////////

applier.properties = function (config) {
  if (config === undefined) {
    return internal.configureReplicationApplier();
  }

  return internal.configureReplicationApplier(config);
};

// //////////////////////////////////////////////////////////////////////////////
// / @brief performs a one-time synchronization with a remote endpoint
// //////////////////////////////////////////////////////////////////////////////

function sync (config) {
  return internal.synchronizeReplication(config);
}

// //////////////////////////////////////////////////////////////////////////////
// / @brief performs a one-time synchronization with a remote endpoint
// //////////////////////////////////////////////////////////////////////////////

function syncCollection (collection, config) {
  config = config || { };
  config.restrictType = 'include';
  config.restrictCollections = [ collection ];
  config.includeSystem = true;
  if (!config.hasOwnProperty('verbose')) {
    config.verbose = false;
  }

  return internal.synchronizeReplication(config);
}

// //////////////////////////////////////////////////////////////////////////////
// / @brief sets up the replication (all-in-one function for initial
// / synchronization and continuous replication)
// //////////////////////////////////////////////////////////////////////////////

function setupReplication (config) {
  config = config || { };
  if (!config.hasOwnProperty('autoStart')) {
    config.autoStart = true;
  }
  if (!config.hasOwnProperty('includeSystem')) {
    config.includeSystem = true;
  }
  if (!config.hasOwnProperty('verbose')) {
    config.verbose = false;
  }
  config.keepBarrier = true;

  try {
    // stop previous instance
    applier.stop();
  } catch (err) {}
  // remove existing configuration
  applier.forget();

  // run initial sync
  var result = internal.synchronizeReplication(config);

  // store applier configuration
  applier.properties(config);

  applier.start(result.lastLogTick, result.barrierId);
  return applier.state();
}

// //////////////////////////////////////////////////////////////////////////////
// / @brief returns the server's id
// //////////////////////////////////////////////////////////////////////////////

function serverId () {
  return internal.serverId();
}

// //////////////////////////////////////////////////////////////////////////////
// / @brief finishes off a synchronization of a single collection
// / `collection` is the name of a collection on the other server that should
// / have been synchronized using syncCollection (incremental or not)
// / recently. `from` is the tick as a string of that synchronization.
// / `config` can contain the following attributes:
// /   - "endpoint": endpoint of the other server
// / If one ensures that there is a read transaction ongoing on that collection
// / on the other server, then this function is guaranteed to bring the two
// / collections in perfect sync, until that read transaction is aborted.
// //////////////////////////////////////////////////////////////////////////////

var mType = {
  REPLICATION_COLLECTION_CREATE: 2000,
  REPLICATION_COLLECTION_DROP: 2001,
  REPLICATION_COLLECTION_RENAME: 2002,
  REPLICATION_COLLECTION_CHANGE: 2003,

  REPLICATION_INDEX_CREATE: 2100,
  REPLICATION_INDEX_DROP: 2101,

  REPLICATION_TRANSACTION_START: 2200,
  REPLICATION_TRANSACTION_COMMIT: 2201,
  REPLICATION_TRANSACTION_ABORT: 2202,

  REPLICATION_MARKER_DOCUMENT: 2300,
  REPLICATION_MARKER_EDGE: 2301,
  REPLICATION_MARKER_REMOVE: 2302
};

function syncCollectionFinalize (database, collname, from, config) {
  var url = endpointToURL(config.endpoint) + '/_db/' + database +
    '/_api/replication/logger-follow?collection=' + collname + '&from=';

  var coll = require('internal').db[collname];

  var transactions = {};

  function apply (entry) {
    var todo;

    function tryPostpone (entry) {
      if (entry.tid !== '0') {
        todo = transactions[entry.tid];
        if (Array.isArray(todo)) {
          entry.tid = '0';
          todo.push(entry);
          return true;
        }
      }
      return false;
    }

    if (entry.type === mType.REPLICATION_MARKER_DOCUMENT) {
      if (tryPostpone(entry)) {
        return;
      }
      try {
        coll.insert(entry.data, {isRestore: true});
        return;
      } catch (err) {
        console.debug('syncCollectionFinalize: insert1', entry, JSON.stringify(err));
      }
      try {
        coll.replace(entry.data._key, entry.data, {isRestore: true});
      } catch (errx) {
        console.error('syncCollectionFinalize: replace1', entry, JSON.stringify(errx));
        throw errx;
      }
    } else if (entry.type === mType.REPLICATION_MARKER_EDGE) {
      if (tryPostpone(entry)) {
        return;
      }
      try {
        coll.insert(entry.data, {isRestore: true});
        return;
      } catch (err) {
        console.debug('syncCollectionFinalize: insert2', entry, JSON.stringify(err));
      }
      try {
        coll.replace(entry.data._key, entry.data, {isRestore: true});
      } catch (errx) {
        console.error('syncCollectionFinalize: replace2', entry, JSON.stringify(errx));
        throw errx;
      }
    } else if (entry.type === mType.REPLICATION_MARKER_REMOVE) {
      if (tryPostpone(entry)) {
        return;
      }
      try {
        coll.remove(entry.data._key);
      } catch (errx) {
        console.error('syncCollectionFinalize: remove', entry, JSON.stringify(errx));
        if (errx.errorNum !== ERRORS.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code) {
          throw errx;
        }
        // We swallow the NOT FOUND error here. It is possible that
        // a follower tries to synchronize to a leader with whom it
        // is already in sync. In that case there could have been a
        // synchronously replicated removal operation that has happened
        // whilst we were resynchronizing the shard. In this case, the
        // removal would have happened already.
      }
    } else if (entry.type === mType.REPLICATION_TRANSACTION_START) {
      transactions[entry.tid] = [];
    } else if (entry.type === mType.REPLICATION_TRANSACTION_COMMIT) {
      todo = transactions[entry.tid];
      if (Array.isArray(todo)) {
        for (var i = 0; i < todo.length; i++) {
          apply(todo[i]);
        }
      }
      delete transactions[entry.tid];
    } else if (entry.type === mType.REPLICATION_TRANSACTION_ABORT) {
      delete transactions[entry.tid];
    } else if (entry.type === mType.REPLICATION_INDEX_CREATE) {
      try {
        coll.ensureIndex(entry.data);
      } catch(errx) {
        console.error('syncCollectionFinalize: ensureIndex', entry, JSON.stringify(errx));
        throw errx;
      }
    } else if (entry.type === mType.REPLICATION_INDEX_DROP) {
      try {
        coll.dropIndex(entry.data.id);
      } catch(errx) {
        console.error('syncCollectionFinalize: dropIndex', entry, JSON.stringify(errx));
        throw errx;
      }
    } else if (entry.type === mType.REPLICATION_COLLECTION_CHANGE) {
      try {
        coll.properties(entry.data);
      } catch(errx) {
        console.error('syncCollectionFinalize: properties', entry, JSON.stringify(errx));
        throw errx;
      }
    } else {
      // all else, including dropping and creating the collection
      console.warn('Found collection drop, create or rename marker:', entry);
    }
  }

  while (true) {
    var chunk = request(url + from);
    if (chunk.statusCode !== 200 &&
      chunk.statusCode !== 204) {
      return {error: true, errorMessage: 'could not contact leader',
      response: chunk};
    }
    if (chunk.statusCode === 204 || chunk.body.length === 0) {
      break; // all done
    }

    var l = chunk.body.split('\n');
    l.pop();
    try {
      l = l.map(JSON.parse);
    } catch (err) {
      return {error: true, errorMessage: 'could not parse body',
              response: chunk, exception: err};
    }

    console.debug('Applying chunk:', l);
    try {
      for (var i = 0; i < l.length; i++) {
        apply(l[i]);
      }
    } catch (err2) {
      return {error: true, errorMessage: 'could not replicate body ops',
              response: chunk, exception: err2};
    }
    if (chunk.headers['x-arango-replication-checkmore'] !== 'true') {
      break; // all done
    }

    from = chunk.headers['x-arango-replication-lastincluded'];
  }
  return {error: false};
}

exports.logger = logger;
exports.applier = applier;
exports.sync = sync;
exports.syncCollection = syncCollection;
exports.setupReplication = setupReplication;
exports.serverId = serverId;
exports.syncCollectionFinalize = syncCollectionFinalize;
<|endoftext|>


<commit_before>
import Observable from './Observable';
import ArrayObserver from './ArrayObserver';

class ObservableArray extends Observable {

    constructor(wrapped) {
        this._wrapped = wrapped ? wrapped : [];
    }

    _createObserver() {
        return new ArrayObserver();
    }

    _markAsRead() {
        if (this._observer !== null) {
            this._observer.markAsRead();
        }
    }

    _markAsChanged() {
        if (this._observer !== null) {
            this._observer.markAsChanged();
        }
    }

    set [index](value) {
    	this._wrapped[index] = value;
    	this._markAsChanged();
    }

    get [index] {
    	this._markAsRead();
    	return index >= 0 && index < this._wrapped.length ? this._wrapped[index] : undefined;
    }

    get length() {
    	this._markAsRead();
    	return this._wrapped.length;
    }

    concat(other) {
    	this._markAsRead();
    	const otherWrapped = other instanceof ObservableArray ? other._wrapped : other;
    	return this._wrapped.concat(arguments);
    }

	copyWithin(target, start, end) {
    	this._markAsRead();
    	return this._wrapped.copyWithin(target, start, end);
	}

	entries() {
    	this._markAsRead();
    	return this._wrapped.entries();
	}

	every(callback, thisArg) {
    	this._markAsRead();
    	return this._wrapped.entries(callback, thisArg);
	}

	fill(value, start, end) {
    	this._markAsChanged();
    	this._wrapped.fill(value, start, end);
    	return this;
	}

	filter(callback, thisArg) {
    	this._markAsRead();
    	return this._wrapped.filter(callback, thisArg);
	}

	find(callback, thisArg) {
    	this._markAsRead();
    	return this._wrapped.find(callback, thisArg);
	}

	findIndex(callback, thisArg) {
    	this._markAsRead();
    	return this._wrapped.findIndex(callback, thisArg);
	}

	forEach(callback, thisArg) {
    	this._markAsRead();
    	this._wrapped.forEach(callback, thisArg);
	}

	includes(searchElement, fromIndex) {
    	this._markAsRead();
    	return this._wrapped.includes(searchElement, fromIndex);
	}

	indexOf(searchElement, fromIndex) {
    	this._markAsRead();
    	return this._wrapped.indexOf(searchElement, fromIndex);
	}

	join(separator) {
    	this._markAsRead();
    	return this._wrapped.join(separator);
	}

	keys() {
    	this._markAsRead();
    	return this._wrapped.keys();
	}

	lastIndexOf(searchElement, fromIndex) {
    	this._markAsRead();
    	return this._wrapped.lastIndexOf(searchElement, fromIndex);
	}

	map(callback, thisArg) {
    	this._markAsRead();
    	return this._wrapped.map(callback, thisArg));
	}

	pop() {
    	this._markAsRead();
    	return this._wrapped.pop();
	}

	push(value) {
    	this._markAsChanged();
    	this._wrapped.push(value);
    	return this._wrapped.length;
	}

	reduce(callback, initialValue) {
    	this._markAsRead();
    	return this._wrapped.reduce(callback, initialValue);
	}

	reduceRight(callback, initialValue) {
    	this._markAsRead();
    	return this._wrapped.reduce(callback, initialValue);
	}

	reverse() {
    	this._markAsChanged();
    	return this._wrapped.reverse();
	}

	shift() {
    	this._markAsChanged();
    	return this._wrapped.shift();
	}

	slice(begin, end) {
    	this._markAsRead();
    	return this._wrapped.slice(begin, end));
	}

	some(callback, thisArg) {
    	this._markAsRead();
    	return this._wrapped.some();
	}

	sort(compareFunction) {
    	this._markAsChanged();
    	return this._wrapped.sort(compareFunction);
	}

	splice(start, deleteCount, item1) {
    	this._markAsChanged();
    	return this._wrapped.splice(arguments);
	}
}
<commit_msg>added a view missing functions<commit_after>
import Observable from './Observable';
import ArrayObserver from './ArrayObserver';

class ObservableArray extends Observable {

    constructor(wrapped) {
        this._wrapped = wrapped ? wrapped : [];
    }

    _createObserver() {
        return new ArrayObserver();
    }

    _markAsRead() {
        if (this._observer !== null) {
            this._observer.markAsRead();
        }
    }

    _markAsChanged() {
        if (this._observer !== null) {
            this._observer.markAsChanged();
        }
    }

    set [index](value) {
        this._wrapped[index] = value;
        this._markAsChanged();
    }

    get [index] {
        this._markAsRead();
        return index >= 0 && index < this._wrapped.length ? this._wrapped[index] : undefined;
    }

    get length() {
        this._markAsRead();
        return this._wrapped.length;
    }

    concat(other) {
        this._markAsRead();
        const otherWrapped = other instanceof ObservableArray ? other._wrapped : other;
        return this._wrapped.concat(arguments);
    }

    copyWithin(target, start, end) {
        this._markAsRead();
        return this._wrapped.copyWithin(target, start, end);
    }

    entries() {
        this._markAsRead();
        return this._wrapped.entries();
    }

    every(callback, thisArg) {
        this._markAsRead();
        return this._wrapped.entries(callback, thisArg);
    }

    fill(value, start, end) {
        this._markAsChanged();
        this._wrapped.fill(value, start, end);
        return this;
    }

    filter(callback, thisArg) {
        this._markAsRead();
        return this._wrapped.filter(callback, thisArg);
    }

    find(callback, thisArg) {
        this._markAsRead();
        return this._wrapped.find(callback, thisArg);
    }

    findIndex(callback, thisArg) {
        this._markAsRead();
        return this._wrapped.findIndex(callback, thisArg);
    }

    forEach(callback, thisArg) {
        this._markAsRead();
        this._wrapped.forEach(callback, thisArg);
    }

    includes(searchElement, fromIndex) {
        this._markAsRead();
        return this._wrapped.includes(searchElement, fromIndex);
    }

    indexOf(searchElement, fromIndex) {
        this._markAsRead();
        return this._wrapped.indexOf(searchElement, fromIndex);
    }

    join(separator) {
        this._markAsRead();
        return this._wrapped.join(separator);
    }

    keys() {
        this._markAsRead();
        return this._wrapped.keys();
    }

    lastIndexOf(searchElement, fromIndex) {
        this._markAsRead();
        return this._wrapped.lastIndexOf(searchElement, fromIndex);
    }

    map(callback, thisArg) {
        this._markAsRead();
        return this._wrapped.map(callback, thisArg));
    }

    pop() {
        this._markAsRead();
        return this._wrapped.pop();
    }

    push(value) {
        this._markAsChanged();
        this._wrapped.push(value);
        return this._wrapped.length;
    }

    reduce(callback, initialValue) {
        this._markAsRead();
        return this._wrapped.reduce(callback, initialValue);
    }

    reduceRight(callback, initialValue) {
        this._markAsRead();
        return this._wrapped.reduce(callback, initialValue);
    }

    reverse() {
        this._markAsChanged();
        return this._wrapped.reverse();
    }

    shift() {
        this._markAsChanged();
        return this._wrapped.shift();
    }

    slice(begin, end) {
        this._markAsRead();
        return this._wrapped.slice(begin, end));
    }

    some(callback, thisArg) {
        this._markAsRead();
        return this._wrapped.some();
    }

    sort(compareFunction) {
        this._markAsChanged();
        return this._wrapped.sort(compareFunction);
    }

    splice(start, deleteCount, item1) {
        this._markAsChanged();
        return this._wrapped.splice(arguments);
    }

    toLocalString() {
        this._markAsRead();
        return this._wrapped.toLocalString();
    }

    toSource() {
        this._markAsRead();
        return this._wrapped.toSource();
    }

    toString() {
        this._markAsRead();
        return this._wrapped.toString();
    }

    unshift(element1) {
        this._markAsChanged();
        return this._wrapped.splice(arguments);
    }

    values() {
        this._markAsRead();
        return this._wrapped.values();
    }
}
<|endoftext|>


<commit_before>/**
 * @module ol/interaction/Translate
 */
import Collection from '../Collection.js';
import Event from '../events/Event.js';
import InteractionProperty from './Property.js';
import PointerInteraction from './Pointer.js';
import {TRUE} from '../functions.js';
import {getChangeEventType} from '../Object.js';
import {includes} from '../array.js';

/**
 * @enum {string}
 */
const TranslateEventType = {
  /**
   * Triggered upon feature translation start.
   * @event TranslateEvent#translatestart
   * @api
   */
  TRANSLATESTART: 'translatestart',
  /**
   * Triggered upon feature translation.
   * @event TranslateEvent#translating
   * @api
   */
  TRANSLATING: 'translating',
  /**
   * Triggered upon feature translation end.
   * @event TranslateEvent#translateend
   * @api
   */
  TRANSLATEEND: 'translateend',
};

/**
 * A function that takes an {@link module:ol/Feature} or
 * {@link module:ol/render/Feature} and an
 * {@link module:ol/layer/Layer} and returns `true` if the feature may be
 * translated or `false` otherwise.
 * @typedef {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default):boolean} FilterFunction
 */

/**
 * @typedef {Object} Options
 * @property {Collection<import("../Feature.js").default>} [features] Only features contained in this collection will be able to be translated. If
 * not specified, all features on the map will be able to be translated.
 * @property {Array<import("../layer/Layer.js").default>|function(import("../layer/Layer.js").default): boolean} [layers] A list of layers from which features should be
 * translated. Alternatively, a filter function can be provided. The
 * function will be called for each layer in the map and should return
 * `true` for layers that you want to be translatable. If the option is
 * absent, all visible layers will be considered translatable.
 * @property {FilterFunction} [filter] A function
 * that takes an {@link module:ol/Feature} and an
 * {@link module:ol/layer/Layer} and returns `true` if the feature may be
 * translated or `false` otherwise.
 * @property {number} [hitTolerance=0] Hit-detection tolerance. Pixels inside the radius around the given position
 * will be checked for features.
 */

/**
 * @classdesc
 * Events emitted by {@link module:ol/interaction/Translate~Translate} instances
 * are instances of this type.
 */
export class TranslateEvent extends Event {
  /**
   * @param {TranslateEventType} type Type.
   * @param {Collection<import("../Feature.js").default>} features The features translated.
   * @param {import("../coordinate.js").Coordinate} coordinate The event coordinate.
   * @param {import("../coordinate.js").Coordinate} startCoordinate The original coordinates before.translation started
   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
   */
  constructor(type, features, coordinate, startCoordinate, mapBrowserEvent) {
    super(type);

    /**
     * The features being translated.
     * @type {Collection<import("../Feature.js").default>}
     * @api
     */
    this.features = features;

    /**
     * The coordinate of the drag event.
     * @const
     * @type {import("../coordinate.js").Coordinate}
     * @api
     */
    this.coordinate = coordinate;

    /**
     * The coordinate of the start position before translation started.
     * @const
     * @type {import("../coordinate.js").Coordinate}
     * @api
     */
    this.startCoordinate = startCoordinate;

    /**
     * Associated {@link module:ol/MapBrowserEvent}.
     * @type {import("../MapBrowserEvent.js").default}
     * @api
     */
    this.mapBrowserEvent = mapBrowserEvent;
  }
}

/**
 * @classdesc
 * Interaction for translating (moving) features.
 *
 * @fires TranslateEvent
 * @api
 */
class Translate extends PointerInteraction {
  /**
   * @param {Options=} opt_options Options.
   */
  constructor(opt_options) {
    const options = opt_options ? opt_options : {};

    super(/** @type {import("./Pointer.js").Options} */ (options));

    /**
     * The last position we translated to.
     * @type {import("../coordinate.js").Coordinate}
     * @private
     */
    this.lastCoordinate_ = null;

    /**
     * The start position before translation started.
     * @type {import("../coordinate.js").Coordinate}
     * @private
     */
    this.startCoordinate_ = null;

    /**
     * @type {Collection<import("../Feature.js").default>}
     * @private
     */
    this.features_ = options.features !== undefined ? options.features : null;

    /** @type {function(import("../layer/Layer.js").default): boolean} */
    let layerFilter;
    if (options.layers) {
      if (typeof options.layers === 'function') {
        layerFilter = options.layers;
      } else {
        const layers = options.layers;
        layerFilter = function (layer) {
          return includes(layers, layer);
        };
      }
    } else {
      layerFilter = TRUE;
    }

    /**
     * @private
     * @type {function(import("../layer/Layer.js").default): boolean}
     */
    this.layerFilter_ = layerFilter;

    /**
     * @private
     * @type {FilterFunction}
     */
    this.filter_ = options.filter ? options.filter : TRUE;

    /**
     * @private
     * @type {number}
     */
    this.hitTolerance_ = options.hitTolerance ? options.hitTolerance : 0;

    /**
     * @type {import("../Feature.js").default}
     * @private
     */
    this.lastFeature_ = null;

    this.addEventListener(
      getChangeEventType(InteractionProperty.ACTIVE),
      this.handleActiveChanged_
    );
  }

  /**
   * Handle pointer down events.
   * @param {import("../MapBrowserPointerEvent.js").default} event Event.
   * @return {boolean} If the event was consumed.
   */
  handleDownEvent(event) {
    this.lastFeature_ = this.featuresAtPixel_(event.pixel, event.map);
    if (!this.lastCoordinate_ && this.lastFeature_) {
      this.startCoordinate_ = event.coordinate;
      this.lastCoordinate_ = event.coordinate;
      this.handleMoveEvent(event);

      const features = this.features_ || new Collection([this.lastFeature_]);

      this.dispatchEvent(
        new TranslateEvent(
          TranslateEventType.TRANSLATESTART,
          features,
          event.coordinate,
          this.startCoordinate_,
          event
        )
      );
      return true;
    }
    return false;
  }

  /**
   * Handle pointer up events.
   * @param {import("../MapBrowserPointerEvent.js").default} event Event.
   * @return {boolean} If the event was consumed.
   */
  handleUpEvent(event) {
    if (this.lastCoordinate_) {
      this.lastCoordinate_ = null;
      this.handleMoveEvent(event);

      const features = this.features_ || new Collection([this.lastFeature_]);

      this.dispatchEvent(
        new TranslateEvent(
          TranslateEventType.TRANSLATEEND,
          features,
          event.coordinate,
          this.startCoordinate_,
          event
        )
      );
      // cleanup
      this.startCoordinate_ = null;
      return true;
    }
    return false;
  }

  /**
   * Handle pointer drag events.
   * @param {import("../MapBrowserPointerEvent.js").default} event Event.
   */
  handleDragEvent(event) {
    if (this.lastCoordinate_) {
      const newCoordinate = event.coordinate;
      const deltaX = newCoordinate[0] - this.lastCoordinate_[0];
      const deltaY = newCoordinate[1] - this.lastCoordinate_[1];

      const features = this.features_ || new Collection([this.lastFeature_]);

      features.forEach(function (feature) {
        const geom = feature.getGeometry();
        geom.translate(deltaX, deltaY);
        feature.setGeometry(geom);
      });

      this.lastCoordinate_ = newCoordinate;
      this.dispatchEvent(
        new TranslateEvent(
          TranslateEventType.TRANSLATING,
          features,
          newCoordinate,
          this.startCoordinate_,
          event
        )
      );
    }
  }

  /**
   * Handle pointer move events.
   * @param {import("../MapBrowserPointerEvent.js").default} event Event.
   */
  handleMoveEvent(event) {
    const elem = event.map.getViewport();

    // Change the cursor to grab/grabbing if hovering any of the features managed
    // by the interaction
    if (this.featuresAtPixel_(event.pixel, event.map)) {
      elem.classList.remove(this.lastCoordinate_ ? 'ol-grab' : 'ol-grabbing');
      elem.classList.add(this.lastCoordinate_ ? 'ol-grabbing' : 'ol-grab');
    } else {
      elem.classList.remove('ol-grab', 'ol-grabbing');
    }
  }

  /**
   * Tests to see if the given coordinates intersects any of our selected
   * features.
   * @param {import("../pixel.js").Pixel} pixel Pixel coordinate to test for intersection.
   * @param {import("../PluggableMap.js").default} map Map to test the intersection on.
   * @return {import("../Feature.js").default} Returns the feature found at the specified pixel
   * coordinates.
   * @private
   */
  featuresAtPixel_(pixel, map) {
    return map.forEachFeatureAtPixel(
      pixel,
      function (feature, layer) {
        if (this.filter_(feature, layer)) {
          if (!this.features_ || includes(this.features_.getArray(), feature)) {
            return feature;
          }
        }
      }.bind(this),
      {
        layerFilter: this.layerFilter_,
        hitTolerance: this.hitTolerance_,
      }
    );
  }

  /**
   * Returns the Hit-detection tolerance.
   * @returns {number} Hit tolerance in pixels.
   * @api
   */
  getHitTolerance() {
    return this.hitTolerance_;
  }

  /**
   * Hit-detection tolerance. Pixels inside the radius around the given position
   * will be checked for features.
   * @param {number} hitTolerance Hit tolerance in pixels.
   * @api
   */
  setHitTolerance(hitTolerance) {
    this.hitTolerance_ = hitTolerance;
  }

  /**
   * Remove the interaction from its current map and attach it to the new map.
   * Subclasses may set up event handlers to get notified about changes to
   * the map here.
   * @param {import("../PluggableMap.js").default} map Map.
   */
  setMap(map) {
    const oldMap = this.getMap();
    super.setMap(map);
    this.updateState_(oldMap);
  }

  /**
   * @private
   */
  handleActiveChanged_() {
    this.updateState_(null);
  }

  /**
   * @param {import("../PluggableMap.js").default} oldMap Old map.
   * @private
   */
  updateState_(oldMap) {
    let map = this.getMap();
    const active = this.getActive();
    if (!map || !active) {
      map = map || oldMap;
      if (map) {
        const elem = map.getViewport();
        elem.classList.remove('ol-grab', 'ol-grabbing');
      }
    }
  }
}

export default Translate;
<commit_msg>Do not scroll page during feature translation<commit_after>/**
 * @module ol/interaction/Translate
 */
import Collection from '../Collection.js';
import Event from '../events/Event.js';
import InteractionProperty from './Property.js';
import PointerInteraction from './Pointer.js';
import {TRUE} from '../functions.js';
import {getChangeEventType} from '../Object.js';
import {includes} from '../array.js';

/**
 * @enum {string}
 */
const TranslateEventType = {
  /**
   * Triggered upon feature translation start.
   * @event TranslateEvent#translatestart
   * @api
   */
  TRANSLATESTART: 'translatestart',
  /**
   * Triggered upon feature translation.
   * @event TranslateEvent#translating
   * @api
   */
  TRANSLATING: 'translating',
  /**
   * Triggered upon feature translation end.
   * @event TranslateEvent#translateend
   * @api
   */
  TRANSLATEEND: 'translateend',
};

/**
 * A function that takes an {@link module:ol/Feature} or
 * {@link module:ol/render/Feature} and an
 * {@link module:ol/layer/Layer} and returns `true` if the feature may be
 * translated or `false` otherwise.
 * @typedef {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default):boolean} FilterFunction
 */

/**
 * @typedef {Object} Options
 * @property {Collection<import("../Feature.js").default>} [features] Only features contained in this collection will be able to be translated. If
 * not specified, all features on the map will be able to be translated.
 * @property {Array<import("../layer/Layer.js").default>|function(import("../layer/Layer.js").default): boolean} [layers] A list of layers from which features should be
 * translated. Alternatively, a filter function can be provided. The
 * function will be called for each layer in the map and should return
 * `true` for layers that you want to be translatable. If the option is
 * absent, all visible layers will be considered translatable.
 * @property {FilterFunction} [filter] A function
 * that takes an {@link module:ol/Feature} and an
 * {@link module:ol/layer/Layer} and returns `true` if the feature may be
 * translated or `false` otherwise.
 * @property {number} [hitTolerance=0] Hit-detection tolerance. Pixels inside the radius around the given position
 * will be checked for features.
 */

/**
 * @classdesc
 * Events emitted by {@link module:ol/interaction/Translate~Translate} instances
 * are instances of this type.
 */
export class TranslateEvent extends Event {
  /**
   * @param {TranslateEventType} type Type.
   * @param {Collection<import("../Feature.js").default>} features The features translated.
   * @param {import("../coordinate.js").Coordinate} coordinate The event coordinate.
   * @param {import("../coordinate.js").Coordinate} startCoordinate The original coordinates before.translation started
   * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
   */
  constructor(type, features, coordinate, startCoordinate, mapBrowserEvent) {
    super(type);

    /**
     * The features being translated.
     * @type {Collection<import("../Feature.js").default>}
     * @api
     */
    this.features = features;

    /**
     * The coordinate of the drag event.
     * @const
     * @type {import("../coordinate.js").Coordinate}
     * @api
     */
    this.coordinate = coordinate;

    /**
     * The coordinate of the start position before translation started.
     * @const
     * @type {import("../coordinate.js").Coordinate}
     * @api
     */
    this.startCoordinate = startCoordinate;

    /**
     * Associated {@link module:ol/MapBrowserEvent}.
     * @type {import("../MapBrowserEvent.js").default}
     * @api
     */
    this.mapBrowserEvent = mapBrowserEvent;
  }
}

/**
 * @classdesc
 * Interaction for translating (moving) features.
 *
 * @fires TranslateEvent
 * @api
 */
class Translate extends PointerInteraction {
  /**
   * @param {Options=} opt_options Options.
   */
  constructor(opt_options) {
    const options = opt_options ? opt_options : {};

    super(/** @type {import("./Pointer.js").Options} */ (options));

    /**
     * The last position we translated to.
     * @type {import("../coordinate.js").Coordinate}
     * @private
     */
    this.lastCoordinate_ = null;

    /**
     * The start position before translation started.
     * @type {import("../coordinate.js").Coordinate}
     * @private
     */
    this.startCoordinate_ = null;

    /**
     * @type {Collection<import("../Feature.js").default>}
     * @private
     */
    this.features_ = options.features !== undefined ? options.features : null;

    /** @type {function(import("../layer/Layer.js").default): boolean} */
    let layerFilter;
    if (options.layers) {
      if (typeof options.layers === 'function') {
        layerFilter = options.layers;
      } else {
        const layers = options.layers;
        layerFilter = function (layer) {
          return includes(layers, layer);
        };
      }
    } else {
      layerFilter = TRUE;
    }

    /**
     * @private
     * @type {function(import("../layer/Layer.js").default): boolean}
     */
    this.layerFilter_ = layerFilter;

    /**
     * @private
     * @type {FilterFunction}
     */
    this.filter_ = options.filter ? options.filter : TRUE;

    /**
     * @private
     * @type {number}
     */
    this.hitTolerance_ = options.hitTolerance ? options.hitTolerance : 0;

    /**
     * @type {import("../Feature.js").default}
     * @private
     */
    this.lastFeature_ = null;

    this.addEventListener(
      getChangeEventType(InteractionProperty.ACTIVE),
      this.handleActiveChanged_
    );
  }

  /**
   * Handle pointer down events.
   * @param {import("../MapBrowserPointerEvent.js").default} event Event.
   * @return {boolean} If the event was consumed.
   */
  handleDownEvent(event) {
    this.lastFeature_ = this.featuresAtPixel_(event.pixel, event.map);
    if (!this.lastCoordinate_ && this.lastFeature_) {
      this.startCoordinate_ = event.coordinate;
      this.lastCoordinate_ = event.coordinate;
      this.handleMoveEvent(event);

      const features = this.features_ || new Collection([this.lastFeature_]);

      this.dispatchEvent(
        new TranslateEvent(
          TranslateEventType.TRANSLATESTART,
          features,
          event.coordinate,
          this.startCoordinate_,
          event
        )
      );
      return true;
    }
    return false;
  }

  /**
   * Handle pointer up events.
   * @param {import("../MapBrowserPointerEvent.js").default} event Event.
   * @return {boolean} If the event was consumed.
   */
  handleUpEvent(event) {
    if (this.lastCoordinate_) {
      this.lastCoordinate_ = null;
      this.handleMoveEvent(event);

      const features = this.features_ || new Collection([this.lastFeature_]);

      this.dispatchEvent(
        new TranslateEvent(
          TranslateEventType.TRANSLATEEND,
          features,
          event.coordinate,
          this.startCoordinate_,
          event
        )
      );
      // cleanup
      this.startCoordinate_ = null;
      return true;
    }
    return false;
  }

  /**
   * Handle pointer drag events.
   * @param {import("../MapBrowserPointerEvent.js").default} event Event.
   */
  handleDragEvent(event) {
    if (this.lastCoordinate_) {
      const newCoordinate = event.coordinate;
      const deltaX = newCoordinate[0] - this.lastCoordinate_[0];
      const deltaY = newCoordinate[1] - this.lastCoordinate_[1];

      const features = this.features_ || new Collection([this.lastFeature_]);

      features.forEach(function (feature) {
        const geom = feature.getGeometry();
        geom.translate(deltaX, deltaY);
        feature.setGeometry(geom);
      });

      this.lastCoordinate_ = newCoordinate;
      // Prevent page scrolling during drag
      event.preventDefault();
      this.dispatchEvent(
        new TranslateEvent(
          TranslateEventType.TRANSLATING,
          features,
          newCoordinate,
          this.startCoordinate_,
          event
        )
      );
    }
  }

  /**
   * Handle pointer move events.
   * @param {import("../MapBrowserPointerEvent.js").default} event Event.
   */
  handleMoveEvent(event) {
    const elem = event.map.getViewport();

    // Change the cursor to grab/grabbing if hovering any of the features managed
    // by the interaction
    if (this.featuresAtPixel_(event.pixel, event.map)) {
      elem.classList.remove(this.lastCoordinate_ ? 'ol-grab' : 'ol-grabbing');
      elem.classList.add(this.lastCoordinate_ ? 'ol-grabbing' : 'ol-grab');
    } else {
      elem.classList.remove('ol-grab', 'ol-grabbing');
    }
  }

  /**
   * Tests to see if the given coordinates intersects any of our selected
   * features.
   * @param {import("../pixel.js").Pixel} pixel Pixel coordinate to test for intersection.
   * @param {import("../PluggableMap.js").default} map Map to test the intersection on.
   * @return {import("../Feature.js").default} Returns the feature found at the specified pixel
   * coordinates.
   * @private
   */
  featuresAtPixel_(pixel, map) {
    return map.forEachFeatureAtPixel(
      pixel,
      function (feature, layer) {
        if (this.filter_(feature, layer)) {
          if (!this.features_ || includes(this.features_.getArray(), feature)) {
            return feature;
          }
        }
      }.bind(this),
      {
        layerFilter: this.layerFilter_,
        hitTolerance: this.hitTolerance_,
      }
    );
  }

  /**
   * Returns the Hit-detection tolerance.
   * @returns {number} Hit tolerance in pixels.
   * @api
   */
  getHitTolerance() {
    return this.hitTolerance_;
  }

  /**
   * Hit-detection tolerance. Pixels inside the radius around the given position
   * will be checked for features.
   * @param {number} hitTolerance Hit tolerance in pixels.
   * @api
   */
  setHitTolerance(hitTolerance) {
    this.hitTolerance_ = hitTolerance;
  }

  /**
   * Remove the interaction from its current map and attach it to the new map.
   * Subclasses may set up event handlers to get notified about changes to
   * the map here.
   * @param {import("../PluggableMap.js").default} map Map.
   */
  setMap(map) {
    const oldMap = this.getMap();
    super.setMap(map);
    this.updateState_(oldMap);
  }

  /**
   * @private
   */
  handleActiveChanged_() {
    this.updateState_(null);
  }

  /**
   * @param {import("../PluggableMap.js").default} oldMap Old map.
   * @private
   */
  updateState_(oldMap) {
    let map = this.getMap();
    const active = this.getActive();
    if (!map || !active) {
      map = map || oldMap;
      if (map) {
        const elem = map.getViewport();
        elem.classList.remove('ol-grab', 'ol-grabbing');
      }
    }
  }
}

export default Translate;
<|endoftext|>


<commit_before>goog.provide('ol.source.BingMaps');

goog.require('goog.Uri');
goog.require('goog.array');
goog.require('goog.net.Jsonp');
goog.require('ol.Attribution');
goog.require('ol.Extent');
goog.require('ol.Size');
goog.require('ol.TileCoord');
goog.require('ol.TileRange');
goog.require('ol.TileUrlFunction');
goog.require('ol.projection');
goog.require('ol.source.ImageTileSource');
goog.require('ol.tilegrid.XYZ');

/**
 * @constructor
 * @extends {ol.source.ImageTileSource}
 * @param {ol.source.BingMapsOptions} bingMapsOptions Bing Maps options.
 */
ol.source.BingMaps = function(bingMapsOptions) {

  goog.base(this, {
    crossOrigin: 'anonymous',
    opaque: true,
    projection: ol.projection.get('EPSG:3857')
  });

  /**
   * @private
   * @type {string}
   */
  this.culture_ = goog.isDef(bingMapsOptions.culture) ?
      bingMapsOptions.culture : 'en-us';

  /**
   * @private
   * @type {boolean}
   */
  this.ready_ = false;

  var uri = new goog.Uri(
      '//dev.virtualearth.net/REST/v1/Imagery/Metadata/' +
      bingMapsOptions.style);
  var jsonp = new goog.net.Jsonp(uri, 'jsonp');
  jsonp.send({
    'include': 'ImageryProviders',
    'key': bingMapsOptions.key
  }, goog.bind(this.handleImageryMetadataResponse, this));

};
goog.inherits(ol.source.BingMaps, ol.source.ImageTileSource);

/**
 * @param {BingMapsImageryMetadataResponse} response Response.
 */
ol.source.BingMaps.prototype.handleImageryMetadataResponse =
    function(response) {

  goog.asserts.assert(
      response.authenticationResultCode == 'ValidCredentials');
  goog.asserts.assert(response.statusCode == 200);
  goog.asserts.assert(response.statusDescription == 'OK');

  var brandLogoUri = response.brandLogoUri;
  var copyright = response.copyright;
  goog.asserts.assert(response.resourceSets.length == 1);
  var resourceSet = response.resourceSets[0];
  goog.asserts.assert(resourceSet.resources.length == 1);
  var resource = resourceSet.resources[0];

  var zoomMin = resource.zoomMin;
  var zoomMax = resource.zoomMax;
  var tileSize = new ol.Size(resource.imageWidth, resource.imageHeight);
  var tileGrid = new ol.tilegrid.XYZ({
    maxZoom: zoomMax,
    tileSize: tileSize
  });
  this.tileGrid = tileGrid;

  this.tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform(
      function(tileCoord) {
        if (tileCoord.z < zoomMin || zoomMax < tileCoord.z) {
          return null;
        }
        var n = 1 << tileCoord.z;
        var y = -tileCoord.y - 1;
        if (y < 0 || n <= y) {
          return null;
        } else {
          var x = goog.math.modulo(tileCoord.x, n);
          return new ol.TileCoord(tileCoord.z, x, y);
        }
      },
      ol.TileUrlFunction.createFromTileUrlFunctions(
          goog.array.map(
              resource.imageUrlSubdomains,
              function(subdomain) {
                var imageUrl = resource.imageUrl
                    .replace('{subdomain}', subdomain)
                    .replace('{culture}', this.culture_);
                return function(tileCoord) {
                  if (goog.isNull(tileCoord)) {
                    return undefined;
                  } else {
                    return imageUrl.replace(
                        '{quadkey}', tileCoord.quadKey());
                  }
                };
              })));

  var transform = ol.projection.getTransformFromProjections(
      ol.projection.get('EPSG:4326'), this.getProjection());
  var attributions = goog.array.map(
      resource.imageryProviders,
      function(imageryProvider) {
        var html = imageryProvider.attribution;
        /** @type {Object.<string, Array.<ol.TileRange>>} */
        var tileRanges = {};
        goog.array.forEach(
            imageryProvider.coverageAreas,
            function(coverageArea) {
              var minZ = coverageArea.zoomMin;
              var maxZ = coverageArea.zoomMax;
              var bbox = coverageArea.bbox;
              var epsg4326Extent =
                  new ol.Extent(bbox[1], bbox[0], bbox[3], bbox[2]);
              var extent = epsg4326Extent.transform(transform);
              var tileRange, z, zKey;
              for (z = minZ; z <= maxZ; ++z) {
                zKey = z.toString();
                tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
                if (zKey in tileRanges) {
                  tileRanges[zKey].push(tileRange);
                } else {
                  tileRanges[zKey] = [tileRange];
                }
              }
            });
        return new ol.Attribution(html, tileRanges);
      });
  this.setAttributions(attributions);

  this.ready_ = true;

  this.dispatchLoadEvent();

};

/**
 * @inheritDoc
 */
ol.source.BingMaps.prototype.isReady = function() {
  return this.ready_;
};
<commit_msg>Fix use of this in ol.source.BingMaps<commit_after>goog.provide('ol.source.BingMaps');

goog.require('goog.Uri');
goog.require('goog.array');
goog.require('goog.net.Jsonp');
goog.require('ol.Attribution');
goog.require('ol.Extent');
goog.require('ol.Size');
goog.require('ol.TileCoord');
goog.require('ol.TileRange');
goog.require('ol.TileUrlFunction');
goog.require('ol.projection');
goog.require('ol.source.ImageTileSource');
goog.require('ol.tilegrid.XYZ');

/**
 * @constructor
 * @extends {ol.source.ImageTileSource}
 * @param {ol.source.BingMapsOptions} bingMapsOptions Bing Maps options.
 */
ol.source.BingMaps = function(bingMapsOptions) {

  goog.base(this, {
    crossOrigin: 'anonymous',
    opaque: true,
    projection: ol.projection.get('EPSG:3857')
  });

  /**
   * @private
   * @type {string}
   */
  this.culture_ = goog.isDef(bingMapsOptions.culture) ?
      bingMapsOptions.culture : 'en-us';

  /**
   * @private
   * @type {boolean}
   */
  this.ready_ = false;

  var uri = new goog.Uri(
      '//dev.virtualearth.net/REST/v1/Imagery/Metadata/' +
      bingMapsOptions.style);
  var jsonp = new goog.net.Jsonp(uri, 'jsonp');
  jsonp.send({
    'include': 'ImageryProviders',
    'key': bingMapsOptions.key
  }, goog.bind(this.handleImageryMetadataResponse, this));

};
goog.inherits(ol.source.BingMaps, ol.source.ImageTileSource);

/**
 * @param {BingMapsImageryMetadataResponse} response Response.
 */
ol.source.BingMaps.prototype.handleImageryMetadataResponse =
    function(response) {

  goog.asserts.assert(
      response.authenticationResultCode == 'ValidCredentials');
  goog.asserts.assert(response.statusCode == 200);
  goog.asserts.assert(response.statusDescription == 'OK');

  var brandLogoUri = response.brandLogoUri;
  var copyright = response.copyright;
  goog.asserts.assert(response.resourceSets.length == 1);
  var resourceSet = response.resourceSets[0];
  goog.asserts.assert(resourceSet.resources.length == 1);
  var resource = resourceSet.resources[0];

  var zoomMin = resource.zoomMin;
  var zoomMax = resource.zoomMax;
  var tileSize = new ol.Size(resource.imageWidth, resource.imageHeight);
  var tileGrid = new ol.tilegrid.XYZ({
    maxZoom: zoomMax,
    tileSize: tileSize
  });
  this.tileGrid = tileGrid;

  var culture = this.culture_;
  this.tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform(
      function(tileCoord) {
        if (tileCoord.z < zoomMin || zoomMax < tileCoord.z) {
          return null;
        }
        var n = 1 << tileCoord.z;
        var y = -tileCoord.y - 1;
        if (y < 0 || n <= y) {
          return null;
        } else {
          var x = goog.math.modulo(tileCoord.x, n);
          return new ol.TileCoord(tileCoord.z, x, y);
        }
      },
      ol.TileUrlFunction.createFromTileUrlFunctions(
          goog.array.map(
              resource.imageUrlSubdomains,
              function(subdomain) {
                var imageUrl = resource.imageUrl
                    .replace('{subdomain}', subdomain)
                    .replace('{culture}', culture);
                return function(tileCoord) {
                  if (goog.isNull(tileCoord)) {
                    return undefined;
                  } else {
                    return imageUrl.replace(
                        '{quadkey}', tileCoord.quadKey());
                  }
                };
              })));

  var transform = ol.projection.getTransformFromProjections(
      ol.projection.get('EPSG:4326'), this.getProjection());
  var attributions = goog.array.map(
      resource.imageryProviders,
      function(imageryProvider) {
        var html = imageryProvider.attribution;
        /** @type {Object.<string, Array.<ol.TileRange>>} */
        var tileRanges = {};
        goog.array.forEach(
            imageryProvider.coverageAreas,
            function(coverageArea) {
              var minZ = coverageArea.zoomMin;
              var maxZ = coverageArea.zoomMax;
              var bbox = coverageArea.bbox;
              var epsg4326Extent =
                  new ol.Extent(bbox[1], bbox[0], bbox[3], bbox[2]);
              var extent = epsg4326Extent.transform(transform);
              var tileRange, z, zKey;
              for (z = minZ; z <= maxZ; ++z) {
                zKey = z.toString();
                tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
                if (zKey in tileRanges) {
                  tileRanges[zKey].push(tileRange);
                } else {
                  tileRanges[zKey] = [tileRange];
                }
              }
            });
        return new ol.Attribution(html, tileRanges);
      });
  this.setAttributions(attributions);

  this.ready_ = true;

  this.dispatchLoadEvent();

};

/**
 * @inheritDoc
 */
ol.source.BingMaps.prototype.isReady = function() {
  return this.ready_;
};
<|endoftext|>