<commit_before>/**
 * Copyright (C) 2013 Maxime Hadjinlian <maxime.hadjinlian@gmail.com>
 * All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

(function () {

  // Retain the value of the original onAdd and onRemove functions
  var originalOnAdd = L.Marker.prototype.onAdd;
  var originalOnRemove = L.Marker.prototype.onRemove;

  // Add bounceonAdd options
  L.Marker.mergeOptions({
    bounceOnAdd: false,
    bounceOnAddOptions: {
      duration: 1000,
      height: -1
    },
    bounceOnAddCallback: function() {},
  });

  L.Marker.include({

    _toPoint: function (latlng) {
      return this._map.latLngToContainerPoint(latlng);
    },
    _toLatLng: function (point) {
      return this._map.containerPointToLatLng(point);
    },

    _motionStep: function (opts) {
      var self = this;

      var start = new Date();
      self.intervalId = setInterval(function () {
        var timePassed = new Date() - start;
        var progress = timePassed / opts.duration;
        if (progress > 1) {
          progress = 1;
        }
        var delta = opts.delta(progress);
        opts.step(delta);
        if (progress === 1) {
          opts.end();
          clearInterval(self.intervalId);
        }
      }, opts.delay || 10);
    },

    _bounceMotion: function (delta, duration, callback) {
      var original = L.latLng(this._origLatlng),
          start_y = this._dropPoint.y,
          start_x = this._dropPoint.x,
          distance = this._point.y - start_y;
      var self = this;

      this._motionStep({
        delay: 10,
        duration: duration || 1000, // 1 sec by default
        delta: delta,
        step: function (delta) {
          self._dropPoint.y =
            start_y
            + (distance * delta)
            - (self._map.project(self._map.getCenter()).y - self._origMapCenter.y);
          self._dropPoint.x =
            start_x
            - (self._map.project(self._map.getCenter()).x - self._origMapCenter.x);
          self.setLatLng(self._toLatLng(self._dropPoint));
        },
        end: function () {
          self.setLatLng(original);
          if (typeof callback === "function") callback();
        }
      });
    },

    // Many thanks to Robert Penner for this function
    _easeOutBounce: function (pos) {
      if ((pos) < (1 / 2.75)) {
        return (7.5625 * pos * pos);
      } else if (pos < (2 / 2.75)) {
        return (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75);
      } else if (pos < (2.5 / 2.75)) {
        return (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375);
      } else {
        return (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375);
      }
    },

    // Bounce : if options.height in pixels is not specified, drop from top.
    // If options.duration is not specified animation is 1s long.
    bounce: function(options, endCallback) {
       this._origLatlng = this.getLatLng();
       this._bounce(options, endCallback);
    },

    _bounce: function (options, endCallback) {
      if (typeof options === "function") {
          endCallback = options;
          options = null;
      }
      options = options || {duration: 1000, height: -1};

      //backward compatibility
      if (typeof options === "number") {
        options.duration = arguments[0];
        options.height = arguments[1];
      }

      // Keep original map center
      this._origMapCenter = this._map.project(this._map.getCenter());
      this._dropPoint = this._getDropPoint(options.height);
      this._bounceMotion(this._easeOutBounce, options.duration, endCallback);
    },

    // This will get you a drop point given a height.
    // If no height is given, the top y will be used.
    _getDropPoint: function (height) {
      // Get current coordidates in pixel
      this._point = this._toPoint(this._origLatlng);
      var top_y;
      if (height === undefined || height < 0) {
        top_y = this._toPoint(this._map.getBounds()._northEast).y;
      } else {
        top_y = this._point.y - height;
      }
      return new L.Point(this._point.x, top_y);
    },

    onAdd: function (map) {
      this._map = map;
      // Keep original latitude and longitude
      this._origLatlng = this._latlng;

      // We need to have our drop point BEFORE adding the marker to the map
      // otherwise, it would create a flicker. (The marker would appear at final
      // location then move to its drop location, and you may be able to see it.)
      if (this.options.bounceOnAdd === true) {
        // backward compatibility
        if (typeof this.options.bounceOnAddDuration !== 'undefined') {
          this.options.bounceOnAddOptions.duration = this.options.bounceOnAddDuration;
        }

        // backward compatibility
        if (typeof this.options.bounceOnAddHeight !== 'undefined') {
          this.options.bounceOnAddOptions.height = this.options.bounceOnAddHeight;
        }

        this._dropPoint = this._getDropPoint(this.options.bounceOnAddOptions.height);
        this.setLatLng(this._toLatLng(this._dropPoint));
      }

      // Call leaflet original method to add the Marker to the map.
      originalOnAdd.call(this, map);

      if (this.options.bounceOnAdd === true) {
        this._bounce(this.options.bounceOnAddOptions, this.options.bounceOnAddCallback);
      }
    },

    onRemove: function (map) {
      clearInterval(this.intervalId);
      originalOnRemove.call(this, map);
    }
  });
})();
<commit_msg>Add an _ to intervalId<commit_after>/**
 * Copyright (C) 2013 Maxime Hadjinlian <maxime.hadjinlian@gmail.com>
 * All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

(function () {

  // Retain the value of the original onAdd and onRemove functions
  var originalOnAdd = L.Marker.prototype.onAdd;
  var originalOnRemove = L.Marker.prototype.onRemove;

  // Add bounceonAdd options
  L.Marker.mergeOptions({
    bounceOnAdd: false,
    bounceOnAddOptions: {
      duration: 1000,
      height: -1
    },
    bounceOnAddCallback: function() {},
  });

  L.Marker.include({

    _toPoint: function (latlng) {
      return this._map.latLngToContainerPoint(latlng);
    },
    _toLatLng: function (point) {
      return this._map.containerPointToLatLng(point);
    },

    _motionStep: function (opts) {
      var self = this;

      var start = new Date();
      self._intervalId = setInterval(function () {
        var timePassed = new Date() - start;
        var progress = timePassed / opts.duration;
        if (progress > 1) {
          progress = 1;
        }
        var delta = opts.delta(progress);
        opts.step(delta);
        if (progress === 1) {
          opts.end();
          clearInterval(self._intervalId);
        }
      }, opts.delay || 10);
    },

    _bounceMotion: function (delta, duration, callback) {
      var original = L.latLng(this._origLatlng),
          start_y = this._dropPoint.y,
          start_x = this._dropPoint.x,
          distance = this._point.y - start_y;
      var self = this;

      this._motionStep({
        delay: 10,
        duration: duration || 1000, // 1 sec by default
        delta: delta,
        step: function (delta) {
          self._dropPoint.y =
            start_y
            + (distance * delta)
            - (self._map.project(self._map.getCenter()).y - self._origMapCenter.y);
          self._dropPoint.x =
            start_x
            - (self._map.project(self._map.getCenter()).x - self._origMapCenter.x);
          self.setLatLng(self._toLatLng(self._dropPoint));
        },
        end: function () {
          self.setLatLng(original);
          if (typeof callback === "function") callback();
        }
      });
    },

    // Many thanks to Robert Penner for this function
    _easeOutBounce: function (pos) {
      if ((pos) < (1 / 2.75)) {
        return (7.5625 * pos * pos);
      } else if (pos < (2 / 2.75)) {
        return (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75);
      } else if (pos < (2.5 / 2.75)) {
        return (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375);
      } else {
        return (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375);
      }
    },

    // Bounce : if options.height in pixels is not specified, drop from top.
    // If options.duration is not specified animation is 1s long.
    bounce: function(options, endCallback) {
       this._origLatlng = this.getLatLng();
       this._bounce(options, endCallback);
    },

    _bounce: function (options, endCallback) {
      if (typeof options === "function") {
          endCallback = options;
          options = null;
      }
      options = options || {duration: 1000, height: -1};

      //backward compatibility
      if (typeof options === "number") {
        options.duration = arguments[0];
        options.height = arguments[1];
      }

      // Keep original map center
      this._origMapCenter = this._map.project(this._map.getCenter());
      this._dropPoint = this._getDropPoint(options.height);
      this._bounceMotion(this._easeOutBounce, options.duration, endCallback);
    },

    // This will get you a drop point given a height.
    // If no height is given, the top y will be used.
    _getDropPoint: function (height) {
      // Get current coordidates in pixel
      this._point = this._toPoint(this._origLatlng);
      var top_y;
      if (height === undefined || height < 0) {
        top_y = this._toPoint(this._map.getBounds()._northEast).y;
      } else {
        top_y = this._point.y - height;
      }
      return new L.Point(this._point.x, top_y);
    },

    onAdd: function (map) {
      this._map = map;
      // Keep original latitude and longitude
      this._origLatlng = this._latlng;

      // We need to have our drop point BEFORE adding the marker to the map
      // otherwise, it would create a flicker. (The marker would appear at final
      // location then move to its drop location, and you may be able to see it.)
      if (this.options.bounceOnAdd === true) {
        // backward compatibility
        if (typeof this.options.bounceOnAddDuration !== 'undefined') {
          this.options.bounceOnAddOptions.duration = this.options.bounceOnAddDuration;
        }

        // backward compatibility
        if (typeof this.options.bounceOnAddHeight !== 'undefined') {
          this.options.bounceOnAddOptions.height = this.options.bounceOnAddHeight;
        }

        this._dropPoint = this._getDropPoint(this.options.bounceOnAddOptions.height);
        this.setLatLng(this._toLatLng(this._dropPoint));
      }

      // Call leaflet original method to add the Marker to the map.
      originalOnAdd.call(this, map);

      if (this.options.bounceOnAdd === true) {
        this._bounce(this.options.bounceOnAddOptions, this.options.bounceOnAddCallback);
      }
    },

    onRemove: function (map) {
      clearInterval(this._intervalId);
      originalOnRemove.call(this, map);
    }
  });
})();
<|endoftext|>


<commit_before>function Box2DPhysics() {
    // import box2d types
    var b2Vec2 = Box2D.Common.Math.b2Vec2;
    var b2BodyDef = Box2D.Dynamics.b2BodyDef;
    var b2Body = Box2D.Dynamics.b2Body;
 	var	b2FixtureDef = Box2D.Dynamics.b2FixtureDef;
 	var b2Fixture = Box2D.Dynamics.b2Fixture;
    var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
    var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape;
    var b2MassData = Box2D.Collision.Shapes.b2MassData;
    var b2Listener = Box2D.Dynamics.b2ContactListener;

    var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;

    var physics = new Container();

    var world = new Box2D.Dynamics.b2World(new b2Vec2(0, 10), true);

    //add contact listener
    var listener = new b2Listener;

    function contactHandler(contact, isEnd) {
        var fixtureA = contact.GetFixtureA();
        var objA = fixtureA.GetBody().GetUserData();
        var fixtureB = contact.GetFixtureB();
        var objB = fixtureB.GetBody().GetUserData();
        if (!isEnd) {
           // console.log("AAAAAAAAAAAAA");
            //objA.send({name:'collision'},kng.send);
            //objB.send({name:'collision'},kng.send);
           // console.log("BBBB");
        }
    }

    listener.BeginContact = function(contact) {
        contactHandler(contact, false);
    }

    listener.EndContact = function(contact) {
        contactHandler(contact, true);
    }

    listener.PostSolve = function(contact, impulse) {
    }

    listener.PreSolve = function(contact, oldManifold) {
    }

    world.SetContactListener(listener);

    var fixDef = new b2FixtureDef;
    fixDef.density = 1.0;
    fixDef.friction = 0.5;
    fixDef.restitution = 0.7;

    function DEBUG() {
        var debugDraw = new b2DebugDraw();
        debugDraw.SetSprite(document.getElementById("canvas").getContext("2d"));
        debugDraw.SetDrawScale(20.0);
        debugDraw.SetFillAlpha(0.5);
        debugDraw.SetLineThickness(0.0);
        debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
        world.SetDebugDraw(debugDraw);
        physics.toString = function(){return 'box2d'};
    };

    DEBUG();

    var SCALE_POS = 1/20.0;
    var SCALE_VEL = 1;

    physics.update = function() {

        this.each(function(data) {
            var m = data.model();
            var nm = data.model(1);
            var vx = m.vx * SCALE_VEL;
            var vy = m.vy * SCALE_VEL;
            var pos = data.body.GetPosition();
            nm.x = (pos.x / SCALE_POS) - m.w/2;
            nm.y = (pos.y / SCALE_POS) - m.h/2;
            nm.rotation = data.body.GetAngle() / (Math.PI * 2) * 360.0;
            //var vel = data.body.GetLinearVelocity();
            //nm.vx = vel.x; nm.vy = vel.y;
            //data.body.SetLinearVelocity(new b2Vec2(vx, vy));
        });
        this.send('update');
        this.send('move');
        this.send('update');
        this.each(function(data) {
            var m = data.model();
            var nm = data.model(1);
            var vx = m.vx * SCALE_VEL;
            var vy = m.vy * SCALE_VEL;
            // primitive checksum calculation (it's lame, I know ;)
            var vsum = (~~(vx * 100)) + ';' + (~~(vy * 100)) + ';' + (~~(vx * 20)) + ';' + (~~(vy * 20));

            if (vsum != data.vsum) // if velocity has changed in the model...
                data.body.SetLinearVelocity(new b2Vec2(vx, vy)); // ...update box2d
            data.vsum = vsum;

            data.body.SetActive(m.active);
        });

        world.Step(1 / 30, 10, 10);
        world.DrawDebugData();

    }

    physics.onAdd = function(data) {

        // get parameters from the model
        var m = data.model();
        var vx = m.vx * SCALE_VEL;
        var vy = m.vy * SCALE_VEL;
        var x = (m.x + m.w/2) * SCALE_POS;
        var y = (m.y + m.h/2) * SCALE_POS;

        // create body def
        var bodyDef = new b2BodyDef;
        var g = m.gravity;
        if (m.static) {
            bodyDef.type = b2Body.b2_staticBody
        } else
            bodyDef.type = g == 0? b2Body.b2_cinematicBody : b2Body.b2_dynamicBody;
        bodyDef.userData = data.model.obj;

        if (m.rotation)
            bodyDef.angle = m.rotation;

        // create object' shape
        if (m.shape=='rect') {
            fixDef.shape = new b2PolygonShape;
            fixDef.shape.SetAsBox(m.w * SCALE_POS/2, m.h * SCALE_POS/2);
        } else {
            fixDef.shape = new b2CircleShape(m.w*SCALE_POS/2);
        }

        // create body
        var body = world.CreateBody(bodyDef);
        body.CreateFixture(fixDef);

        // set body position and velocity
        body.SetLinearVelocity(new b2Vec2(vx,vy));
        body.SetPosition(new b2Vec2(x, y))

        // remember the body
        data.body = body;
    };

    physics.onRemove = function(data) {
         console.log("--------REMOVE");
         world.DestroyBody(data.body);
    }

    return physics;
}

<commit_msg>enabling collisions\<commit_after>function Box2DPhysics() {
    // import box2d types
    var b2Vec2 = Box2D.Common.Math.b2Vec2;
    var b2BodyDef = Box2D.Dynamics.b2BodyDef;
    var b2Body = Box2D.Dynamics.b2Body;
 	var	b2FixtureDef = Box2D.Dynamics.b2FixtureDef;
 	var b2Fixture = Box2D.Dynamics.b2Fixture;
    var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
    var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape;
    var b2MassData = Box2D.Collision.Shapes.b2MassData;
    var b2Listener = Box2D.Dynamics.b2ContactListener;

    var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;

    var physics = new Container();

    var world = new Box2D.Dynamics.b2World(new b2Vec2(0, 10), true);

    //add contact listener
    var listener = new b2Listener;

    function contactHandler(contact, isEnd) {
        var fixtureA = contact.GetFixtureA();
        var objA = fixtureA.GetBody().GetUserData();
        var fixtureB = contact.GetFixtureB();
        var objB = fixtureB.GetBody().GetUserData();
        if (!isEnd) {
           // console.log("AAAAAAAAAAAAA");
            objA.send({name:'collision', target:objB},kng.send);
            objB.send({name:'collision', target:objA},kng.send);
           // console.log("BBBB");
        }
    }

    listener.BeginContact = function(contact) {
        contactHandler(contact, false);
    }

    listener.EndContact = function(contact) {
        contactHandler(contact, true);
    }

    listener.PostSolve = function(contact, impulse) {
    }

    listener.PreSolve = function(contact, oldManifold) {
    }

    world.SetContactListener(listener);

    var fixDef = new b2FixtureDef;
    fixDef.density = 1.0;
    fixDef.friction = 0.5;
    fixDef.restitution = 0.7;

    function DEBUG() {
        var debugDraw = new b2DebugDraw();
        debugDraw.SetSprite(document.getElementById("canvas").getContext("2d"));
        debugDraw.SetDrawScale(20.0);
        debugDraw.SetFillAlpha(0.5);
        debugDraw.SetLineThickness(0.0);
        debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
        world.SetDebugDraw(debugDraw);
        physics.toString = function(){return 'box2d'};
    };

    DEBUG();

    var SCALE_POS = 1/20.0;
    var SCALE_VEL = 1;

    physics.update = function() {

        this.each(function(data) {
            var m = data.model();
            var nm = data.model(1);
            var vx = m.vx * SCALE_VEL;
            var vy = m.vy * SCALE_VEL;
            var pos = data.body.GetPosition();
            nm.x = (pos.x / SCALE_POS) - m.w/2;
            nm.y = (pos.y / SCALE_POS) - m.h/2;
            nm.rotation = data.body.GetAngle() / (Math.PI * 2) * 360.0;
            //var vel = data.body.GetLinearVelocity();
            //nm.vx = vel.x; nm.vy = vel.y;
            //data.body.SetLinearVelocity(new b2Vec2(vx, vy));
        });
        this.send('update');
        this.send('move');
        this.send('update');
        this.each(function(data) {
            var m = data.model();
            var nm = data.model(1);
            var vx = m.vx * SCALE_VEL;
            var vy = m.vy * SCALE_VEL;
            // primitive checksum calculation (it's lame, I know ;)
            var vsum = (~~(vx * 100)) + ';' + (~~(vy * 100)) + ';' + (~~(vx * 20)) + ';' + (~~(vy * 20));

            if (vsum != data.vsum) // if velocity has changed in the model...
                data.body.SetLinearVelocity(new b2Vec2(vx, vy)); // ...update box2d
            data.vsum = vsum;

            data.body.SetActive(m.active);
        });

        world.Step(1 / 30, 10, 10);
        world.DrawDebugData();

    }

    physics.onAdd = function(data) {

        // get parameters from the model
        var m = data.model();
        var vx = m.vx * SCALE_VEL;
        var vy = m.vy * SCALE_VEL;
        var x = (m.x + m.w/2) * SCALE_POS;
        var y = (m.y + m.h/2) * SCALE_POS;

        // create body def
        var bodyDef = new b2BodyDef;
        var g = m.gravity;
        if (m.static) {
            bodyDef.type = b2Body.b2_staticBody
        } else
            bodyDef.type = g == 0? b2Body.b2_cinematicBody : b2Body.b2_dynamicBody;
        bodyDef.userData = data.model.obj;

        if (m.rotation)
            bodyDef.angle = m.rotation;

        // create object' shape
        if (m.shape=='rect') {
            fixDef.shape = new b2PolygonShape;
            fixDef.shape.SetAsBox(m.w * SCALE_POS/2, m.h * SCALE_POS/2);
        } else {
            fixDef.shape = new b2CircleShape(m.w*SCALE_POS/2);
        }

        // create body
        var body = world.CreateBody(bodyDef);
        body.CreateFixture(fixDef);

        // set body position and velocity
        body.SetLinearVelocity(new b2Vec2(vx,vy));
        body.SetPosition(new b2Vec2(x, y))

        // remember the body
        data.body = body;
    };

    physics.onRemove = function(data) {
         console.log("--------REMOVE");
         world.DestroyBody(data.body);
    }

    return physics;
}

<|endoftext|>


<commit_before>var fs = require('fs');
var exec = require('child_process').exec;

var wget = require('wget');

var common = require('./common');

fs.readFile(common.pathToConfig, 'utf8', main);

function main(err, configFile) {
    if(err) throw err;

    var config = JSON.parse(configFile);

    var bar = common.makeBar(
        'Downloading shapefiles: [:bar] :current/:total',
        [config.resolutions, config.vectors]
    );

    function unzip(r, v) {
        return [
            'unzip',
            common.wgetDir + common.srcPrefix + common.bn(r, v.src, 'zip'),
            '-d', common.wgetDir
        ].join(' ');
    }

    config.resolutions.forEach(function(r) {
        config.vectors.forEach(function(v) {

            var url = [
                    common.urlBase,
                    r, 'm/', v.type + '/',
                    common.srcPrefix,
                    common.bn(r, v.src, 'zip')
                ].join(''),
                out = [
                    common.wgetDir,
                    common.srcPrefix,
                    common.bn(r, v.src, 'zip')
                ].join('');

            var download = wget.download(url, out, {});

            download.on('error', function(error) {
                console.log(error);
            });

            download.on('end', function(output) {
                bar.tick();
                exec(unzip(r, v));
            });

        });
    });
}
<commit_msg>bin: improve wget<commit_after>var fs = require('fs');
var exec = require('child_process').exec;

var wget = require('wget');

var common = require('./common');

fs.readFile(common.pathToConfig, 'utf8', main);

function main(err, configFile) {
    if(err) throw err;

    var config = JSON.parse(configFile);

    var bar = common.makeBar(
        'Downloading shapefiles: [:bar] :current/:total',
        [config.resolutions, config.vectors]
    );

    function unzip(r, v) {
        return [
            'unzip -o',
            common.wgetDir + common.srcPrefix + common.bn(r, v.src, 'zip'),
            '-d', common.wgetDir
        ].join(' ');
    }

    config.resolutions.forEach(function(r) {
        config.vectors.forEach(function(v) {

            var url = [
                    common.urlBase,
                    r, 'm/', v.type + '/',
                    common.srcPrefix,
                    common.bn(r, v.src, 'zip')
                ].join(''),
                out = [
                    common.wgetDir,
                    common.srcPrefix,
                    common.bn(r, v.src, 'zip')
                ].join('');

            var download = wget.download(url, out, {});

            download.on('error', function(err) {
                console.log(err);
            });

            download.on('end', function() {
                exec(unzip(r, v), function() {
                    bar.tick();
                    if(bar.complete) process.exit();
                });
            });
        });
    });
}
<|endoftext|>


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

let url;
const info = require('../package');
const chalk = require('chalk');
const opts = require('commander')
  .version(info.version)
  .arguments('<url>')
  .action((a) => { url = a; })
  .option('-q, --quality <ITAG>',
    'Video quality to download, default: highest')
  .option('-r, --range <INT>..<INT>',
    'Byte range to download, ie 10355705-12452856')
  .option('-b, --begin <INT>', 'Time to begin video, format by 1:30.123 and 1m30s')
  .option('-o, --output <FILE>', 'Save to file, template by {prop}, default: stdout or {title}')
  .option('--filter <STR>',
    'Can be video, videoonly, audio, audioonly',
    /^(video|audio)(only)?$/)
  .option('--filter-container <REGEXP>', 'Filter in format container')
  .option('--unfilter-container <REGEXP>', 'Filter out format container')
  .option('--filter-resolution <REGEXP>', 'Filter in format resolution')
  .option('--unfilter-resolution <REGEXP>', 'Filter out format resolution')
  .option('--filter-codecs <REGEXP>', 'Filter in format codecs')
  .option('--unfilter-codecs <REGEXP>', 'Filter out format codecs')
  .option('-i, --info', 'Print video info without downloading')
  .option('-j, --info-json', 'Print video info as JSON without downloading')
  .option('--print-url', 'Print direct download URL')
  .option('--no-cache', 'Skip file cache for html5player')
  .option('--debug', 'Print debug information')
  .parse(process.argv)
  ;

if (!url) {
  opts.outputHelp((help) => {
    return chalk.red('\n  url argument is required\n') + help;
  });
  process.exit(1);
}

const path         = require('path');
const fs           = require('fs');
const ytdl         = require('ytdl-core');
const homedir      = require('homedir');
const util         = require('../lib/util');

const label = chalk.bold.gray;

ytdl.cache.info.timeout = 0;
if (opts.cache !== false) {
  // Keep cache in file.
  const cachefile = path.resolve(homedir(), '.ytdl-cache.json');
  let cache = {};
  fs.readFile(cachefile, (err, contents) => {
    if (err) return;
    try {
      cache = JSON.parse(contents);
    } catch (err) {
      console.error(`Badly formatted cachefile (${cachefile}): ${err.message}`);
    }
  });

  ytdl.cache.sig.get = key => cache[key];
  ytdl.cache.sig.set = (key, value) => {
    cache[key] = value;
    fs.writeFile(cachefile,
      JSON.stringify(cache, null, 2), () => {});
  };
}

/**
 * Prints basic video information.
 *
 * @param {Object} info
 * @param {boolean} live
 */
const printVideoInfo = (info, live) => {
  console.log();
  console.log(label('title: ') + info.title);
  console.log(label('author: ') + info.author.name);
  console.log(label('avg rating: ') +
    info.player_response.videoDetails.averageRating);
  console.log(label('views: ') +
    info.player_response.videoDetails.viewCount);
  if (!live) {
    console.log(label('length: ') + util.toHumanTime(info.length_seconds));
  }
};

if (opts.infoJson) {
  ytdl.getInfo(url, { debug: opts.debug }, (err, info) => {
    if (err) {
      console.error(err.message);
      process.exit(1);
      return;
    }
    console.log(JSON.stringify(info));
  });
} else if (opts.info) {
  const cliff = require('cliff');
  ytdl.getInfo(url, { debug: opts.debug }, (err, info) => {
    if (err) {
      console.error(err.message);
      process.exit(1);
      return;
    }

    printVideoInfo(info, info.formats.some(f => f.live));

    const cols = [
      'itag',
      'container',
      'quality',
      'codecs',
      'bitrate',
      'audio bitrate'
    ];
    info.formats.forEach((format) => {
      format['quality'] = format.qualityLabel;
      format['bitrate'] = format.qualityLabel ?
        util.toHumanSize(format.bitrate) : null;
      format['audio bitrate'] = format.audioBitrate ?
        format.audioBitrate + 'KB' : null;
      cols.forEach((col) => {
        format[col] = format[col] || '';
      });
    });
    console.log(label('formats:'));
    const colors = ['green', 'blue', 'green', 'blue', 'green', 'blue'];
    console.log(cliff.stringifyObjectRows(info.formats, cols, colors));
  });

} else {
  let output = opts.output;
  let ext = (output || '').match(/(\.\w+)?$/)[1];

  if (output) {
    if (ext && !opts.quality && !opts.filterContainer) {
      opts.filterContainer = '^' + ext.slice(1) + '$';
    }
  } else if (process.stdout.isTTY) {
    output = '{title}';
  }

  const ytdlOptions = {};
  ytdlOptions.quality = /,/.test(opts.quality) ?
    opts.quality.split(',') : opts.quality;
  if (opts.range) {
    let s = opts.range.split('-');
    ytdlOptions.range = { start: s[0], end: s[1] };
  }
  ytdlOptions.begin = opts.begin;

  // Create filters.
  const filters = [];

  /**
   * @param {string} field
   * @param {string} regexpStr
   * @param {boolean|null} negated
   */
  const createFilter = (field, regexpStr, negated) => {
    let regexp;
    try {
      regexp = new RegExp(regexpStr, 'i');
    } catch (err) {
      console.error(err.message);
      process.exit(1);
    }

    filters.push(format => negated !== regexp.test(format[field]));
  };

  ['container', 'resolution:qualityLabel', 'encoding'].forEach((field) => {
    let [fieldName, fieldKey] = field.split(':');
    let optsKey = 'filter' + fieldName[0].toUpperCase() + fieldName.slice(1);
    if (opts[optsKey]) {
      createFilter(fieldKey, opts[optsKey], false);
    }

    optsKey = 'un' + optsKey;
    if (opts[optsKey]) {
      createFilter(fieldKey, opts[optsKey], true);
    }
  });

  // Support basic ytdl-core filters manually, so that other
  // cli filters are supported when used together.
  switch (opts.filter) {
    case 'video':
      filters.push(format => format.bitrate);
      break;

    case 'videoonly':
      filters.push(format => format.bitrate && !format.audioBitrate);
      break;

    case 'audio':
      filters.push(format => format.audioBitrate);
      break;

    case 'audioonly':
      filters.push(format => !format.bitrate && format.audioBitrate);
      break;
  }

  ytdlOptions.filter = (format) => {
    return filters.every(filter => filter(format));
  };

  if (opts.printUrl) {
    ytdl.getInfo(url, { debug: opts.debug }, (err, info) => {
      if (err) {
        console.error(err.message);
        process.exit(1);
        return;
      }
      let format = ytdl.chooseFormat(info.formats, ytdlOptions);
      if (format instanceof Error) {
        console.error(format.message);
        process.exit(1);
        return;
      }
      console.log(format.url);
    });

  } else {
    const readStream = ytdl(url, ytdlOptions);
    const stdoutMutable = process.stdout && process.stdout.cursorTo && process.stdout.clearLine;
    let isPlaylist = false;

    readStream.on('info', (info, format) => {
      if (!output) {
        readStream.pipe(process.stdout).on('error', (err) => {
          console.error(err.message);
          process.exit(1);
        });
        return;
      }

      output = util.tmpl(output, [info, format]);
      if (!ext && format.container) {
        output += '.' + format.container;
      }

      // Parses & sanitises output filename for any illegal characters
      let parsedOutput = path.parse(output);
      output = path.format({
        dir: parsedOutput.dir,
        base: parsedOutput.base,
      });

      readStream.pipe(fs.createWriteStream(output))
        .on('error', (err) => {
          console.error(err.message);
          process.exit(1);
        });

      isPlaylist = format.live || format.isHLS || format.isDashMPD;

      // Print information about the video if not streaming to stdout.
      printVideoInfo(info, isPlaylist);

      console.log(label('container: ') + format.container);
      console.log(label('quality: ') + format.qualityLabel);
      console.log(label('codecs: ') + format.codecs);
      if (!isPlaylist) { return; }

      const throttle = require('lodash.throttle');
      let dataRead = 0;
      const updateProgress = throttle(() => {
        process.stdout.cursorTo(0);
        process.stdout.clearLine(1);
        let line = label('size: ') + util.toHumanSize(dataRead);
        if (dataRead >= 1024) {
          line += ` (${dataRead} bytes)`;
        }
        process.stdout.write(line);
      }, 500);

      readStream.on('data', (data) => {
        dataRead += data.length;
        if (stdoutMutable) {
          updateProgress();
        }
      });

      readStream.on('end', () => {
        if (stdoutMutable) {
          updateProgress.flush();
          console.log();
        } else {
          console.log('\n' + label('downloaded: ') + util.toHumanSize(dataRead));
        }
      });
    });

    readStream.once('response', (res) => {
      if (!output || isPlaylist) { return; }

      // Print information about the format we're downloading.
      const size = parseInt(res.headers['content-length'], 10);
      console.log(label('size: ') + util.toHumanSize(size) +
                  ' (' + size +' bytes)');
      console.log(label('output: ') + output);
      console.log();
      if (!stdoutMutable) { return; }

      // Create progress bar.
      const bar = require('progress-bar').create(process.stdout, 50);
      const throttle = require('lodash.throttle');
      bar.format = '$bar; $percentage;%';

      let lastPercent = null;
      let updateBar = () => {
        let percent = dataRead / size;
        let newPercent = Math.floor(percent * 100);
        if (newPercent != lastPercent) {
          lastPercent = newPercent;
          bar.update(percent);
        }
      };
      let updateBarThrottled = throttle(updateBar, 100, { trailing: false });

      // Keep track of progress.
      let dataRead = 0;
      readStream.on('data', (data) => {
        dataRead += data.length;
        if (dataRead === size) {
          updateBar();
        } else {
          updateBarThrottled();
        }
      });

      readStream.on('end', () => {
        console.log();
      });
    });

    readStream.on('error', (err) => {
      console.error(err.message);
      process.exit(1);
    });

    process.on('SIGINT', () => {
      console.log();
      process.exit();
    });
  }
}
<commit_msg>fix: `--filter` works with new formats<commit_after>#!/usr/bin/env node

let url;
const info = require('../package');
const chalk = require('chalk');
const opts = require('commander')
  .version(info.version)
  .arguments('<url>')
  .action((a) => { url = a; })
  .option('-q, --quality <ITAG>',
    'Video quality to download, default: highest')
  .option('-r, --range <INT>..<INT>',
    'Byte range to download, ie 10355705-12452856')
  .option('-b, --begin <INT>', 'Time to begin video, format by 1:30.123 and 1m30s')
  .option('-o, --output <FILE>', 'Save to file, template by {prop}, default: stdout or {title}')
  .option('--filter <STR>',
    'Can be video, videoonly, audio, audioonly',
    /^(video|audio)(only)?$/)
  .option('--filter-container <REGEXP>', 'Filter in format container')
  .option('--unfilter-container <REGEXP>', 'Filter out format container')
  .option('--filter-resolution <REGEXP>', 'Filter in format resolution')
  .option('--unfilter-resolution <REGEXP>', 'Filter out format resolution')
  .option('--filter-codecs <REGEXP>', 'Filter in format codecs')
  .option('--unfilter-codecs <REGEXP>', 'Filter out format codecs')
  .option('-i, --info', 'Print video info without downloading')
  .option('-j, --info-json', 'Print video info as JSON without downloading')
  .option('--print-url', 'Print direct download URL')
  .option('--no-cache', 'Skip file cache for html5player')
  .option('--debug', 'Print debug information')
  .parse(process.argv)
  ;

if (!url) {
  opts.outputHelp((help) => {
    return chalk.red('\n  url argument is required\n') + help;
  });
  process.exit(1);
}

const path         = require('path');
const fs           = require('fs');
const ytdl         = require('ytdl-core');
const homedir      = require('homedir');
const util         = require('../lib/util');

const label = chalk.bold.gray;

ytdl.cache.info.timeout = 0;
if (opts.cache !== false) {
  // Keep cache in file.
  const cachefile = path.resolve(homedir(), '.ytdl-cache.json');
  let cache = {};
  fs.readFile(cachefile, (err, contents) => {
    if (err) return;
    try {
      cache = JSON.parse(contents);
    } catch (err) {
      console.error(`Badly formatted cachefile (${cachefile}): ${err.message}`);
    }
  });

  ytdl.cache.sig.get = key => cache[key];
  ytdl.cache.sig.set = (key, value) => {
    cache[key] = value;
    fs.writeFile(cachefile,
      JSON.stringify(cache, null, 2), () => {});
  };
}

/**
 * Prints basic video information.
 *
 * @param {Object} info
 * @param {boolean} live
 */
const printVideoInfo = (info, live) => {
  console.log();
  console.log(label('title: ') + info.title);
  console.log(label('author: ') + info.author.name);
  console.log(label('avg rating: ') +
    info.player_response.videoDetails.averageRating);
  console.log(label('views: ') +
    info.player_response.videoDetails.viewCount);
  if (!live) {
    console.log(label('length: ') + util.toHumanTime(info.length_seconds));
  }
};

if (opts.infoJson) {
  ytdl.getInfo(url, { debug: opts.debug }, (err, info) => {
    if (err) {
      console.error(err.message);
      process.exit(1);
      return;
    }
    console.log(JSON.stringify(info));
  });
} else if (opts.info) {
  const cliff = require('cliff');
  ytdl.getInfo(url, { debug: opts.debug }, (err, info) => {
    if (err) {
      console.error(err.message);
      process.exit(1);
      return;
    }

    printVideoInfo(info, info.formats.some(f => f.live));

    const cols = [
      'itag',
      'container',
      'quality',
      'codecs',
      'bitrate',
      'audio bitrate'
    ];
    info.formats.forEach((format) => {
      format['quality'] = format.qualityLabel;
      format['bitrate'] = format.qualityLabel ?
        util.toHumanSize(format.bitrate) : null;
      format['audio bitrate'] = format.audioBitrate ?
        format.audioBitrate + 'KB' : null;
      cols.forEach((col) => {
        format[col] = format[col] || '';
      });
    });
    console.log(label('formats:'));
    const colors = ['green', 'blue', 'green', 'blue', 'green', 'blue'];
    console.log(cliff.stringifyObjectRows(info.formats, cols, colors));
  });

} else {
  let output = opts.output;
  let ext = (output || '').match(/(\.\w+)?$/)[1];

  if (output) {
    if (ext && !opts.quality && !opts.filterContainer) {
      opts.filterContainer = '^' + ext.slice(1) + '$';
    }
  } else if (process.stdout.isTTY) {
    output = '{title}';
  }

  const ytdlOptions = {};
  ytdlOptions.quality = /,/.test(opts.quality) ?
    opts.quality.split(',') : opts.quality;
  if (opts.range) {
    let s = opts.range.split('-');
    ytdlOptions.range = { start: s[0], end: s[1] };
  }
  ytdlOptions.begin = opts.begin;

  // Create filters.
  const filters = [];

  /**
   * @param {string} field
   * @param {string} regexpStr
   * @param {boolean|null} negated
   */
  const createFilter = (field, regexpStr, negated) => {
    let regexp;
    try {
      regexp = new RegExp(regexpStr, 'i');
    } catch (err) {
      console.error(err.message);
      process.exit(1);
    }

    filters.push(format => negated !== regexp.test(format[field]));
  };

  ['container', 'resolution:qualityLabel', 'encoding'].forEach((field) => {
    let [fieldName, fieldKey] = field.split(':');
    let optsKey = 'filter' + fieldName[0].toUpperCase() + fieldName.slice(1);
    if (opts[optsKey]) {
      createFilter(fieldKey, opts[optsKey], false);
    }

    optsKey = 'un' + optsKey;
    if (opts[optsKey]) {
      createFilter(fieldKey, opts[optsKey], true);
    }
  });

  // Support basic ytdl-core filters manually, so that other
  // cli filters are supported when used together.
  const hasVideo = format => !!format.qualityLabel;
  const hasAudio = format => !!format.audioBitrate;
  switch (opts.filter) {
    case 'video':
      filters.push(hasVideo);
      break;

    case 'videoonly':
      filters.push(format => hasVideo(format) && !hasAudio(format));
      break;

    case 'audio':
      filters.push(hasAudio);
      break;

    case 'audioonly':
      filters.push(format => !hasVideo(format) && hasAudio(format));
      break;
  }

  ytdlOptions.filter = (format) => {
    return filters.every(filter => filter(format));
  };

  if (opts.printUrl) {
    ytdl.getInfo(url, { debug: opts.debug }, (err, info) => {
      if (err) {
        console.error(err.message);
        process.exit(1);
        return;
      }
      let format = ytdl.chooseFormat(info.formats, ytdlOptions);
      if (format instanceof Error) {
        console.error(format.message);
        process.exit(1);
        return;
      }
      console.log(format.url);
    });

  } else {
    const readStream = ytdl(url, ytdlOptions);
    const stdoutMutable = process.stdout && process.stdout.cursorTo && process.stdout.clearLine;
    let isPlaylist = false;

    readStream.on('info', (info, format) => {
      if (!output) {
        readStream.pipe(process.stdout).on('error', (err) => {
          console.error(err.message);
          process.exit(1);
        });
        return;
      }

      output = util.tmpl(output, [info, format]);
      if (!ext && format.container) {
        output += '.' + format.container;
      }

      // Parses & sanitises output filename for any illegal characters
      let parsedOutput = path.parse(output);
      output = path.format({
        dir: parsedOutput.dir,
        base: parsedOutput.base,
      });

      readStream.pipe(fs.createWriteStream(output))
        .on('error', (err) => {
          console.error(err.message);
          process.exit(1);
        });

      isPlaylist = format.live || format.isHLS || format.isDashMPD;

      // Print information about the video if not streaming to stdout.
      printVideoInfo(info, isPlaylist);

      console.log(label('container: ') + format.container);
      console.log(label('quality: ') + format.qualityLabel);
      console.log(label('codecs: ') + format.codecs);
      if (!isPlaylist) { return; }

      const throttle = require('lodash.throttle');
      let dataRead = 0;
      const updateProgress = throttle(() => {
        process.stdout.cursorTo(0);
        process.stdout.clearLine(1);
        let line = label('size: ') + util.toHumanSize(dataRead);
        if (dataRead >= 1024) {
          line += ` (${dataRead} bytes)`;
        }
        process.stdout.write(line);
      }, 500);

      readStream.on('data', (data) => {
        dataRead += data.length;
        if (stdoutMutable) {
          updateProgress();
        }
      });

      readStream.on('end', () => {
        if (stdoutMutable) {
          updateProgress.flush();
          console.log();
        } else {
          console.log('\n' + label('downloaded: ') + util.toHumanSize(dataRead));
        }
      });
    });

    readStream.once('response', (res) => {
      if (!output || isPlaylist) { return; }

      // Print information about the format we're downloading.
      const size = parseInt(res.headers['content-length'], 10);
      console.log(label('size: ') + util.toHumanSize(size) +
                  ' (' + size +' bytes)');
      console.log(label('output: ') + output);
      console.log();
      if (!stdoutMutable) { return; }

      // Create progress bar.
      const bar = require('progress-bar').create(process.stdout, 50);
      const throttle = require('lodash.throttle');
      bar.format = '$bar; $percentage;%';

      let lastPercent = null;
      let updateBar = () => {
        let percent = dataRead / size;
        let newPercent = Math.floor(percent * 100);
        if (newPercent != lastPercent) {
          lastPercent = newPercent;
          bar.update(percent);
        }
      };
      let updateBarThrottled = throttle(updateBar, 100, { trailing: false });

      // Keep track of progress.
      let dataRead = 0;
      readStream.on('data', (data) => {
        dataRead += data.length;
        if (dataRead === size) {
          updateBar();
        } else {
          updateBarThrottled();
        }
      });

      readStream.on('end', () => {
        console.log();
      });
    });

    readStream.on('error', (err) => {
      console.error(err.message);
      process.exit(1);
    });

    process.on('SIGINT', () => {
      console.log();
      process.exit();
    });
  }
}
<|endoftext|>


<commit_before>/**
 * Text
 * @author Tom
 */

/**
 * Loads dictionary for given language
 * @param {String} language
 */
function loadDictionary(language) {
        include(languageDictionaryPath + language + ".js");
}

var defaultLanguage = "en_US";
var languageDictionaryPath = isDefined("TextRoot") ? TextRoot : "texts";;
var json_locale_data = {}

var currentLanguage = null;

/**
 * Returns text from template for given key and params
 * @param {String} key
 * @param {String} ... params
 * @return {String} text
 */
function $T(key){
    if (json_locale_data['messages-js'] && json_locale_data['messages-js'][key]) {
        return json_locale_data['messages-js'][key][1];
    } else {
        return key;
    }
}

String.prototype.format = function() {
    var args = arguments;
    return this.replace(/{(\d+)}/g, function(match, number) {
        return typeof args[number] != 'undefined' ? args[number] : '{' + number + '}';
    });
};
<commit_msg>Update indico/htdocs/js/presentation/Ui/Text.js<commit_after>/**
 * Text
 * @author Tom
 */

/**
 * Loads dictionary for given language
 * @param {String} language
 */
function loadDictionary(language) {
        include(languageDictionaryPath + language + ".js");
}

var defaultLanguage = "en_US";
var languageDictionaryPath = isDefined("TextRoot") ? TextRoot : "texts";;
var json_locale_data = {}

var currentLanguage = null;

/**
 * Returns text from template for given key and params
 * @param {String} key
 * @param {String} ... params
 * @return {String} text
 */
function $T(key){
    if (json_locale_data[key]) {
        return json_locale_data[key][1];
    } else {
        return key;
    }
}

String.prototype.format = function() {
    var args = arguments;
    return this.replace(/{(\d+)}/g, function(match, number) {
        return typeof args[number] != 'undefined' ? args[number] : '{' + number + '}';
    });
};
<|endoftext|>


<commit_before>var assert = require('assert')
var base58check = require('bs58check')
var bcrypto = require('./crypto')
var ecdsa = require('./ecdsa')
var ecurve = require('ecurve')
var networks = require('./networks')
var randomBytes = require('randombytes')
var typeForce = require('typeforce')

var Address = require('./address')
var BigInteger = require('bigi')

function findNetworkByWIFVersion (version) {
  for (var networkName in networks) {
    var network = networks[networkName]

    if (network.wif === version) return network
  }

  assert(false, 'Unknown network')
}

function ECPair (d, Q, options) {
  options = options || {}

  var compressed = options.compressed === undefined ? true : options.compressed
  var network = options.network === undefined ? networks.bitcoin : options.network

  typeForce('Boolean', compressed)
  assert('pubKeyHash' in network, 'Unknown pubKeyHash constants for network')

  if (d) {
    assert(d.signum() > 0, 'Private key must be greater than 0')
    assert(d.compareTo(ECPair.curve.n) < 0, 'Private key must be less than the curve order')

    assert(!Q, 'Unexpected publicKey parameter')
    Q = ECPair.curve.G.multiply(d)

  // enforce Q is a public key if no private key given
  } else {
    typeForce('Point', Q)
  }

  this.compressed = compressed
  this.d = d
  this.Q = Q
  this.network = network
}

// Public access to secp256k1 curve
ECPair.curve = ecurve.getCurveByName('secp256k1')

ECPair.fromPublicKeyBuffer = function (buffer, network) {
  var Q = ecurve.Point.decodeFrom(ECPair.curve, buffer)

  return new ECPair(null, Q, {
    compressed: Q.compressed,
    network: network
  })
}

ECPair.fromWIF = function (string) {
  var payload = base58check.decode(string)
  var version = payload.readUInt8(0)
  var compressed

  if (payload.length === 34) {
    assert.strictEqual(payload[33], 0x01, 'Invalid compression flag')

    // truncate the version/compression bytes
    payload = payload.slice(1, -1)
    compressed = true

  // no compression flag
  } else {
    assert.equal(payload.length, 33, 'Invalid WIF payload length')

    // Truncate the version byte
    payload = payload.slice(1)
    compressed = false
  }

  var network = findNetworkByWIFVersion(version)
  var d = BigInteger.fromBuffer(payload)

  return new ECPair(d, null, {
    compressed: compressed,
    network: network
  })
}

ECPair.makeRandom = function (options) {
  options = options || {}

  var rng = options.rng || randomBytes
  var buffer = rng(32)
  typeForce('Buffer', buffer)
  assert.equal(buffer.length, 32, 'Expected 256-bit Buffer from RNG')

  var d = BigInteger.fromBuffer(buffer)
  d = d.mod(ECPair.curve.n)

  return new ECPair(d, null, options)
}

ECPair.prototype.toWIF = function () {
  assert(this.d, 'Missing private key')

  var bufferLen = this.compressed ? 34 : 33
  var buffer = new Buffer(bufferLen)

  buffer.writeUInt8(this.network.wif, 0)
  this.d.toBuffer(32).copy(buffer, 1)

  if (this.compressed) {
    buffer.writeUInt8(0x01, 33)
  }

  return base58check.encode(buffer)
}

ECPair.prototype.getAddress = function () {
  var pubKey = this.getPublicKeyBuffer()

  return new Address(bcrypto.hash160(pubKey), this.network.pubKeyHash)
}

ECPair.prototype.getPublicKeyBuffer = function () {
  return this.Q.getEncoded(this.compressed)
}

ECPair.prototype.sign = function (hash) {
  assert(this.d, 'Missing private key')

  return ecdsa.sign(ECPair.curve, hash, this.d)
}

ECPair.prototype.verify = function (hash, signature) {
  return ecdsa.verify(ECPair.curve, hash, signature, this.Q)
}

module.exports = ECPair
<commit_msg>ECPair: lazily calculate Q<commit_after>var assert = require('assert')
var base58check = require('bs58check')
var bcrypto = require('./crypto')
var ecdsa = require('./ecdsa')
var ecurve = require('ecurve')
var networks = require('./networks')
var randomBytes = require('randombytes')
var typeForce = require('typeforce')

var Address = require('./address')
var BigInteger = require('bigi')

function findNetworkByWIFVersion (version) {
  for (var networkName in networks) {
    var network = networks[networkName]

    if (network.wif === version) return network
  }

  assert(false, 'Unknown network')
}

function ECPair (d, Q, options) {
  options = options || {}

  var compressed = options.compressed === undefined ? true : options.compressed
  var network = options.network === undefined ? networks.bitcoin : options.network

  typeForce('Boolean', compressed)
  assert('pubKeyHash' in network, 'Unknown pubKeyHash constants for network')

  if (d) {
    assert(d.signum() > 0, 'Private key must be greater than 0')
    assert(d.compareTo(ECPair.curve.n) < 0, 'Private key must be less than the curve order')

    assert(!Q, 'Unexpected publicKey parameter')
    this.d = d

  // enforce Q is a public key if no private key given
  } else {
    typeForce('Point', Q)
    this.__Q = Q
  }

  this.compressed = compressed
  this.network = network
}

Object.defineProperty(ECPair.prototype, 'Q', {
  get: function() {
    if (!this.__Q && this.d) {
      this.__Q = ECPair.curve.G.multiply(this.d)
    }

    return this.__Q
  }
})

// Public access to secp256k1 curve
ECPair.curve = ecurve.getCurveByName('secp256k1')

ECPair.fromPublicKeyBuffer = function (buffer, network) {
  var Q = ecurve.Point.decodeFrom(ECPair.curve, buffer)

  return new ECPair(null, Q, {
    compressed: Q.compressed,
    network: network
  })
}

ECPair.fromWIF = function (string) {
  var payload = base58check.decode(string)
  var version = payload.readUInt8(0)
  var compressed

  if (payload.length === 34) {
    assert.strictEqual(payload[33], 0x01, 'Invalid compression flag')

    // truncate the version/compression bytes
    payload = payload.slice(1, -1)
    compressed = true

  // no compression flag
  } else {
    assert.equal(payload.length, 33, 'Invalid WIF payload length')

    // Truncate the version byte
    payload = payload.slice(1)
    compressed = false
  }

  var network = findNetworkByWIFVersion(version)
  var d = BigInteger.fromBuffer(payload)

  return new ECPair(d, null, {
    compressed: compressed,
    network: network
  })
}

ECPair.makeRandom = function (options) {
  options = options || {}

  var rng = options.rng || randomBytes
  var buffer = rng(32)
  typeForce('Buffer', buffer)
  assert.equal(buffer.length, 32, 'Expected 256-bit Buffer from RNG')

  var d = BigInteger.fromBuffer(buffer)
  d = d.mod(ECPair.curve.n)

  return new ECPair(d, null, options)
}

ECPair.prototype.toWIF = function () {
  assert(this.d, 'Missing private key')

  var bufferLen = this.compressed ? 34 : 33
  var buffer = new Buffer(bufferLen)

  buffer.writeUInt8(this.network.wif, 0)
  this.d.toBuffer(32).copy(buffer, 1)

  if (this.compressed) {
    buffer.writeUInt8(0x01, 33)
  }

  return base58check.encode(buffer)
}

ECPair.prototype.getAddress = function () {
  var pubKey = this.getPublicKeyBuffer()

  return new Address(bcrypto.hash160(pubKey), this.network.pubKeyHash)
}

ECPair.prototype.getPublicKeyBuffer = function () {
  return this.Q.getEncoded(this.compressed)
}

ECPair.prototype.sign = function (hash) {
  assert(this.d, 'Missing private key')

  return ecdsa.sign(ECPair.curve, hash, this.d)
}

ECPair.prototype.verify = function (hash, signature) {
  return ecdsa.verify(ECPair.curve, hash, signature, this.Q)
}

module.exports = ECPair
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. 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.

(function(scope, testing) {

  // PLACEHOLDER: Replace with something that works.
  scope.convertEffectInput = function(effectInput) {
    var placeholderProperty = 'left';
    var interpolation = scope.propertyInterpolation(placeholderProperty, '0px', '100px');
    return function(target, fraction) {
      if (fraction !== null) {
        scope.apply(target, placeholderProperty, interpolation(fraction));
      } else {
        scope.clear(target, placeholderProperty);
      }
    };
  };

})(webAnimations, testing);
<commit_msg>Started implementing the normalize() method.<commit_after>// Copyright 2014 Google Inc. 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.

(function(scope, testing) {

  // PLACEHOLDER: Replace with something that works.
  scope.convertEffectInput = function(effectInput) {
    // TODO: clone effectInput
    // TODO: normalize effectInput clone && space the keyframes by offsets

    // TODO: convert normalized effect to property specific keyframes
    // TODO: make interpolations from pairs of PSKs (like this v) and insert into a thing (data structure)
    var interpolation = scope.propertyInterpolation('left', '0px', '100px');
    return function(target, fraction) {
      // TODO: look up the interpolations in the thing that will apply at
      // fraction
      // TODO: apply them like this v
      scope.apply(target, 'left', interpolation(fraction));
    };
  };

  function normalize(effectInput) {
    if (!Array.isArray(effectInput) || effectInput.length < 2) {
        ;// TODO: Invalid input. Fail.
    }

    var effectInputCopy = [];
    function addKeyframe(originalKeyframe) {
      var keyframe = {};
      for (var member in originalKeyframe) {
        if (originalKeyframe.hasOwnProperty(member)) {
          var memberValue = originalKeyframe[member];
          // FIXME: If the value isn't a number or a string, this sets it to the empty string. Should do something better.
          if (typeof memberValue != 'number' && typeof memberValue != 'string')
            memberValue = "";
          keyframe[member] = memberValue;
        }
      }
      effectInputCopy.push(keyframe);
    }

    var everyFrameHasOffset = true;
    var looselySortedByOffset = true;
    var lastOffset = -Infinity;

    for (var i = 0; i < effectInput.length; i++) {
      var keyframeHasOffset = false;
      var offset = effectInput[i].offset;
      if (offset !== null && offset !== undefined) {
        if (typeof offset != 'number' || offset < 0 || offset > 1)
          continue; // NOTE: This doesn't quite match the spec. Fix?
        keyframeHasOffset = true;

        if (keyframeHasOffset) {
          if (offset < lastOffset)
            looselySortedByOffset = false;
          lastOffset = offset;
        }
      }
      everyFrameHasOffset = everyFrameHasOffset && keyframeHasOffset;
      if (effectInput[i].composite == 'add') {
        ;// TODO: Fail?
      }

      addKeyframe(effectInput[i]);

      // TODO: Check property value pairs (here or in addKeyframe). Convert dashed properties to CamelCase?
    }
    if (!looselySortedByOffset) {
      if (!everyFrameHasOffset)
        ; // TODO: Can't resolve. Fail.
      else
        ; // TODO: Sort them by offset.
    }
    // TODO: Check for partial keyframes?

    // TODO: Space the normalized keyframes

    return effectInputCopy;
  }

})(webAnimations, testing);
<|endoftext|>


<commit_before>/*
 CKEditor Addons
 */
CKEDITOR.define("confirmChanges", {});
CKEDITOR.define("validateText", {});
CKEDITOR.define("getTextHistory", {});

CKEDITOR.newCommandWithExecution = function (executionFunc) {
    return {
        modes: {wysiwyg: 1, source: 1},// This command works in both editing modes.
        editorFocus: false,// This command will not auto focus editor before execution.
        canUndo: false,// This command requires no undo snapshot.
        exec: executionFunc
    }
};

CKEDITOR.plugins.add("documentSaver", {
    init: function (editor) {
        var pluginName = "documentSaver";
        editor.documentSnapshot = editor.getData();
        editor.blurHandler = function (e) {
            if (e.editor.checkDirty()) {
                e.editor.openDialog(pluginName);
            }
        };
        editor.focusHandler = function (e) {
            e.removeListener();
            e.editor.on('blur', e.editor.blurHandler);
        };
        var switchToolbarCommandFunction = function (e) {
            var element = e.element;
            if (e.elementMode == 1) {
                e.execCommand("toolbarswitch");
            }
            for (var key in CKEDITOR.instances) {
                var editor = CKEDITOR.instances[key];
                if (element == editor.element) {
                    return editor;
                }
            }
        };

        editor.on('blur', editor.blurHandler);

        var confirmNoEvent = function (e, callback) {
            if (!callback) {
                e = switchToolbarCommandFunction(e);
            }
            CKEDITOR.fire("confirmChangesEvent", {callback: callback}, e);
            editor.documentSnapshot = e.getData();
            e.resetDirty();
            if (!callback) {
                e.removeListener('blur', e.blurHandler);
                e.focusManager.unlock();
                e.element.$.blur();
                e.focusManager.blur();
                e.on("focus", e.focusHandler);
            }
        };

        var confirmWithEvent = function (e) {
            e = switchToolbarCommandFunction(e);
            var callback = Imcms.Events.getCallback("TextEditorRedirect");
            CKEDITOR.fire("confirmChangesEvent", {callback: callback}, e);
        };
        var confirmCommandWithEvent = CKEDITOR.newCommandWithExecution(confirmWithEvent);
        editor.addCommand("confirmChanges", confirmCommandWithEvent);
        editor.ui.addButton('confirm', {
            label: 'Save all changes',
            command: "confirmChanges",
            icon: "images/ic_apply.png"
        });

        var confirmCommandNoEvent = CKEDITOR.newCommandWithExecution(confirmNoEvent);
        editor.addCommand("confirmChangesWithoutEvent", confirmCommandNoEvent);

        var cancelCommandFunction = function (e) {
            var newEditor = switchToolbarCommandFunction(e),
                hideCommand = function (e) {
                    setTimeout(function () {
                        e.removeListener('instanceReady', hideCommand);
                        e.setData(e.documentSnapshot);
                        e.removeListener('blur', e.blurHandler);
                        e.focusManager.unlock();
                        e.element.$.blur();
                        e.focusManager.blur();
                        e.on("focus", e.focusHandler);
                    }, 1);
                };
            if (newEditor != e) {
                newEditor.on('instanceReady', hideCommand.bind(null, newEditor));

            } else {
                hideCommand(e);
            }
        };
        var cancelCommandDefinition = CKEDITOR.newCommandWithExecution(
            Imcms.Events.getCallbackOr("TextEditorRedirect", cancelCommandFunction)
        );
        editor.addCommand("cancelChanges", cancelCommandDefinition);
        editor.ui.addButton('cancel', {
            label: 'Cancel all changes and restore document to previous state',
            command: "cancelChanges",
            icon: "images/ic_cancel.png"
        });

        var saveCommandDefinition = CKEDITOR.newCommandWithExecution(function (e) {
            var $button = $('.' + e.id).find('.cke_button__savedata_icon')
                .css({
                    backgroundImage: "url(" + CKEDITOR.basePath + "images/ic_loader.gif" + ")"
                });
            confirmNoEvent(e, function () {
                $button.css({
                    backgroundImage: "url(" + CKEDITOR.basePath + "images/ic_save.png" + ")"
                });
            });
        });
        editor.addCommand("saveChanges", saveCommandDefinition);
        editor.ui.addButton('saveData', {
            label: 'Save all changes',
            command: "saveChanges",
            icon: "images/ic_save.png"
        });
    }
});
CKEDITOR.dialog.add("documentSaver", function (e) {
    return {
        title: 'Save Dialog',
        width: 200,
        height: 25,
        onOk: function () {
            e.execCommand("confirmChanges");
        },
        onCancel: function () {
            e.execCommand("cancelChanges");
        },
        onHide: function () {
            setTimeout(function () {
                e.focusManager.unlock();
                e.element.$.blur();
                e.focusManager.blur();
                $(e.focusManager.currentActive).blur();
            }, 500);
        },
        contents: [
            {
                id: 'general',
                label: 'Settings',
                elements: [
                    {
                        type: 'html',
                        html: '
Save document?
'
                    }
                ]
            }
        ]
    };
});

CKEDITOR.defineToolbar = function (editor) {
    var prefix;

    if (editor.elementMode == 1) { // full-screen editor mode
        editor.config.maxToolbar = true;
        prefix = "max";

    } else {
        editor.config.maxToolbar = false;
        prefix = "min";
    }

    if (editor.element.data("contenttype") === "text") {
        return prefix + "PlainText";

    } else if (editor.element.data("contenttype") === "from-html") {
        return prefix + "TextToolbar";

    } else {
        return prefix + "HtmlToolbar";
    }
};

CKEDITOR.switchFormat = false;

CKEDITOR.plugins.add("switchFormatToHTML", {
    init: function (editor) {
        editor.ui.addButton('switchFormatToHTML', {
            label: 'Switch format to HTML',
            command: "switchFormat",
            icon: "images/switch-between-html-and-text-mode.png"
        });
    }
});

CKEDITOR.plugins.add("switchFormatToText", {
    init: function (editor) {
        editor.ui.addButton('switchFormatToText', {
            label: 'Switch format to text',
            command: "switchFormat",
            icon: "images/plain_text.png"
        });
    }
});

CKEDITOR.plugins.add("fileBrowser", {
    init: function (editor) {

        var onChooseFile = function () {
            Imcms.Editors.Content.showDialog({
                onApply: $.proxy(onFileChosen, this),
                onCancel: $.proxy(onFileChosen, this)
            });
            editor.focusManager.blur();
            editor.element.$.blur();
        };
        var onFileChosen = function (data) {
            if (data) {
                editor.insertHtml('
', 'unfiltered_html');
            }
            editor.focusManager.focus();
            editor.element.$.focus();
        };

        var openBrowserCommandDefinition = CKEDITOR.newCommandWithExecution(onChooseFile);
        editor.addCommand("openBrowser", openBrowserCommandDefinition);

        editor.ui.addButton('openBrowser', {
            label: 'Open Image Browser',
            command: "openBrowser",
            icon: "images/ic_images.png"
        });
    }
});

CKEDITOR.plugins.add("w3cValidator", {
    init: function (editor) {
        var w3cValidateCommand = function (e) {
            var $button = $('.' + e.id).find('.cke_button__w3cvalidate_icon')
                .css({
                    backgroundImage: "url(" + CKEDITOR.basePath + "images/ic_loader.gif" + ")"
                });
            //todo: Add message if content is invalid
            CKEDITOR.fire("validateText", {
                callback: function (data) {
                    $button.css({
                        backgroundImage: "url(" + CKEDITOR.basePath + (data.result ? "images/ic_valid.png" : "images/ic_invalid.png") + ")"
                    });

                    if (!data.result) {
                        $(e.element.$).data("w3cValidateData", data);
                        e.execCommand("w3cValidateDialog", data);
                    }
                }
            }, e);
        };
        var w3cValidateCommandDefinition = CKEDITOR.newCommandWithExecution(w3cValidateCommand);
        editor.addCommand("w3cValidate", w3cValidateCommandDefinition);
        editor.addCommand("w3cValidateDialog", new CKEDITOR.dialogCommand("w3cValidationResultDialog"));

        editor.ui.addButton('w3cValidate', {
            label: 'Validate Content over W3C',
            command: "w3cValidate",
            icon: "images/ic_w3c.png"
        });
    }
});
CKEDITOR.dialog.add("w3cValidationResultDialog", function (e) {
    var $wrapper = $("
"),
        $content = $("
").addClass("imcms-w3c-errors").appendTo($wrapper),
        data = $(e.element.$).data("w3cValidateData");

    $("
").append($("
").text("Validation Output: " + data.data.errors.length + " Errors")).appendTo($content);

    data.data.errors.forEach(function (item, pos) {
        var $container = $("
").addClass("imcms-w3c-error").appendTo($content),
            $errorMessage = $("
").text(pos + 1 + ". " + item.message.charAt(0).toUpperCase() + item.message.slice(1)).appendTo($container),
            $sourceContainer = $("
").appendTo($container),
            $source = $("").addClass("language-html").html(item.line + ": " + item.source.replace(/(<([^>]+)>)/ig, "")).appendTo($sourceContainer);

        Prism.highlightElement($source[0]);
    });

    return {
        title: 'Validation Result Dialog',
        width: 600,
        minHeight: 250,
        contents: [
            {
                id: 'w3cValidation',
                label: 'Validation',
                elements: [
                    {
                        type: 'html',
                        html: $("
").append($wrapper).html()
                    }
                ]
            }
        ]
    };
});

CKEDITOR.plugins.add("textHistory", {
    init: function (editor) {
        var textHistoryCommand = function (e) {
            var $button = $('.' + e.id).find('.cke_button__texthistory_icon')
                .css({
                    backgroundImage: "url(" + CKEDITOR.basePath + "images/ic_loader.gif" + ")"
                });
            //todo: Add message if content is invalid
            CKEDITOR.fire("getTextHistory", {
                callback: function (data) {
                    $button.css({
                        backgroundImage: "url(" + CKEDITOR.basePath + "images/ic_history.png" + ")"
                    });

                    $(e.element.$).data("textHistoryData", data);
                    e.execCommand("textHistoryDialog", data);
                }
            }, e);
        };
        var textHistoryCommandDefinition = CKEDITOR.newCommandWithExecution(textHistoryCommand);
        editor.addCommand("textHistory", textHistoryCommandDefinition);
        editor.addCommand("textHistoryDialog", new CKEDITOR.dialogCommand("textHistory"));

        editor.ui.addButton('textHistory', {
            label: 'Text History',
            command: "textHistory",
            icon: "images/ic_history.png"
        });
    }
});

CKEDITOR.dialog.add("textHistory", function (e) {
    var $wrapper = $("
").addClass("imcms-text-history"),
        $leftPanel = $("
").addClass("imcms-left-panel").appendTo($wrapper),

        $content = $("
").addClass("imcms-content")
            .css({
                "max-width": "600px",
                "float": "right"
            })
            .appendTo($wrapper),

        data = $(e.element.$).data("textHistoryData")
            .map(function (textHistoryData) {
                textHistoryData.modifiedDate = new Date(textHistoryData.modifiedDate);
                textHistoryData.type = (textHistoryData.type == "HTML")
                    ? "html"
                    : "from-html";
                return textHistoryData;
            })
            .sort(function (a, b) {
                return (a.modifiedDate > b.modifiedDate ? -1 : (a.modifiedDate == b.modifiedDate ? 0 : 1));
            }),

        groupedData = {},
        $selected = undefined,
        selectedItem,
        previousType;

    data.forEach(function (it) {
        var key = it.modifiedDate.format("dd/m/yy");

        if (!(key in groupedData)) {
            groupedData[key] = [];
        }

        groupedData[key].push(it);
    });

    var buttonsShowed = false;

    function addTextHistoryButton(text, onClick) {
        return $("<button>")
            .addClass("imcms-neutral")
            .css("float", "right")
            .html(text)
            .appendTo($wrapper)
            .click(onClick);
    }

    $.each(groupedData, function (key, list) {
        $("
").addClass("imcms-separator").text(key).appendTo($leftPanel);

        list.forEach(function (item) {
            $("
").appendTo($leftPanel)
                .append(item.modifiedDate.format("HH:MM:ss") + " | " + item.modifiedBy)
                .click(function () {
                    if (!buttonsShowed) {
                        addTextHistoryButton("As HTML", function () {
                            if (selectedItem.type !== "html") {
                                $content.html($content.text());
                                selectedItem.type = "html";
                            }
                        });
                        addTextHistoryButton("As Text", function () {
                            if (selectedItem.type === "html") {
                                $content.text($content.html());
                                selectedItem.type = "from-html";
                            }
                        });
                        buttonsShowed = true;
                    }

                    if ($selected) {
                        $selected.removeClass("selected");
                    }

                    var callFunc = (item.type === "html")
                        ? "html"
                        : "text";

                    $content[callFunc](item.text);
                    $selected = $(this).addClass("selected");
                    selectedItem = item;
                    previousType = item.type;
                });
        })
    });

    return {
        title: 'Text History Dialog',
        width: 600,
        height: 400,
        onOk: function () {
            if (selectedItem) {
                e.setData(""); // clear previous text
                var contentType = $(e.element.$).data("contenttype");

                var callFunc = (contentType === "html")
                    ? "insertHtml"
                    : "insertText";

                e[callFunc](selectedItem.text);

                if (selectedItem.type !== contentType) {
                    e.execCommand("switchFormat");
                }
            }
        },
        contents: [
            {
                id: 'textHistory',
                label: 'Text History',
                elements: [
                    {
                        type: 'html',
                        onLoad: function () {
                            $("#" + this.domId).append($wrapper)
                        },
                        html: ""
                    }
                ]
            }
        ]
    };
});<commit_msg>IMCMS-134 - Text History adjustments: - Button texts changed.<commit_after>/*
 CKEditor Addons
 */
CKEDITOR.define("confirmChanges", {});
CKEDITOR.define("validateText", {});
CKEDITOR.define("getTextHistory", {});

CKEDITOR.newCommandWithExecution = function (executionFunc) {
    return {
        modes: {wysiwyg: 1, source: 1},// This command works in both editing modes.
        editorFocus: false,// This command will not auto focus editor before execution.
        canUndo: false,// This command requires no undo snapshot.
        exec: executionFunc
    }
};

CKEDITOR.plugins.add("documentSaver", {
    init: function (editor) {
        var pluginName = "documentSaver";
        editor.documentSnapshot = editor.getData();
        editor.blurHandler = function (e) {
            if (e.editor.checkDirty()) {
                e.editor.openDialog(pluginName);
            }
        };
        editor.focusHandler = function (e) {
            e.removeListener();
            e.editor.on('blur', e.editor.blurHandler);
        };
        var switchToolbarCommandFunction = function (e) {
            var element = e.element;
            if (e.elementMode == 1) {
                e.execCommand("toolbarswitch");
            }
            for (var key in CKEDITOR.instances) {
                var editor = CKEDITOR.instances[key];
                if (element == editor.element) {
                    return editor;
                }
            }
        };

        editor.on('blur', editor.blurHandler);

        var confirmNoEvent = function (e, callback) {
            if (!callback) {
                e = switchToolbarCommandFunction(e);
            }
            CKEDITOR.fire("confirmChangesEvent", {callback: callback}, e);
            editor.documentSnapshot = e.getData();
            e.resetDirty();
            if (!callback) {
                e.removeListener('blur', e.blurHandler);
                e.focusManager.unlock();
                e.element.$.blur();
                e.focusManager.blur();
                e.on("focus", e.focusHandler);
            }
        };

        var confirmWithEvent = function (e) {
            e = switchToolbarCommandFunction(e);
            var callback = Imcms.Events.getCallback("TextEditorRedirect");
            CKEDITOR.fire("confirmChangesEvent", {callback: callback}, e);
        };
        var confirmCommandWithEvent = CKEDITOR.newCommandWithExecution(confirmWithEvent);
        editor.addCommand("confirmChanges", confirmCommandWithEvent);
        editor.ui.addButton('confirm', {
            label: 'Save all changes',
            command: "confirmChanges",
            icon: "images/ic_apply.png"
        });

        var confirmCommandNoEvent = CKEDITOR.newCommandWithExecution(confirmNoEvent);
        editor.addCommand("confirmChangesWithoutEvent", confirmCommandNoEvent);

        var cancelCommandFunction = function (e) {
            var newEditor = switchToolbarCommandFunction(e),
                hideCommand = function (e) {
                    setTimeout(function () {
                        e.removeListener('instanceReady', hideCommand);
                        e.setData(e.documentSnapshot);
                        e.removeListener('blur', e.blurHandler);
                        e.focusManager.unlock();
                        e.element.$.blur();
                        e.focusManager.blur();
                        e.on("focus", e.focusHandler);
                    }, 1);
                };
            if (newEditor != e) {
                newEditor.on('instanceReady', hideCommand.bind(null, newEditor));

            } else {
                hideCommand(e);
            }
        };
        var cancelCommandDefinition = CKEDITOR.newCommandWithExecution(
            Imcms.Events.getCallbackOr("TextEditorRedirect", cancelCommandFunction)
        );
        editor.addCommand("cancelChanges", cancelCommandDefinition);
        editor.ui.addButton('cancel', {
            label: 'Cancel all changes and restore document to previous state',
            command: "cancelChanges",
            icon: "images/ic_cancel.png"
        });

        var saveCommandDefinition = CKEDITOR.newCommandWithExecution(function (e) {
            var $button = $('.' + e.id).find('.cke_button__savedata_icon')
                .css({
                    backgroundImage: "url(" + CKEDITOR.basePath + "images/ic_loader.gif" + ")"
                });
            confirmNoEvent(e, function () {
                $button.css({
                    backgroundImage: "url(" + CKEDITOR.basePath + "images/ic_save.png" + ")"
                });
            });
        });
        editor.addCommand("saveChanges", saveCommandDefinition);
        editor.ui.addButton('saveData', {
            label: 'Save all changes',
            command: "saveChanges",
            icon: "images/ic_save.png"
        });
    }
});
CKEDITOR.dialog.add("documentSaver", function (e) {
    return {
        title: 'Save Dialog',
        width: 200,
        height: 25,
        onOk: function () {
            e.execCommand("confirmChanges");
        },
        onCancel: function () {
            e.execCommand("cancelChanges");
        },
        onHide: function () {
            setTimeout(function () {
                e.focusManager.unlock();
                e.element.$.blur();
                e.focusManager.blur();
                $(e.focusManager.currentActive).blur();
            }, 500);
        },
        contents: [
            {
                id: 'general',
                label: 'Settings',
                elements: [
                    {
                        type: 'html',
                        html: '
Save document?
'
                    }
                ]
            }
        ]
    };
});

CKEDITOR.defineToolbar = function (editor) {
    var prefix;

    if (editor.elementMode == 1) { // full-screen editor mode
        editor.config.maxToolbar = true;
        prefix = "max";

    } else {
        editor.config.maxToolbar = false;
        prefix = "min";
    }

    if (editor.element.data("contenttype") === "text") {
        return prefix + "PlainText";

    } else if (editor.element.data("contenttype") === "from-html") {
        return prefix + "TextToolbar";

    } else {
        return prefix + "HtmlToolbar";
    }
};

CKEDITOR.switchFormat = false;

CKEDITOR.plugins.add("switchFormatToHTML", {
    init: function (editor) {
        editor.ui.addButton('switchFormatToHTML', {
            label: 'Switch format to HTML',
            command: "switchFormat",
            icon: "images/switch-between-html-and-text-mode.png"
        });
    }
});

CKEDITOR.plugins.add("switchFormatToText", {
    init: function (editor) {
        editor.ui.addButton('switchFormatToText', {
            label: 'Switch format to text',
            command: "switchFormat",
            icon: "images/plain_text.png"
        });
    }
});

CKEDITOR.plugins.add("fileBrowser", {
    init: function (editor) {

        var onChooseFile = function () {
            Imcms.Editors.Content.showDialog({
                onApply: $.proxy(onFileChosen, this),
                onCancel: $.proxy(onFileChosen, this)
            });
            editor.focusManager.blur();
            editor.element.$.blur();
        };
        var onFileChosen = function (data) {
            if (data) {
                editor.insertHtml('
', 'unfiltered_html');
            }
            editor.focusManager.focus();
            editor.element.$.focus();
        };

        var openBrowserCommandDefinition = CKEDITOR.newCommandWithExecution(onChooseFile);
        editor.addCommand("openBrowser", openBrowserCommandDefinition);

        editor.ui.addButton('openBrowser', {
            label: 'Open Image Browser',
            command: "openBrowser",
            icon: "images/ic_images.png"
        });
    }
});

CKEDITOR.plugins.add("w3cValidator", {
    init: function (editor) {
        var w3cValidateCommand = function (e) {
            var $button = $('.' + e.id).find('.cke_button__w3cvalidate_icon')
                .css({
                    backgroundImage: "url(" + CKEDITOR.basePath + "images/ic_loader.gif" + ")"
                });
            //todo: Add message if content is invalid
            CKEDITOR.fire("validateText", {
                callback: function (data) {
                    $button.css({
                        backgroundImage: "url(" + CKEDITOR.basePath + (data.result ? "images/ic_valid.png" : "images/ic_invalid.png") + ")"
                    });

                    if (!data.result) {
                        $(e.element.$).data("w3cValidateData", data);
                        e.execCommand("w3cValidateDialog", data);
                    }
                }
            }, e);
        };
        var w3cValidateCommandDefinition = CKEDITOR.newCommandWithExecution(w3cValidateCommand);
        editor.addCommand("w3cValidate", w3cValidateCommandDefinition);
        editor.addCommand("w3cValidateDialog", new CKEDITOR.dialogCommand("w3cValidationResultDialog"));

        editor.ui.addButton('w3cValidate', {
            label: 'Validate Content over W3C',
            command: "w3cValidate",
            icon: "images/ic_w3c.png"
        });
    }
});
CKEDITOR.dialog.add("w3cValidationResultDialog", function (e) {
    var $wrapper = $("
"),
        $content = $("
").addClass("imcms-w3c-errors").appendTo($wrapper),
        data = $(e.element.$).data("w3cValidateData");

    $("
").append($("
").text("Validation Output: " + data.data.errors.length + " Errors")).appendTo($content);

    data.data.errors.forEach(function (item, pos) {
        var $container = $("
").addClass("imcms-w3c-error").appendTo($content),
            $errorMessage = $("
").text(pos + 1 + ". " + item.message.charAt(0).toUpperCase() + item.message.slice(1)).appendTo($container),
            $sourceContainer = $("
").appendTo($container),
            $source = $("").addClass("language-html").html(item.line + ": " + item.source.replace(/(<([^>]+)>)/ig, "")).appendTo($sourceContainer);

        Prism.highlightElement($source[0]);
    });

    return {
        title: 'Validation Result Dialog',
        width: 600,
        minHeight: 250,
        contents: [
            {
                id: 'w3cValidation',
                label: 'Validation',
                elements: [
                    {
                        type: 'html',
                        html: $("
").append($wrapper).html()
                    }
                ]
            }
        ]
    };
});

CKEDITOR.plugins.add("textHistory", {
    init: function (editor) {
        var textHistoryCommand = function (e) {
            var $button = $('.' + e.id).find('.cke_button__texthistory_icon')
                .css({
                    backgroundImage: "url(" + CKEDITOR.basePath + "images/ic_loader.gif" + ")"
                });
            //todo: Add message if content is invalid
            CKEDITOR.fire("getTextHistory", {
                callback: function (data) {
                    $button.css({
                        backgroundImage: "url(" + CKEDITOR.basePath + "images/ic_history.png" + ")"
                    });

                    $(e.element.$).data("textHistoryData", data);
                    e.execCommand("textHistoryDialog", data);
                }
            }, e);
        };
        var textHistoryCommandDefinition = CKEDITOR.newCommandWithExecution(textHistoryCommand);
        editor.addCommand("textHistory", textHistoryCommandDefinition);
        editor.addCommand("textHistoryDialog", new CKEDITOR.dialogCommand("textHistory"));

        editor.ui.addButton('textHistory', {
            label: 'Text History',
            command: "textHistory",
            icon: "images/ic_history.png"
        });
    }
});

CKEDITOR.dialog.add("textHistory", function (e) {
    var $wrapper = $("
").addClass("imcms-text-history"),
        $leftPanel = $("
").addClass("imcms-left-panel").appendTo($wrapper),

        $content = $("
").addClass("imcms-content")
            .css({
                "max-width": "600px",
                "float": "right"
            })
            .appendTo($wrapper),

        data = $(e.element.$).data("textHistoryData")
            .map(function (textHistoryData) {
                textHistoryData.modifiedDate = new Date(textHistoryData.modifiedDate);
                textHistoryData.type = (textHistoryData.type == "HTML")
                    ? "html"
                    : "from-html";
                return textHistoryData;
            })
            .sort(function (a, b) {
                return (a.modifiedDate > b.modifiedDate ? -1 : (a.modifiedDate == b.modifiedDate ? 0 : 1));
            }),

        groupedData = {},
        $selected = undefined,
        selectedItem,
        previousType;

    data.forEach(function (it) {
        var key = it.modifiedDate.format("dd/m/yy");

        if (!(key in groupedData)) {
            groupedData[key] = [];
        }

        groupedData[key].push(it);
    });

    var buttonsShowed = false;

    function addTextHistoryButton(text, onClick) {
        return $("<button>")
            .addClass("imcms-neutral")
            .css("float", "right")
            .html(text)
            .appendTo($wrapper)
            .click(onClick);
    }

    $.each(groupedData, function (key, list) {
        $("
").addClass("imcms-separator").text(key).appendTo($leftPanel);

        list.forEach(function (item) {
            $("
").appendTo($leftPanel)
                .append(item.modifiedDate.format("HH:MM:ss") + " | " + item.modifiedBy)
                .click(function () {
                    if (!buttonsShowed) {
                        addTextHistoryButton("View Page", function () {
                            if (selectedItem.type !== "html") {
                                $content.html($content.text());
                                selectedItem.type = "html";
                            }
                        });
                        addTextHistoryButton("View Source", function () {
                            if (selectedItem.type === "html") {
                                $content.text($content.html());
                                selectedItem.type = "from-html";
                            }
                        });
                        buttonsShowed = true;
                    }

                    if ($selected) {
                        $selected.removeClass("selected");
                    }

                    var callFunc = (item.type === "html")
                        ? "html"
                        : "text";

                    $content[callFunc](item.text);
                    $selected = $(this).addClass("selected");
                    selectedItem = item;
                    previousType = item.type;
                });
        })
    });

    return {
        title: 'Text History Dialog',
        width: 600,
        height: 400,
        contents: [
            {
                id: 'textHistory',
                label: 'Text History',
                elements: [
                    {
                        type: 'html',
                        onLoad: function () {
                            $("#" + this.domId).append($wrapper)
                        },
                        html: ""
                    }
                ]
            }
        ],
        buttons: [
            {
                id: "text history OK button",
                type: "button",
                label: "Write to textfield",
                title: "Write to textfield",
                "class":"cke_dialog_ui_button_ok",
                disabled: false,
                onClick: function () {
                    if (selectedItem) {
                        e.setData(""); // clear previous text
                        var contentType = $(e.element.$).data("contenttype");

                        var callFunc = (contentType === "html")
                            ? "insertHtml"
                            : "insertText";

                        e[callFunc](selectedItem.text);

                        if (selectedItem.type !== contentType) {
                            e.execCommand("switchFormat");
                        }
                    }
                }
            },
            CKEDITOR.dialog.cancelButton
        ]
    };
});<|endoftext|>