<commit_before>//================================================================
// RS_BuildRect.js
// ---------------------------------------------------------------
// The MIT License
// Copyright (c) 2019 biud436
// ---------------------------------------------------------------
// Free for commercial and non commercial use.
//================================================================
/*:
 * @plugindesc <RS_BuildRect>
 * @author biud436
 *
 * @param alpha
 * @type number
 * @desc Specify the alpha value.
 * @default 0.7
 * @decimals 1
 *
 * @param color
 * @desc Specify the color value
 * @default 0xff0000
 *
 * @help
 * This plugin allows you to draw the rectangle on your screen and
 * you can export a json file to your data folder.
 *
 * Notice that this plugin can use only in PC platform.
 *
 * To save the json file, please press keys Ctrl + F7!
 *
 * ================================================================
 * Change Log
 * ================================================================
 * 2019.10.09 (v1.0.0) - First Release.
 */

var Imported = Imported || {};
Imported.RS_BuildRect = true;

var RS = RS || {};
RS.BuildRect = RS.BuildRect || {};

(function($) {

    "use strict";

    var parameters = $plugins.filter(function (i) {
      return i.description.contains('<RS_BuildRect>');
    });

    parameters = (parameters.length > 0) && parameters[0].parameters;

    $.Params = {};
    $.Params.rectColor = Number(parameters['color'] || 0xff0000);
    $.Params.rectAlpha = Number(parameters['alpha'] || 0.7);

    class RFactory extends Sprite {

        constructor() {
            super();
            this.clearFlags();
            this.createGraphics();
            this.on('removed', this.terminate, this);
        }

        clearFlags() {
            this._isReady = false;
            this._data = [];
            this._isMouseMovement = false;
            this._endX = 0;
            this._endY = 0;
            this._startX = 0;
            this._startY = 0;

            this._multiLayer = new PIXI.Sprite();
            this.addChild(this._multiLayer);

            this.createPrimitive();
        }

        createPrimitive() {
            this._primitive = new Rectangle(0, 0, 0, 0);
        };

        createGraphics() {
            this._canvas = new PIXI.Graphics();
            this._canvas.alpha = $.Params.rectAlpha;
            this.addChild(this._canvas);

            if(this._canvas) {
                this._isReady = true;
            }
        }

        createTextLayer(...args) {
            const style = new PIXI.TextStyle({
                fontFamily: 'Arial',
                fontSize: 20,
                fill: '#ffffff',
                stroke: '#000000',
                strokeThickness: 2,
                wordWrap: true,
                wordWrapWidth: 200
            });
            if(this._textLayer) {
                this.removeChild(this._textLayer);
            }
            let text = '';
            const argc = args.length;

            if(argc === 1) {
                if(args[0] instanceof PIXI.Rectangle) {
                    const rect = args[0];
                    text = `x : ${rect.x}, y : ${rect.y}, width : ${rect.width}, height : ${rect.height}`;
                } else {
                    text = `${args[0]}`;
                }
            } else if(argc === 4) {
                text = `x : ${args[0]}, y : ${args[1]}, width : ${args[2]}, height : ${args[3]}`;
            }

            this._textLayer = new PIXI.Text(text.split(", ").join("\r\n"), style);
            this._textLayer.x = 0;
            this._textLayer.y = 0;
            this.addChild(this._textLayer);
        }

        drawTempRect(x, y, width, height, color = $.Params.rectColor) {

            if(!this._isReady) return false;

            if(width < 0) {
                width = 1;
            }

            if(height < 0) {
                height = 0;
            }

            if(typeof color !== 'number') {
                color = $.Params.rectColor;
            }

            const canvas = this._canvas;

            canvas.beginFill(color);
            canvas.drawRect(x, y, width, height);
            canvas.endFill();

        }

        /**
         *
         * @param {PIXI.Rectangle} rect
         * @param {Number} color
         */
        addRect(rect, color) {

            if(!this._isReady) return false;

            if(!(rect instanceof PIXI.Rectangle)) {
                rect = new PIXI.Rectangle(0, 0, 1, 1);
            }

            if(rect.width < 0) {
                rect.width = 1;
            }

            if(rect.height < 0) {
                rect.height = 0;
            }

            const canvas = new PIXI.Graphics();
            canvas.alpha = $.Params.rectAlpha;

            if(typeof color !== 'number') {
                color = $.Params.rectColor;
            }

            canvas.beginFill(color);
            canvas.drawRect(rect.x, rect.y, rect.width, rect.height);
            canvas.endFill();

            this._multiLayer.addChild(canvas);

            this._data.push(rect.clone());

        }

        clear() {
            const canvas = this._canvas;
            canvas.clear();
        }

        update() {
            super.update();
        }

        terminate() {
            if(this._isReady && this._canvas) {
                this.removeChild(this._canvas);
                this._canvas = null;
                this._isReady = false;
            }
        }

        /**
         *
         * @param {MouseEvent} event
         */
        onMouseDown(event) {

            this._isMouseMovement = true;

            const x = Graphics.pageToCanvasX(event.clientX);
            const y = Graphics.pageToCanvasY(event.clientY);

            if(!this._primitive) {
                this.createPrimitive();
            }

            this._startX = x;
            this._startY = y;

            this.clear();

        }

        /**
         *
         * @param {MouseEvent} event
         */
        onFlush(event) {
            if(!this._primitive) {
                this.createPrimitive();
            }

            let endX = Graphics.pageToCanvasX(event.clientX);
            let endY = Graphics.pageToCanvasY(event.clientY);
            const startX = this._startX;
            const startY = this._startY;

            this._primitive.x = Math.min(startX, endX);
            this._primitive.y = Math.min(startY, endY);
            this._primitive.width = Math.max(startX, endX) - this._primitive.x;
            this._primitive.height = Math.max(startY, endY) - this._primitive.y;

            const d = Math.sqrt(Math.pow(this._primitive.width - this._primitive.x, 2) + Math.pow(this._primitive.height - this._primitive.y, 2));

            this.createTextLayer(this._primitive);

            return (d >= 5) ? true : false;

        }

        /**
         *
         * @param {MouseEvent} event
         */
        onMouseMove(event) {
            if( this._isMouseMovement) {

                if(this.onFlush(event)) {
                    this.clear();

                    this.drawTempRect(
                        this._primitive.x,
                        this._primitive.y,
                        this._primitive.width,
                        this._primitive.height,
                        $.Params.rectColor);
                }

            }
        }

        /**
         *
         * @param {MouseEvent} event
         */
        onMouseUp(event) {

            if(this.onFlush(event)) {
                this.clear();
                this.addRect(this._primitive, $.Params.rectColor);
                this._isMouseMovement = false;
            }

        }

        onSave() {
            const fs = require('fs');
            const path = require('path');
            const mainDir = path.join(process.mainModule.filename, "..");
            const retPath = path.join(mainDir, "data", "rect.json")
            const retData = JSON.stringify(this._data, null, "\t");

            let chooser = document.createElement('input');
            chooser.style.display = "none";
            chooser.id = "fileDialog";
            chooser.type = "file";
            chooser.nwsaveas = "rect.json";
            chooser.setAttribute('nwworkingdir', mainDir);

            chooser.addEventListener("change", () => {
                const filename = chooser.value;
                fs.writeFile(filename, retData, err => {
                    if(err) {
                        console.warn(`RS_BuildRect error! : ${err.message}`);
                    }
                    this.createTextLayer(`Successfully saved!! \n${filename}`);

                    this._multiLayer.removeChildren();
                    this._data = [];
                    this._primitive = new Rectangle(0, 0, 1, 1);

                    setTimeout(() => {
                        this.removeChild(this._textLayer);
                    }, 1000);

                });
            });

            chooser.click();

        };

        /**
         *
         * @param {KeyboardEvent} event
         */
        onKeyDown(event) {
            const keycode = event.keyCode || event.which;
            if(keycode == 118 && event.ctrlKey) {
                this.onSave();
            }
        }

    }

    let alias_Scene_Map_start = Scene_Map.prototype.start;
    Scene_Map.prototype.start = function() {
        alias_Scene_Map_start.call(this);
        this._rectFactory = new RFactory();
        this.addChild(this._rectFactory);

        document.body.addEventListener('mousedown', this._rectFactory.onMouseDown.bind(this._rectFactory));
        document.body.addEventListener('mousemove', this._rectFactory.onMouseMove.bind(this._rectFactory));
        document.body.addEventListener('mouseup', this._rectFactory.onMouseUp.bind(this._rectFactory));
        document.body.addEventListener('keydown',  this._rectFactory.onKeyDown.bind(this._rectFactory))
    };

    let alias_Scene_Map_terminate = Scene_Map.prototype.terminate;
    Scene_Map.prototype.terminate = function() {
        if(!this._rectFactory) return;
        document.body.removeEventListener('mousedown', this._rectFactory.onMouseDown.bind(this._rectFactory));
        document.body.removeEventListener('mousemove', this._rectFactory.onMouseMove.bind(this._rectFactory));
        document.body.removeEventListener('mouseup', this._rectFactory.onMouseUp.bind(this._rectFactory));
        document.body.removeEventListener('keydown',  this._rectFactory.onKeyDown.bind(this._rectFactory))
        alias_Scene_Map_terminate.call(this);
    };

    Scene_Map.prototype.processMapTouch = function() {
    };

})(RS.BuildRect);<commit_msg>Added the feature that get the name of the tile from img/tilesets folder<commit_after>//================================================================
// RS_BuildRect.js
// ---------------------------------------------------------------
// The MIT License
// Copyright (c) 2019 biud436
// ---------------------------------------------------------------
// Free for commercial and non commercial use.
//================================================================
/*:
 * @plugindesc <RS_BuildRect>
 * @author biud436
 *
 * @param alpha
 * @type number
 * @desc Specify the alpha value.
 * @default 0.7
 * @decimals 1
 *
 * @param color
 * @desc Specify the color value
 * @default 0xff0000
 *
 * @help
 * This plugin allows you to draw the rectangle on your screen and
 * you can export a json file to your data folder.
 *
 * Notice that this plugin can use only in PC platform.
 *
 * To save the json file, please press keys Ctrl + F7!
 *
 * ================================================================
 * Change Log
 * ================================================================
 * 2019.10.09 (v1.0.0) - First Release.
 * 2019.10.10 (v1.0.1) :
 * - Added the feature that get the name of the tile from img/tilesets folder.
 * - Now it can create a JSON file for RS_MirrorArea plugin.
 */

var Imported = Imported || {};
Imported.RS_BuildRect = true;

var RS = RS || {};
RS.BuildRect = RS.BuildRect || {};

(function($) {

    "use strict";

    var parameters = $plugins.filter(function (i) {
      return i.description.contains('<RS_BuildRect>');
    });

    parameters = (parameters.length > 0) && parameters[0].parameters;

    $.Params = {};
    $.Params.rectColor = Number(parameters['color'] || 0xff0000);
    $.Params.rectAlpha = Number(parameters['alpha'] || 0.7);

    class RFactory extends Sprite {

        constructor() {
            super();
            this.clearFlags();
            this.createGraphics();
            this.on('removed', this.terminate, this);
        }

        clearFlags() {
            this._isReady = false;
            this._data = [];
            this._isMouseMovement = false;
            this._endX = 0;
            this._endY = 0;
            this._startX = 0;
            this._startY = 0;

            this._multiLayer = new PIXI.Sprite();
            this.addChild(this._multiLayer);

            this.createPrimitive();
        }

        createPrimitive() {
            this._primitive = new Rectangle(0, 0, 0, 0);
        };

        createGraphics() {
            this._canvas = new PIXI.Graphics();
            this._canvas.alpha = $.Params.rectAlpha;
            this.addChild(this._canvas);

            if(this._canvas) {
                this._isReady = true;
            }
        }

        createTextLayer(...args) {
            const style = new PIXI.TextStyle({
                fontFamily: 'Arial',
                fontSize: 20,
                fill: '#ffffff',
                stroke: '#000000',
                strokeThickness: 2,
                wordWrap: true,
                wordWrapWidth: 200
            });
            if(this._textLayer) {
                this.removeChild(this._textLayer);
            }
            let text = '';
            const argc = args.length;

            if(argc === 1) {
                if(args[0] instanceof PIXI.Rectangle) {
                    const rect = args[0];
                    text = `x : ${rect.x}, y : ${rect.y}, width : ${rect.width}, height : ${rect.height}`;
                } else {
                    text = `${args[0]}`;
                }
            } else if(argc === 4) {
                text = `x : ${args[0]}, y : ${args[1]}, width : ${args[2]}, height : ${args[3]}`;
            }

            this._textLayer = new PIXI.Text(text.split(", ").join("\r\n"), style);
            this._textLayer.x = 0;
            this._textLayer.y = 0;
            this.addChild(this._textLayer);
        }

        drawTempRect(x, y, width, height, color = $.Params.rectColor) {

            if(!this._isReady) return false;

            if(width < 0) {
                width = 1;
            }

            if(height < 0) {
                height = 0;
            }

            if(typeof color !== 'number') {
                color = $.Params.rectColor;
            }

            const canvas = this._canvas;

            canvas.beginFill(color);
            canvas.drawRect(x, y, width, height);
            canvas.endFill();

        }

        /**
         *
         * @param {Number} prefix
         * 0 : A1
         * 1 : A2
         * 2 : A3
         * 3 : A4
         * 4 : A5
         * 5 : B
         * 6 : C
         * 7 : D
         * 8 : E
         * @param {Number} lastTileId The tile stores the special ID of the tiles by tilesets.
         * Depending on the ID of the tile, The B or C tileset is selected.
         */
        getTileName(prefix, lastTileId) {
            const tilesets = $gameMap.tileset().tilesetNames;
            const filename = tilesets[prefix];

            if(filename === "") return;

            const fs = require('fs');
            const path = require('path');
            const mainDir = path.join(process.mainModule.filename, "..");
            const txtFileName = path.join(mainDir, "img", "tilesets", `${filename}.txt`);

            if(fs.existsSync(txtFileName)) {
                let eof = fs.readFileSync(txtFileName, "utf8");
                const lines = eof.split(/[\r\n]+/i);
                 // The line number starts with to 0 and it is the number between 0 and 255.
                const tileName = lines[lastTileId % 256];
                if(typeof(tileName) === "string") {
                    // it consists with English|Japanese, so it must split.
                    this._type = tileName.split("|")[0];
                }
            }
        }

        /**
         *
         * @param {PIXI.Rectangle} rect
         * @param {Number} color
         */
        addRect(rect, color) {

            if(!this._isReady) return false;

            if(!(rect instanceof PIXI.Rectangle)) {
                rect = new PIXI.Rectangle(0, 0, 1, 1);
            }

            if(rect.width < 0) {
                rect.width = 1;
            }

            if(rect.height < 0) {
                rect.height = 0;
            }

            const canvas = new PIXI.Graphics();
            canvas.alpha = $.Params.rectAlpha;

            if(typeof color !== 'number') {
                color = $.Params.rectColor;
            }

            canvas.beginFill(color);
            canvas.drawRect(rect.x, rect.y, rect.width, rect.height);
            canvas.endFill();

            this._multiLayer.addChild(canvas);

            if(Imported.RS_MirrorArea) {

                const mx = $gameMap.canvasToMapX(rect.x);
                const my = $gameMap.canvasToMapY(rect.y);
                const tileIds = $gameMap.layeredTiles(mx, my);
                const lastTileId = tileIds[0];

                this._type = "MIRROR_NORMAL";

                if(lastTileId > Tilemap.TILE_ID_B && lastTileId < Tilemap.TILE_ID_C) {
                    this.getTileName(5, lastTileId);
                } else if(lastTileId >= Tilemap.TILE_ID_C && lastTileId < Tilemap.TILE_ID_D) {
                    this.getTileName(6, lastTileId);
                }

                const mirror = {
                    note: this._type,
                    w: rect.width,
                    h: rect.height,
                    mask_ox : rect.x,
                    mask_oy : rect.y,
                    char_ox : rect.x,
                    char_oy : rect.y
                };

                this._type = null;

                this._data.push(mirror);

            } else {
                this._data.push(rect.clone());
            }

        }

        clear() {
            const canvas = this._canvas;
            canvas.clear();
        }

        update() {
            super.update();
        }

        terminate() {
            if(this._isReady && this._canvas) {
                this.removeChild(this._canvas);
                this._canvas = null;
                this._isReady = false;
            }
        }

        /**
         *
         * @param {MouseEvent} event
         */
        onMouseDown(event) {

            this._isMouseMovement = true;

            const x = Graphics.pageToCanvasX(event.clientX);
            const y = Graphics.pageToCanvasY(event.clientY);

            if(!this._primitive) {
                this.createPrimitive();
            }

            this._startX = x;
            this._startY = y;

            this.clear();

        }

        /**
         *
         * @param {MouseEvent} event
         */
        onFlush(event) {
            if(!this._primitive) {
                this.createPrimitive();
            }

            let endX = Graphics.pageToCanvasX(event.clientX);
            let endY = Graphics.pageToCanvasY(event.clientY);
            const startX = this._startX;
            const startY = this._startY;

            this._primitive.x = Math.min(startX, endX);
            this._primitive.y = Math.min(startY, endY);
            this._primitive.width = Math.max(startX, endX) - this._primitive.x;
            this._primitive.height = Math.max(startY, endY) - this._primitive.y;

            const d = Math.sqrt(Math.pow(this._primitive.width - this._primitive.x, 2) + Math.pow(this._primitive.height - this._primitive.y, 2));

            this.createTextLayer(this._primitive);

            return (d >= 5) ? true : false;

        }

        /**
         *
         * @param {MouseEvent} event
         */
        onMouseMove(event) {
            if( this._isMouseMovement) {

                if(this.onFlush(event)) {
                    this.clear();

                    this.drawTempRect(
                        this._primitive.x,
                        this._primitive.y,
                        this._primitive.width,
                        this._primitive.height,
                        $.Params.rectColor);
                }

            }
        }

        /**
         *
         * @param {MouseEvent} event
         */
        onMouseUp(event) {

            if(this.onFlush(event)) {
                this.clear();
                this.addRect(this._primitive, $.Params.rectColor);
                this._isMouseMovement = false;
            }

        }

        onSave() {
            const fs = require('fs');
            const path = require('path');
            const mainDir = path.join(process.mainModule.filename, "..");
            const retPath = path.join(mainDir, "data", "rect.json")
            const retData = JSON.stringify(this._data, null, "\t");

            let chooser = document.createElement('input');
            chooser.style.display = "none";
            chooser.id = "fileDialog";
            chooser.type = "file";
            chooser.nwsaveas = "rect.json";
            chooser.setAttribute('nwworkingdir', mainDir);

            chooser.addEventListener("change", () => {
                const filename = chooser.value;
                fs.writeFile(filename, retData, err => {
                    if(err) {
                        this.createTextLayer(`Failed to save!!\n${err.message}`);
                        return;
                    }
                    this.createTextLayer(`Successfully saved!! \n${filename}`);

                    this._multiLayer.removeChildren();
                    this._data = [];
                    this._primitive = new Rectangle(0, 0, 1, 1);

                    setTimeout(() => {
                        this.removeChild(this._textLayer);
                    }, 1000);

                });
            });

            chooser.click();

        };

        /**
         *
         * @param {KeyboardEvent} event
         */
        onKeyDown(event) {
            const keycode = event.keyCode || event.which;
            if(keycode == 118 && event.ctrlKey) {
                this.onSave();
            }
        }

    }

    let alias_Scene_Map_start = Scene_Map.prototype.start;
    Scene_Map.prototype.start = function() {
        alias_Scene_Map_start.call(this);
        this._rectFactory = new RFactory();
        this.addChild(this._rectFactory);

        document.body.addEventListener('mousedown', this._rectFactory.onMouseDown.bind(this._rectFactory));
        document.body.addEventListener('mousemove', this._rectFactory.onMouseMove.bind(this._rectFactory));
        document.body.addEventListener('mouseup', this._rectFactory.onMouseUp.bind(this._rectFactory));
        document.body.addEventListener('keydown',  this._rectFactory.onKeyDown.bind(this._rectFactory))
    };

    let alias_Scene_Map_terminate = Scene_Map.prototype.terminate;
    Scene_Map.prototype.terminate = function() {
        if(!this._rectFactory) return;
        document.body.removeEventListener('mousedown', this._rectFactory.onMouseDown.bind(this._rectFactory));
        document.body.removeEventListener('mousemove', this._rectFactory.onMouseMove.bind(this._rectFactory));
        document.body.removeEventListener('mouseup', this._rectFactory.onMouseUp.bind(this._rectFactory));
        document.body.removeEventListener('keydown',  this._rectFactory.onKeyDown.bind(this._rectFactory))
        alias_Scene_Map_terminate.call(this);
    };

    Scene_Map.prototype.processMapTouch = function() {
    };

})(RS.BuildRect);<|endoftext|>


<commit_before>Template.HostList.events({
});

Template.HostList.helpers({
  hosts: function () {
    return Hosts.find();
  }
});

// Make sortable rows.
Template.HostList.rendered = function() {

  this.$('#sortable').sortable({

    stop: function(event, ui) {

      target = ui.item.get(0);
      before = ui.item.prev().get(0);
      after = ui.item.next().get(0);

      if (!before) {
        newSort = Blaze.getData(after).sort -1;
      } else if (!after) {
        newSort = Blaze.getData(before).sort +1;
      } else {
        newSort = (Blaze.getData(after).sort +
                  Blaze.getData(before).sort) / 2;
      }

      Hosts.update({_id: Blaze.getData(target)._id}, {
        $set: {
          sort: newSort
        }
      });
    }
  });

}
<commit_msg>Sorted host list by sort value and improved comments.<commit_after>Template.HostList.events({
});

Template.HostList.helpers({
  // Get list of Hosts sorted by the sort field.
  hosts: function () {
    return Hosts.find({}, {sort: {sort: 1}});
  }
});

Template.HostList.rendered = function() {

  // Make rows sortable/draggable using Jquery-UI.
  this.$('#sortable').sortable({

    stop: function(event, ui) {
      // Define target row items.
      target = ui.item.get(0);
      before = ui.item.prev().get(0);
      after = ui.item.next().get(0);

      // Change the sort value dependnig on target location.
      // If target is now first, subtract 1 from sort value.
      if (!before) {
        newSort = Blaze.getData(after).sort -1;
      // If target is now last, add 1 to sort value.
      } else if (!after) {
        newSort = Blaze.getData(before).sort +1;
      // Get value of prev and next elements
      // to determine new target sort value.
      } else {
        newSort = (Blaze.getData(after).sort +
                  Blaze.getData(before).sort) / 2;
      }

      // Update the database with new sort value.
      Hosts.update({_id: Blaze.getData(target)._id}, {
        $set: {
          sort: newSort
        }
      });

    }

  });
}
<|endoftext|>


<commit_before>//https://developers.google.com/web/fundamentals/getting-started/primers/service-workers
var CACHE_NAME = '#1486635876181';
var urlsToCache = [
  '/css/style.css',
  '/js/main.js',
  '/js/svg4everybody.js',
  '/icon.svg'
];

var BLACKLIST = [
  '/',
];

self.addEventListener('install', function (event) {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function (cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.match(event.request)
      .then(function (response) {
        if (response) {
          return response;
        }
        var fetchRequest = event.request.clone();

        return fetch(fetchRequest).then(

          function (response) {
            var shouldCache = true;

            for (var i = 0; i < BLACKLIST.length; i++) {
              var regExp = new RegExp(BLACKLIST[i]);
              if (regExp.test(fetchRequest.url)) {
                shouldCache = false;
                break;
              }
            }

            if (!shouldCache || !response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }

            var responseToCache = response.clone();

            caches.open(CACHE_NAME)
              .then(function (cache) {
                cache.put(event.request, responseToCache);
              });

            return response;
          }
        );
      })
  );
});

self.addEventListener('activate', function (event) {
  event.waitUntil(
    caches.keys().then(function (cacheNames) {
      return Promise.all(
        cacheNames.map(function (cacheName) {
          if (CACHE_NAME != cacheName) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});
<commit_msg>update sw.js<commit_after>var CACHE_NAME = '#1486649026431';
var urlsToCache = [
  '/css/style.css',
  '/js/main.js',
  '/js/svg4everybody.js',
  '/icon.svg',
  '/404.html'
];
var cachePathPattern = /^(https?:\/\/.+)?\/(about|20\d{2}|css|js|assets)\/(.+)$/

self.addEventListener('install', function (event) {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function (cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.match(event.request)
      .then(function (response) {
        if (response) {
          return response;
        }
        var fetchRequest = event.request.clone();

        return fetch(fetchRequest).then(

          function (response) {
            var shouldCache = false
            if (fetchRequest.url) {
              shouldCache = cachePathPattern.test(fetchRequest.url)
            }
            if (!shouldCache || !response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }
            var responseToCache = response.clone()
            caches.open(CACHE_NAME)
              .then(function (cache) {
                cache.put(event.request, responseToCache);
              });
            return response;
          }
        );
      })
  );
});

self.addEventListener('activate', function (event) {
  event.waitUntil(
    caches.keys().then(function (cacheNames) {
      return Promise.all(
        cacheNames.map(function (cacheName) {
          if (CACHE_NAME != cacheName) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});<|endoftext|>


<commit_before>'use strict';

let Options = {
  PopSound: '../../resources/sounds/PowerAuras/sonar.ogg',
  RankOptions: {
    'S': {
      Type: 'mob',
    },
    'SS+': {
      Type: 'mob',
    },
    'SS-': {
      Type: 'mob',
    },
    'A': {
      Type: 'mob',
    },
    'B': {
      Type: 'mob',
      PopSoundAlert: false,
    },
  },
  CustomMonsters: {},
};

// Minimum distance a mob with the same name needs to be away from the old
// location before a sound is played and it is treated as a new mob.
// TODO: probably all mobs should be tracked with ids to avoid this.
// TODO: this would also let us handle mobs with the same name better.
const kMinDistanceBeforeSound = 100;

let gRadar;

const instanceChangedRegex = {
  en: NetRegexes.gameLog({ code: '0039', line: 'You are now in the instanced area.*?' }),
  de: NetRegexes.gameLog({ code: '0039', line: 'Du bist nun in dem instanziierten Areal.*?' }),
  fr: NetRegexes.gameLog({ code: '0039', line: 'Vous êtes maintenant dans la zone instanciée.*?' }),
  ja: NetRegexes.gameLog({ code: '0039', line: 'インスタンスエリア.*?' }),
  cn: NetRegexes.gameLog({ code: '0039', line: '当前所在副本区为.*?' }),
  ko: NetRegexes.gameLog({ code: '0039', line: '인스턴스 지역.*?' }),
};

class Point2D {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  // Calculates vector length (magnitude)
  length() {
    return Math.sqrt((this.x) * (this.x) + (this.y) * (this.y));
  }

  // Calculate delta vector
  delta(target) {
    return new Point2D(target.x - this.x, target.y - this.y);
  }

  // Calculate distance between 2 points
  distance(target) {
    return this.delta(target).length();
  }
}

function posToMap(h) {
  let offset = 21.5;
  let pitch = 0.02;
  return h * pitch + offset;
}

function PlaySound(monster, options) {
  if (options.TTS) {
    callOverlayHandler({
      call: 'cactbotSay',
      text: monster.rank + ' ' + monster.name,
    });
  } else if (options.PopSoundAlert && options.PopSound && options.PopVolume) {
    let audio = new Audio(options.PopSound);
    audio.volume = options.PopVolume;
    audio.play();
  }
}

class Radar {
  constructor(element) {
    this.targetMonsters = {};
    this.playerPos = {};
    this.playerRotation = 0;
    this.table = element;
    this.options = Options;
    this.monsters = Object.assign({}, gMonster, Options.CustomMonsters);
    this.lang = this.options.ParserLanguage || 'en';
    this.nameToMonster = {};
    for (let i in this.monsters) {
      let monster = this.monsters[i];
      let lang = this.lang || 'en';
      monster.name = monster.name[lang] || monster.name['en'];

      // Names are either strings or arrays of strings.
      if (typeof monster.name === 'string') {
        this.nameToMonster[monster.name.toLowerCase()] = monster;
      } else {
        for (let i = 0; i < monster.name.length; ++i)
          this.nameToMonster[monster.name[i].toLowerCase()] = monster;
      }
    }
  }

  AddMonster(log, monster, matches) {
    if (monster.id && matches.npcNameId !== monster.id)
      return;
    if (monster.regex && !log.match(monster.regex))
      return;
    if (monster.hp && parseFloat(matches.hp) < monster.hp)
      return;

    let options = this.options;
    // option overwrite
    if (monster.rank in options.RankOptions)
      options = Object.assign({}, this.options, options.RankOptions[monster.rank]);
    if (options.Type === 'mob') {
      if (!matches.id.startsWith('4'))
        return;
      if (typeof matches.npcId === 'undefined')
        return;
    }

    let mobKey = matches.name.toLowerCase();
    if (mobKey in this.targetMonsters) {
      // Get positions
      let playerPos = new Point2D(this.playerPos.x, this.playerPos.y);
      let oldPos = this.targetMonsters[mobKey].pos;
      let newPos =
        new Point2D(parseFloat(matches.x), parseFloat(matches.y));

      // Calculate distances
      let oldDistance = playerPos.distance(oldPos);
      let newDistance = playerPos.distance(newPos);

      // Update position only if its closer than the current one
      if (newDistance < oldDistance) {
        this.targetMonsters[mobKey].pos = newPos;
        this.targetMonsters[mobKey].posZ = matches.z;

        // Update DOM
        this.UpdateMonsterDom(this.targetMonsters[mobKey]);

        // Play sound only if its far enough
        if (oldPos.distance(newPos) >= kMinDistanceBeforeSound)
          PlaySound(this.targetMonsters[mobKey], options);
      }
    } else {
      // Add DOM
      let arrowId = 'arrow-' + matches.id;
      let tr = document.createElement('tr');
      let th = document.createElement('th');
      let img = document.createElement('img');
      img.setAttribute('id', arrowId);
      img.setAttribute('src', 'arrow.png');
      img.setAttribute('class', 'radar-image-40');
      th.appendChild(img);
      th.setAttribute('style', 'max-width: 100px');
      tr.appendChild(th);
      th = document.createElement('th');
      th.setAttribute('align', 'left');
      th.appendChild(document.createElement('div'));
      tr.appendChild(th);
      this.table.insertBefore(tr, this.table.childNodes[0]);

      let m = {
        'id': matches.id,
        'name': matches.name,
        'rank': monster.rank || '',
        'hp': parseFloat(matches.hp),
        'currentHp': parseFloat(matches.hp),
        'battleTime': 0,
        'pos': new Point2D(parseFloat(matches.x), parseFloat(matches.y)),
        'posZ': matches.z,
        'addTime': Date.now(),
        'dom': tr,
        'puller': null,
      };
      this.targetMonsters[mobKey] = m;
      this.UpdateMonsterDom(m);

      PlaySound(this.targetMonsters[mobKey], options);
    }
  }

  UpdateMonsterPuller(monster, puller) {
    if (!this.options.Puller)
      return;
    if (monster.puller !== null)
      return;
    monster.puller = puller;
    this.UpdateMonsterDom(monster);
    console.log('Pull: ' + puller + ' => ' + monster.name);
  }

  UpdateMonsterDom(monster) {
    let options = this.options;
    if (monster.rank in options.RankOptions)
      options = Object.assign({}, this.options, options.RankOptions[monster.rank]);
    let tr = monster.dom;
    // calculate rotation based on facing
    let playerVector = new Point2D(this.playerPos.x, this.playerPos.y);
    let targetVector = monster.pos;
    let deltaVector = new Point2D(targetVector.x - playerVector.x, targetVector.y - playerVector.y);
    if (tr) {
      tr.childNodes[1].innerHTML = monster.rank + '    ' + monster.name;
      if (Math.abs(this.playerPos.z - monster.posZ) > 5)
        tr.childNodes[1].innerHTML += '  ' + (this.playerPos.z < monster.posZ ? '↑' : '↓');
      tr.childNodes[1].innerHTML += '
' + deltaVector.length().toFixed(2) + 'm';
      if (Date.now() / 1000 <= monster.battleTime + 60) {
        tr.childNodes[1].innerHTML += ' ' + (monster.currentHp * 100 /
          monster.hp).toFixed(2) + '%';
      }
      if (monster.puller)
        tr.childNodes[1].innerHTML += '  ' + monster.puller;
      // Z position is relative to the map so it's omitted.
      if (options.Position) {
        tr.childNodes[1].innerHTML += '
X: ' +
          posToMap(monster.pos.x).toFixed(1) + '  Y:' +
          posToMap(monster.pos.y).toFixed(1);
      }
    }
    if (options.DetectionRange > 0 && deltaVector.length() > options.DetectionRange)
      monster.dom.classList.add('hide');
    else
      monster.dom.classList.remove('hide');

    let deltaTheta = Math.atan2(deltaVector.y, deltaVector.x);
    deltaTheta -= Math.PI - this.playerRotation;
    let angle = deltaTheta * 180 / Math.PI;
    let arrowId = 'arrow-' + monster.id;
    let arrow = document.getElementById(arrowId);
    arrow.style.transform = 'rotate(' + angle + 'deg)';
  }

  RemoveMonster(mobKey) {
    if (mobKey in this.targetMonsters) {
      this.targetMonsters[mobKey].dom.remove();
      delete this.targetMonsters[mobKey];
    }
  }

  OnNetLog(e) {
    const type = e.line[0];
    const log = e.rawLine;

    // added new combatant
    if (type === '03') {
      const matches = log.match(NetRegexes.addedCombatantFull());
      if (matches) {
        const monster = this.nameToMonster[matches.groups.name.toLowerCase()];
        if (monster)
          this.AddMonster(log, monster, matches.groups);
      }
      return;
    }

    // network ability
    if (type === '21' || type === '22') {
      const matches = log.match(NetRegexes.abilityFull());
      if (matches) {
        const monster = this.targetMonsters[matches.groups.target.toLowerCase()];
        if (monster) {
          // provoke doesn't work on hunt mobs
          const isProvoke = matches.id === '1D6D';
          if (!isProvoke)
            this.UpdateMonsterPuller(monster, matches.groups.source);
        }
      }
      return;
    }

    // change instance
    if (type === '00') {
      const lang = this.options.ParserLanguage;
      if (log.match(instanceChangedRegex[lang] || instanceChangedRegex['en'])) {
        // don't remove mobs lasting less than 10 seconds
        this.ClearTargetMonsters(10);
      }
      return;
    }

    // removing combatant
    if (type === '25') {
      const matches = log.match(NetRegexes.wasDefeated());
      if (matches)
        this.RemoveMonster(matches.groups.target.toLowerCase());
      return;
    }
  }

  OnPlayerChange(e) {
    this.playerPos.x = e.detail.pos.x;
    this.playerPos.y = e.detail.pos.y;
    this.playerPos.z = e.detail.pos.z;
    this.playerRotation = e.detail.rotation;
    for (let i in this.targetMonsters)
      this.UpdateMonsterDom(this.targetMonsters[i]);
  }

  OnChangeZone(e) {
    this.ClearTargetMonsters();
  }

  ClearTargetMonsters(deltaTime) {
    let deltaTimeThreshold = deltaTime || 0;
    for (let i in this.targetMonsters) {
      if ((Date.now() - this.targetMonsters[i].addTime) / 1000 > deltaTimeThreshold) {
        this.targetMonsters[i].dom.remove();
        delete this.targetMonsters[i];
      }
    }
  }
}

UserConfig.getUserConfigLocation('radar', function() {
  addOverlayListener('LogLine', (e) => {
    gRadar.OnNetLog(e);
  });

  addOverlayListener('onPlayerChangedEvent', (e) => {
    gRadar.OnPlayerChange(e);
  });

  addOverlayListener('ChangeZone', (e) => {
    gRadar.OnChangeZone(e);
  });

  gRadar = new Radar(document.getElementById('radar-table'));
});
<commit_msg>radar: fix mobs not showing up with default options<commit_after>'use strict';

let Options = {
  PopSound: '../../resources/sounds/PowerAuras/sonar.ogg',
  RankOptions: {
    'S': {
      Type: 'mob',
    },
    'SS+': {
      Type: 'mob',
    },
    'SS-': {
      Type: 'mob',
    },
    'A': {
      Type: 'mob',
    },
    'B': {
      Type: 'mob',
      PopSoundAlert: false,
    },
  },
  CustomMonsters: {},
};

// Minimum distance a mob with the same name needs to be away from the old
// location before a sound is played and it is treated as a new mob.
// TODO: probably all mobs should be tracked with ids to avoid this.
// TODO: this would also let us handle mobs with the same name better.
const kMinDistanceBeforeSound = 100;

let gRadar;

const instanceChangedRegex = {
  en: NetRegexes.gameLog({ code: '0039', line: 'You are now in the instanced area.*?' }),
  de: NetRegexes.gameLog({ code: '0039', line: 'Du bist nun in dem instanziierten Areal.*?' }),
  fr: NetRegexes.gameLog({ code: '0039', line: 'Vous êtes maintenant dans la zone instanciée.*?' }),
  ja: NetRegexes.gameLog({ code: '0039', line: 'インスタンスエリア.*?' }),
  cn: NetRegexes.gameLog({ code: '0039', line: '当前所在副本区为.*?' }),
  ko: NetRegexes.gameLog({ code: '0039', line: '인스턴스 지역.*?' }),
};

class Point2D {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  // Calculates vector length (magnitude)
  length() {
    return Math.sqrt((this.x) * (this.x) + (this.y) * (this.y));
  }

  // Calculate delta vector
  delta(target) {
    return new Point2D(target.x - this.x, target.y - this.y);
  }

  // Calculate distance between 2 points
  distance(target) {
    return this.delta(target).length();
  }
}

function posToMap(h) {
  let offset = 21.5;
  let pitch = 0.02;
  return h * pitch + offset;
}

function PlaySound(monster, options) {
  if (options.TTS) {
    callOverlayHandler({
      call: 'cactbotSay',
      text: monster.rank + ' ' + monster.name,
    });
  } else if (options.PopSoundAlert && options.PopSound && options.PopVolume) {
    let audio = new Audio(options.PopSound);
    audio.volume = options.PopVolume;
    audio.play();
  }
}

class Radar {
  constructor(element) {
    this.targetMonsters = {};
    this.playerPos = {};
    this.playerRotation = 0;
    this.table = element;
    this.options = Options;
    this.monsters = Object.assign({}, gMonster, Options.CustomMonsters);
    this.lang = this.options.ParserLanguage || 'en';
    this.nameToMonster = {};
    for (let i in this.monsters) {
      let monster = this.monsters[i];
      let lang = this.lang || 'en';
      monster.name = monster.name[lang] || monster.name['en'];

      // Names are either strings or arrays of strings.
      if (typeof monster.name === 'string') {
        this.nameToMonster[monster.name.toLowerCase()] = monster;
      } else {
        for (let i = 0; i < monster.name.length; ++i)
          this.nameToMonster[monster.name[i].toLowerCase()] = monster;
      }
    }
  }

  AddMonster(log, monster, matches) {
    if (monster.id && matches.npcNameId !== monster.id)
      return;
    if (monster.regex && !log.match(monster.regex))
      return;
    if (monster.hp && parseFloat(matches.hp) < monster.hp)
      return;

    let options = this.options;
    // option overwrite
    if (monster.rank in options.RankOptions)
      options = Object.assign({}, this.options, options.RankOptions[monster.rank]);
    if (options.Type === 'mob') {
      if (!matches.id.startsWith('4'))
        return;
      if (!matches.npcNameId || matches.npcNameId === '0')
        return;
    }

    let mobKey = matches.name.toLowerCase();
    if (mobKey in this.targetMonsters) {
      // Get positions
      let playerPos = new Point2D(this.playerPos.x, this.playerPos.y);
      let oldPos = this.targetMonsters[mobKey].pos;
      let newPos =
        new Point2D(parseFloat(matches.x), parseFloat(matches.y));

      // Calculate distances
      let oldDistance = playerPos.distance(oldPos);
      let newDistance = playerPos.distance(newPos);

      // Update position only if its closer than the current one
      if (newDistance < oldDistance) {
        this.targetMonsters[mobKey].pos = newPos;
        this.targetMonsters[mobKey].posZ = matches.z;

        // Update DOM
        this.UpdateMonsterDom(this.targetMonsters[mobKey]);

        // Play sound only if its far enough
        if (oldPos.distance(newPos) >= kMinDistanceBeforeSound)
          PlaySound(this.targetMonsters[mobKey], options);
      }
    } else {
      // Add DOM
      let arrowId = 'arrow-' + matches.id;
      let tr = document.createElement('tr');
      let th = document.createElement('th');
      let img = document.createElement('img');
      img.setAttribute('id', arrowId);
      img.setAttribute('src', 'arrow.png');
      img.setAttribute('class', 'radar-image-40');
      th.appendChild(img);
      th.setAttribute('style', 'max-width: 100px');
      tr.appendChild(th);
      th = document.createElement('th');
      th.setAttribute('align', 'left');
      th.appendChild(document.createElement('div'));
      tr.appendChild(th);
      this.table.insertBefore(tr, this.table.childNodes[0]);

      let m = {
        'id': matches.id,
        'name': matches.name,
        'rank': monster.rank || '',
        'hp': parseFloat(matches.hp),
        'currentHp': parseFloat(matches.hp),
        'battleTime': 0,
        'pos': new Point2D(parseFloat(matches.x), parseFloat(matches.y)),
        'posZ': matches.z,
        'addTime': Date.now(),
        'dom': tr,
        'puller': null,
      };
      this.targetMonsters[mobKey] = m;
      this.UpdateMonsterDom(m);

      PlaySound(this.targetMonsters[mobKey], options);
    }
  }

  UpdateMonsterPuller(monster, puller) {
    if (!this.options.Puller)
      return;
    if (monster.puller !== null)
      return;
    monster.puller = puller;
    this.UpdateMonsterDom(monster);
    console.log('Pull: ' + puller + ' => ' + monster.name);
  }

  UpdateMonsterDom(monster) {
    let options = this.options;
    if (monster.rank in options.RankOptions)
      options = Object.assign({}, this.options, options.RankOptions[monster.rank]);
    let tr = monster.dom;
    // calculate rotation based on facing
    let playerVector = new Point2D(this.playerPos.x, this.playerPos.y);
    let targetVector = monster.pos;
    let deltaVector = new Point2D(targetVector.x - playerVector.x, targetVector.y - playerVector.y);
    if (tr) {
      tr.childNodes[1].innerHTML = monster.rank + '    ' + monster.name;
      if (Math.abs(this.playerPos.z - monster.posZ) > 5)
        tr.childNodes[1].innerHTML += '  ' + (this.playerPos.z < monster.posZ ? '↑' : '↓');
      tr.childNodes[1].innerHTML += '
' + deltaVector.length().toFixed(2) + 'm';
      if (Date.now() / 1000 <= monster.battleTime + 60) {
        tr.childNodes[1].innerHTML += ' ' + (monster.currentHp * 100 /
          monster.hp).toFixed(2) + '%';
      }
      if (monster.puller)
        tr.childNodes[1].innerHTML += '  ' + monster.puller;
      // Z position is relative to the map so it's omitted.
      if (options.Position) {
        tr.childNodes[1].innerHTML += '
X: ' +
          posToMap(monster.pos.x).toFixed(1) + '  Y:' +
          posToMap(monster.pos.y).toFixed(1);
      }
    }
    if (options.DetectionRange > 0 && deltaVector.length() > options.DetectionRange)
      monster.dom.classList.add('hide');
    else
      monster.dom.classList.remove('hide');

    let deltaTheta = Math.atan2(deltaVector.y, deltaVector.x);
    deltaTheta -= Math.PI - this.playerRotation;
    let angle = deltaTheta * 180 / Math.PI;
    let arrowId = 'arrow-' + monster.id;
    let arrow = document.getElementById(arrowId);
    arrow.style.transform = 'rotate(' + angle + 'deg)';
  }

  RemoveMonster(mobKey) {
    if (mobKey in this.targetMonsters) {
      this.targetMonsters[mobKey].dom.remove();
      delete this.targetMonsters[mobKey];
    }
  }

  OnNetLog(e) {
    const type = e.line[0];
    const log = e.rawLine;

    // added new combatant
    if (type === '03') {
      const matches = log.match(NetRegexes.addedCombatantFull());
      if (matches) {
        const monster = this.nameToMonster[matches.groups.name.toLowerCase()];
        if (monster)
          this.AddMonster(log, monster, matches.groups);
      }
      return;
    }

    // network ability
    if (type === '21' || type === '22') {
      const matches = log.match(NetRegexes.abilityFull());
      if (matches) {
        const monster = this.targetMonsters[matches.groups.target.toLowerCase()];
        if (monster) {
          // provoke doesn't work on hunt mobs
          const isProvoke = matches.id === '1D6D';
          if (!isProvoke)
            this.UpdateMonsterPuller(monster, matches.groups.source);
        }
      }
      return;
    }

    // change instance
    if (type === '00') {
      const lang = this.options.ParserLanguage;
      if (log.match(instanceChangedRegex[lang] || instanceChangedRegex['en'])) {
        // don't remove mobs lasting less than 10 seconds
        this.ClearTargetMonsters(10);
      }
      return;
    }

    // removing combatant
    if (type === '25') {
      const matches = log.match(NetRegexes.wasDefeated());
      if (matches)
        this.RemoveMonster(matches.groups.target.toLowerCase());
      return;
    }
  }

  OnPlayerChange(e) {
    this.playerPos.x = e.detail.pos.x;
    this.playerPos.y = e.detail.pos.y;
    this.playerPos.z = e.detail.pos.z;
    this.playerRotation = e.detail.rotation;
    for (let i in this.targetMonsters)
      this.UpdateMonsterDom(this.targetMonsters[i]);
  }

  OnChangeZone(e) {
    this.ClearTargetMonsters();
  }

  ClearTargetMonsters(deltaTime) {
    let deltaTimeThreshold = deltaTime || 0;
    for (let i in this.targetMonsters) {
      if ((Date.now() - this.targetMonsters[i].addTime) / 1000 > deltaTimeThreshold) {
        this.targetMonsters[i].dom.remove();
        delete this.targetMonsters[i];
      }
    }
  }
}

UserConfig.getUserConfigLocation('radar', function() {
  addOverlayListener('LogLine', (e) => {
    gRadar.OnNetLog(e);
  });

  addOverlayListener('onPlayerChangedEvent', (e) => {
    gRadar.OnPlayerChange(e);
  });

  addOverlayListener('ChangeZone', (e) => {
    gRadar.OnChangeZone(e);
  });

  gRadar = new Radar(document.getElementById('radar-table'));
});
<|endoftext|>


<commit_before>"use strict";
var fs = require('fs');
var mongoose = require('mongoose');
var app = require('./../server');
var request = require('supertest')(app);
var jwt = require('jsonwebtoken');
var config = require('./../config/pass');
var model = require('./../app/models');
var _userseeds = fs.readFileSync(__dirname + '/../seeds/users.json');
var _roleseeds = fs.readFileSync(__dirname + '/../seeds/roles.json');
var _documentseeds = fs.readFileSync(__dirname + '/../seeds/documents.json');
var userData = JSON.parse(_userseeds);
var roleData = JSON.parse(_roleseeds);
var docData = JSON.parse(_documentseeds);
var User = model.User;
var Role = model.Role;
var Document = model.Document;

describe("DOCUMENT TESTS", function() {
 var id, userToken;
 beforeEach(function(done) {
  var newUser = new User(userData[0]);
  var newRole = new Role(roleData[0]);
  newUser.save();
  newRole.save();
  id = newUser._id;
  userToken = jwt.sign(newUser, config.secret, {
   expiresIn: 86400 // expires in 24 hrs
  });
  done();
 });
 afterEach(function(done) {
  Document.remove({}, function() {
   User.remove({}, function() {
    Role.remove({}, function() {
     done();
    });
   });
  });
 });
 describe("CREATE DOCUMENT POST /api/documents/", function() {
  it("should create document for user with valid credentials", function(done) {
   request.post('/api/documents/').set('x-access-token', userToken).send(docData[0]).expect(200).end(function(err, res) {
    expect(err).not.toBeUndefined();
    expect(res.body).toEqual(jasmine.objectContaining({
     success: true,
     message: 'Document successfully created'
    }));
    done();
   });
  });
  it("should not create a document without the user authenticated", function(done) {
   request.post('/api/documents/').send(docData[1]).expect(403).end(function(err, res) {
    expect(err).not.toBeUndefined();
    expect(res.body).toEqual(jasmine.objectContaining({
     success: false,
     message: 'Please provide your token'
    }));
    done();
   });
  });
  it("should not create a document without a valid role", function(done) {
   request.post('/api/documents').set('x-access-token', userToken).expect(403).send({
    title: docData[0].title,
    content: docData[0].content,
    role: 'DoesntExist' || undefined
   }).end(function(err, res) {
    expect(err).toBeDefined();
    expect(err).not.toBeNull();
    expect(res.body).toEqual(jasmine.objectContaining({
     success: false,
     message: 'Invalid role'
    }));
    done();
   });
  });
  xit("should create document with unique title", function(done) {
   request.post('/api/documents').set('x-access-token', userToken).send(docData[0]).expect(403).end(function(err, res) {
    expect(err).toBeDefined();
    expect(err).not.toBeNull();
    expect(res.body).toEqual(jasmine.objectContaining({
     success: false,
     message: 'Document exists'
    }));
   });
  });
 });
 describe("GET DOCUMENTS GET /api/documents/", function() {
  afterEach(function(done) {
   Document.remove({}, function() {
    User.remove({}, function() {
     Role.remove({}, function() {
      done();
     });
    });
   });
  });
  it("it should return all documents", function(done) {
   for (var i = 0, n = docData.length; i < n; i++) {
    var newRole = new Role(roleData[i]);
    var newUser = new User(userData[i]);
    var docDetail = docData[i];
    docDetail.ownerId = newUser._id;
    var newDoc = new Document(docDetail);
    newUser.save();
    newRole.save();
    newDoc.save();
   }
   request.get('/api/documents/').set('x-access-token', userToken).expect(200).end(function(err, res) {
    expect(err).toBeNull();
    expect(res.body.length).toBe(3);
    expect(res.body[0]).toEqual(jasmine.objectContaining({
     title: 'The regalia',
     role: 'Documentarian',
     content: 'Kings and people of royal heritage are known for their great outward look at all times as a demonstration of their royalty'
    }));
    expect(res.body[1]).toEqual(jasmine.objectContaining({
     title: 'The quest for dividends of democracy',
     role: 'Trainer',
     content: 'Democracy without dividend is arnachy in disguise. Every through democratic institution must plan to deliver to the citizens they represent'
    }));
    expect(res.body[2]).toEqual(jasmine.objectContaining({
     title: 'The beautiful ones are not yet born',
     role: 'Librarian',
     content: 'It makes more sense when people understand the essence of existence rather outward beauty that fades away and is no more'
    }));
   });
   done();
  });
 });
});<commit_msg>test(document-spec): add document tests<commit_after>"use strict";
var fs = require('fs');
var mongoose = require('mongoose');
var app = require('./../server');
var request = require('supertest')(app);
var jwt = require('jsonwebtoken');
var config = require('./../config/pass');
var model = require('./../app/models');
var _userseeds = fs.readFileSync(__dirname + '/../seeds/users.json');
var _roleseeds = fs.readFileSync(__dirname + '/../seeds/roles.json');
var _documentseeds = fs.readFileSync(__dirname + '/../seeds/documents.json');
var userData = JSON.parse(_userseeds);
var roleData = JSON.parse(_roleseeds);
var docData = JSON.parse(_documentseeds);
var User = model.User;
var Role = model.Role;
var Document = model.Document;

describe("DOCUMENT TESTS", function() {
 describe("CREATE DOCUMENT POST /api/documents/", function() {
  var id, userToken;
  beforeEach(function(done) {
   var newUser = new User(userData[0]);
   var newRole = new Role(roleData[0]);
   newUser.save();
   newRole.save();
   id = newUser._id;
   userToken = jwt.sign(newUser, config.secret, {
    expiresIn: 86400 // expires in 24 hrs
   });
   done();
  });
  afterEach(function(done) {
   Document.remove({}, function() {
    User.remove({}, function() {
     Role.remove({}, function() {
      done();
     });
    });
   });
  });
  it("should create document for user with valid credentials", function(done) {
   request.post('/api/documents/').set('x-access-token', userToken).send({
    title: docData[0].title,
    content: docData[0].content,
    role: docData[0].role,
    ownerId: id
   }).expect(200).end(function(err, res) {
    expect(err).not.toBeUndefined();
    expect(res.body).toEqual(jasmine.objectContaining({
     success: true,
     message: 'Document successfully created'
    }));
    done();
   });
  });
  it("should create document with unique title", function(done) {
   var doctest = docData[0];
   doctest.ownerId = id;
   var newDoc = new Document(doctest);
   newDoc.save();
   request.post('/api/documents/')
   .set('x-access-token', userToken)
   .send(docData[0])
   .expect(403)
   .end(function(err, res) {
    expect(err).toBeDefined();
    expect(err).toBeNull();
    expect(res.body).toEqual(jasmine.objectContaining({
     success: false,
     message: 'Document already exist'
    }));
    done();
   });
  });
  it("should not create a document without the user authenticated", function(done) {
   request.post('/api/documents/')
   .send(docData[1])
   .expect(403)
   .end(function(err, res) {
    expect(err).not.toBeUndefined();
    expect(res.body).toEqual(jasmine.objectContaining({
     success: false,
     message: 'Please provide your token'
    }));
    done();
   });
  });
  it("should not create a document without a valid role", function(done) {
   request.post('/api/documents')
   .set('x-access-token', userToken)
   .expect(403)
   .send({
    title: docData[0].title,
    content: docData[0].content,
    role: 'DoesntExist' || undefined
   }).end(function(err, res) {
    expect(err).toBeDefined();
    expect(err).not.toBeNull();
    expect(res.body).toEqual(jasmine.objectContaining({
     success: false,
     message: 'Invalid role'
    }));
    done();
   });
  });
 });
 describe("GET, UPDATE, DELETE DOCUMENTS on /api/documents/", function() {
  var docId, userToken;
  beforeEach(function(done) {
   var newRole = new Role(roleData[0]);
   var newUser = new User(userData[0]);
   newRole.save();
   newUser.save();
   var docTest = docData[0];
   docTest.ownerId = newUser._id;
   var newDoc = new Document(docTest);
   newDoc.save();

   // assign newDoc._id to a global varaible to be used in this suite
   docId = newDoc._id;
   userToken = jwt.sign(newUser, config.secret, {
    expiresIn: 86400 // expires in 24 hrs
   });
   done();
  });
  afterEach(function(done) {
   Document.remove({}, function() {
    User.remove({}, function() {
     Role.remove({}, function() {
      done();
     });
    });
   });
  });
  it("it should return all documents", function(done) {
   for (var i = 1, n = docData.length; i < n; i++) {
    var newRole = new Role(roleData[i]);
    var newUser = new User(userData[i]);
    newRole.save();
    newUser.save();
    var docDetail = docData[i];
    docDetail.ownerId = newUser._id;
    var newDoc = new Document(docDetail);
    newDoc.save();
   }

   request.get('/api/documents/')
   .set('x-access-token', userToken)
   .expect(200)
   .end(function(err, res) {
    expect(err).toBeNull();
    expect(res.body.length).toBe(3);
    expect(res.body[0]).toEqual(jasmine.objectContaining({
     title: 'The regalia',
     role: 'Documentarian',
     content: 'Kings and people of royal heritage are known for their great outward look at all times as a demonstration of their royalty'
    }));
    expect(res.body[1]).toEqual(jasmine.objectContaining({
     title: 'The quest for dividends of democracy',
     role: 'Trainer',
     content: 'Democracy without dividend is arnachy in disguise. Every through democratic institution must plan to deliver to the citizens they represent'
    }));
    expect(res.body[2]).toEqual(jasmine.objectContaining({
     title: 'The beautiful ones are not yet born',
     role: 'Librarian',
     content: 'It makes more sense when people understand the essence of existence rather outward beauty that fades away and is no more'
    }));
    done();
   });
  });
  it("should return all documents for a specific user on GET /api/users/:id/documents/", function(done) {
   var user1 = new User(userData[1]);
   user1.save();
   var doc1 = docData[1];
   var doc2 = docData[2];
   doc1.ownerId = user1._id;
   doc2.ownerId = user1._id;
   var newDoc1 = new Document(doc1);
   var newDoc2 = new Document(doc2);
   newDoc1.save();
   newDoc2.save();

   request.get('/api/users/' + user1._id + '/documents')
   .set('x-access-token', userToken)
   .expect(200)
   .end(function(err, res) {
    expect(res.body.length).toBe(2);
    expect(res.body[0]).toEqual(jasmine.objectContaining({
     title: 'The quest for dividends of democracy',
     role: 'Trainer',
     content: 'Democracy without dividend is arnachy in disguise. Every through democratic institution must plan to deliver to the citizens they represent'
    }));
    expect(res.body[1]).toEqual(jasmine.objectContaining({
     title: 'The beautiful ones are not yet born',
     role: 'Librarian',
     content: 'It makes more sense when people understand the essence of existence rather outward beauty that fades away and is no more'
    }));
    done();
   });
  });
  it("should not return document for an invalid user Id", function(done) {
   var invalidId = mongoose.Types.ObjectId('4edd40c86762e0fb12000003');
   request.delete('/api/documents/' + invalidId)
   .set('x-access-token', userToken)
   .expect(404)
   .end(function(err, res) {
    expect(res).not.toBeNull();
    expect(res.body).toEqual(jasmine.objectContaining({
     success: false,
     message: 'Document not available'
    }));
    done();
   });
  });
  it("should return document for an id", function(done) {
   request.get('/api/documents/' + docId)
   .set('x-access-token', userToken)
   .expect(200)
   .end(function(err, res) {
    expect(res).not.toBeNull();
    expect(res.body).toEqual(jasmine.objectContaining({
     title: 'The regalia',
     role: 'Documentarian',
     content: 'Kings and people of royal heritage are known for their great outward look at all times as a demonstration of their royalty'
    }));
    done();
   });
  });
  it("should not return any document for invalid id", function(done) {
   var invalidId = mongoose.Types.ObjectId('4edd40c86762e0fb12000003');
   request.get('/api/documents/' + invalidId)
   .set('x-access-token', userToken)
   .expect(404)
   .end(function(err, res) {
    expect(res).not.toBeNull();
    expect(res.body).toEqual(jasmine.objectContaining({
     success: false,
     message: 'No document found for the Id'
    }));
    done();
   });
  });
  it("should update document by id", function(done) {
   request.put('/api/documents/' + docId)
   .set('x-access-token', userToken)
   .expect(200)
   .send({
    title: 'Testing update route',
    content: 'Nice practicing and doing TDD'
   }).end(function(err, res) {
    expect(res.body).toEqual(jasmine.objectContaining({
     success: true,
     message: 'Document updated successfully'
    }));
    request.get('/api/documents/' + docId)
    .set('x-access-token', userToken)
    .expect(404)
    .end(function(err, res) {
     expect(res.body).toEqual(jasmine.objectContaining({
      title: 'Testing update route',
      content: 'Nice practicing and doing TDD'
     }));
     done();
    });
   });
  });
  it("should delete document by id", function(done) {
   request.delete('/api/documents/' + docId).expect(200)
   .set('x-access-token', userToken)
   .end(function(err, res) {
    expect(res.body).toEqual(jasmine.objectContaining({
     success: true,
     message: 'Document deleted successfully'
    }));
    request.get('/api/documents/' + docId)
    .expect(404)
    .set('x-access-token', userToken)
    .end(function(err, res) {
     expect(res.body).toEqual(jasmine.objectContaining({
      success: false,
      message: 'No document found for the Id'
     }));
     done();
    });
   });
  });
  it("should not delete  any document by an invalid id", function(done) {
   var invalidId = mongoose.Types.ObjectId('4edd40c86762e0fb12000003');
   request.delete('/api/documents/' + invalidId)
   .set('x-access-token', userToken)
   .expect(404)
   .end(function(err, res) {
    expect(res).not.toBeNull();
    expect(res.body).toEqual(jasmine.objectContaining({
     success: false,
     message: 'Document not available'
    }));
    done();
   });
  });
 });
});<|endoftext|>


<commit_before>/* eslint-env node, mocha */

var Client = require('../lib/nodejs/lib.js').Client;
var assert = require('chai').assert;
var process = require('process');
var sonicdHost = process.env.SONICD_HOST || 'wss://0.0.0.0:443';
var util = require('./util');

describe('ws sonicd', function() {

  var client = new Client(sonicdHost);

  it('should be able to handle multiple concurrent queries', function(done) {

    var connections = 1000;
    var checkWait = 1000; //1 second
    var messages = 1;
    var errs = [];
    var finished = 0;

    var query = {
      query: messages.toString(),
      config: {
        'progress-delay': 0,
        size: messages,
        indexed: true,
        class: 'SyntheticSource'
      }
    };

    function count(err) {
      if (err) {
        errs.push(err);
      }
      finished += 1;
    }

    function checkCondition() {
      console.log('checking if done..' + finished + '/' + connections);
      if (connections > finished) {
        setTimeout(checkCondition, checkWait);
      } else {
        console.log('done with load test: connections ' + connections + '; errors: ', errs.length);
        if (errs.length > 0) {
          done(new Error(JSON.stringify(errs)));
        } else {
          done();
        }
      }
    }

    for (var i = 0, len = connections; i < len; i++) {
      try {
        util.testHappyPathSingle(client, query, messages, count);
      } catch (e) {
        errs.push(e);
      }
    }

    checkCondition();
  }).timeout(100000);
});
<commit_msg>added support for passing load test's target connections as env var<commit_after>/* eslint-env node, mocha */

var Client = require('../lib/nodejs/lib.js').Client;
var assert = require('chai').assert;
var process = require('process');
var sonicdHost = process.env.SONICD_HOST || 'wss://0.0.0.0:443';
var util = require('./util');

describe('ws sonicd', function() {

  var client = new Client(sonicdHost);

  it('should be able to handle multiple concurrent queries', function(done) {

    var connections = parseInt(process.env.LOAD_TEST_CONN || '1000');
    var checkWait = 1000; //1 second
    var messages = 1;
    var errs = [];
    var finished = 0;

    var query = {
      query: messages.toString(),
      config: {
        'progress-delay': 0,
        size: messages,
        indexed: true,
        class: 'SyntheticSource'
      }
    };

    function count(err) {
      if (err) {
        errs.push(err);
      }
      finished += 1;
    }

    function checkCondition() {
      console.log('checking if done..' + finished + '/' + connections);
      if (connections > finished) {
        setTimeout(checkCondition, checkWait);
      } else {
        console.log('done with load test: connections ' + connections + '; errors: ', errs.length);
        if (errs.length > 0) {
          done(new Error(JSON.stringify(errs)));
        } else {
          done();
        }
      }
    }

    for (var i = 0, len = connections; i < len; i++) {
      try {
        util.testHappyPathSingle(client, query, messages, count);
      } catch (e) {
        errs.push(e);
      }
    }

    checkCondition();
  }).timeout(100000);
});
<|endoftext|>


<commit_before>(function() {
  shl.ui = {};

  shl.ui.createProspectTableView = function() {
    var data = [{title:"Row 1"},{title:"Row 2"}];
    return Titanium.UI.createTableView({data:data});
  };

  shl.ui.createAddWindow = function() {
    var win = Ti.UI.createWindow({
      title: 'Add Prospect',
      backgroundColor:'#eeeeee'
    });

    if (Ti.Platform.osname === 'iphone') {
      var b = Titanium.UI.createButton({
        title:'Close',
        style:Titanium.UI.iPhone.SystemButtonStyle.PLAIN
      });
      b.addEventListener('click',function() {
        win.close();
      });
      win.setRightNavButton(b);
    }

    var data = [];
    var s1 = Ti.UI.createTableViewSection();
    // First Name Field
    var fnameRow = Ti.UI.createTableViewRow({
      height: 40,
      layout: "vertical",
      selectionStyle: "none"
    });
    var fname = Ti.UI.createTextField({
      height:40,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('First Name')
    });
    fnameRow.add(fname);
    s1.add(fnameRow);
    // Last Name Field
    var lnameRow = Ti.UI.createTableViewRow({
      height: 40,
      layout: "vertical",
      selectionStyle: "none"
    });
    var lname = Ti.UI.createTextField({
      height:40,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('Last Name')
    });
    lnameRow.add(lname);
    s1.add(lnameRow);

    data.push(s1);

    var s2 = Ti.UI.createTableViewSection({
      borderColor: 'transparent',
      borderWidth: 0
    });
    var genderRow = Ti.UI.createTableViewRow({
      backgroundColor: 'transparent',
      borderWidth: 0,
      borderColor: 'transparent',
      height: 40,
      selectionStyle: "none"
    });
    if (Ti.Platform.osname != 'android') {
      var gender = Titanium.UI.createTabbedBar({
        labels: ['Male', 'Female', 'Couple'],
        backgroundColor: '#336699',
        style: Titanium.UI.iPhone.SystemButtonStyle.BAR,
        height: 45,
        width: 302
      });
      genderRow.add(gender);
    }
    s2.add(genderRow);
    data.push(s2);

    var s3 = Ti.UI.createTableViewSection();
    var streetRow = Ti.UI.createTableViewRow({
      height: 45,
      layout: "vertical",
      selectionStyle: "none"
    });
    var street = Ti.UI.createTextField({
      height:40,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('Street')
    });
    streetRow.add(street);
    s3.add(streetRow);
    var citystateRow = Ti.UI.createTableViewRow({
      height: 45,
      layout: "horizontal",
      selectionStyle: "none"
    });
    var city = Ti.UI.createTextField({
      width: 150,
      height:40,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('City')
    });
    var state = Ti.UI.createTextField({
      width: 150,
      height: 40,
      left: 0,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('State')
    });
    citystateRow.add(city);
    citystateRow.add(state);
    s3.add(citystateRow);
    data.push(s3);

    // Finally Make the TableView and add
    var tableView = Ti.UI.createTableView({
      data: data,
      style: Titanium.UI.iPhone.TableViewStyle.GROUPED
    });
    win.add(tableView);

    return win;
  };

  shl.ui.createAllWindow = function() {
    var win = Ti.UI.createWindow({
      title: 'All',
      activity: {
        onCreateOptionsMenu : function(e) {
          var menu = e.menu;
          var m1 = menu.add({title: 'Add'});
          m1.addEventListener('click', function(e) {
            shl.allTab.open(shl.ui.createAddWindow());
          });
        }
      }
    });
    win.add(shl.ui.createProspectTableView());

    if (Ti.Platform.osname === 'iphone') {
      var b = Ti.UI.createButton({
        title: 'Add',
        style: Ti.UI.iPhone.SystemButtonStyle.PLAIN
      });
      b.addEventListener('click', function() {
        shl.ui.createAddWindow().open({modal:true});
      });
      win.setRightNavButton(b);
    }
    return win;
  };

  shl.ui.createListsWindow = function() {
    var win = Ti.UI.createWindow({
      title: 'Lists',
      activity: {
        onCreateOptionsMenu : function(e) {
          var menu = e.menu;
          var m1 = menu.add({title: 'Add'});
          m1.addEventListener('click', function(e) {
            shl.allTab.open(shl.ui.createAddWindow());
          });
        }
      }
    });
    win.add(shl.ui.createProspectTableView());

    if (Ti.Platform.osname === 'iphone') {
      var b = Ti.UI.createButton({
        title: 'Add',
        style: Ti.UI.iPhone.SystemButtonStyle.PLAIN
      });
      b.addEventListener('click', function() {
        shl.ui.createAddWindow().open({modal:true});
      });
      win.setRightNavButton(b);
    }
    return win;
  };

  shl.ui.createSearchWindow = function() {
    var win = Ti.UI.createWindow({
      title: 'Search',
      activity: {
        onCreateOptionsMenu : function(e) {
          var menu = e.menu;
          var m1 = menu.add({title: 'Add'});
          m1.addEventListener('click', function(e) {
            shl.allTab.open(shl.ui.createAddWindow());
          });
        }
      }
    });
    win.add(shl.ui.createProspectTableView());

    if (Ti.Platform.osname === 'iphone') {
      var b = Ti.UI.createButton({
        title: 'Add',
        style: Ti.UI.iPhone.SystemButtonStyle.PLAIN
      });
      b.addEventListener('click', function() {
        shl.ui.createAddWindow().open({modal:true});
      });
      win.setRightNavButton(b);
    }
    return win;
  };

  shl.ui.createMoreWindow = function() {
    var win = Ti.UI.createWindow({
      title: 'More',
      activity: {
        onCreateOptionsMenu : function(e) {
          var menu = e.menu;
          var m1 = menu.add({title: 'Add'});
          m1.addEventListener('click', function(e) {
            shl.allTab.open(shl.ui.createAddWindow());
          });
        }
      }
    });
    win.add(shl.ui.createProspectTableView());

    if (Ti.Platform.osname === 'iphone') {
      var b = Ti.UI.createButton({
        title: 'Add',
        style: Ti.UI.iPhone.SystemButtonStyle.PLAIN
      });
      b.addEventListener('click', function() {
        shl.ui.createAddWindow().open({modal:true});
      });
      win.setRightNavButton(b);
    }
    return win;
  };

  shl.ui.createApplicationTabGroup = function() {
    var tabgroup = Ti.UI.createTabGroup();

    // all, lists, search, more
    var all = shl.ui.createAllWindow();
    var lists = shl.ui.createListsWindow();
    var search = shl.ui.createSearchWindow();
    var more = shl.ui.createMoreWindow();

    shl.allTab = Ti.UI.createTab({
      title: 'All',
      window: all,
      icon: 'images/112-group.png'
    });
    shl.listsTab = Ti.UI.createTab({
      title: 'Lists',
      window: lists,
      icon: 'images/179-notepad.png'
    });
    shl.searchTab = Ti.UI.createTab({
      title: 'Search',
      window: search,
      icon: 'images/06-magnify.png'
    });
    shl.moreTab = Ti.UI.createTab({
      title: 'More',
      window: more,
      icon: 'images/59-info.png'
    });

    tabgroup.addTab(shl.allTab);
    tabgroup.addTab(shl.listsTab);
    tabgroup.addTab(shl.searchTab);
    tabgroup.addTab(shl.moreTab);

    return tabgroup;
  };
})();
<commit_msg>added more interface to add prospect screen.<commit_after>(function() {
  shl.ui = {};

  shl.ui.createProspectTableView = function() {
    var data = [{title:"Row 1"},{title:"Row 2"}];
    return Titanium.UI.createTableView({data:data});
  };

  // TODO This looks nasty in android
  shl.ui.createAddWindow = function() {
    var win = Ti.UI.createWindow({
      title: 'Add Prospect',
      backgroundColor:'#eeeeee'
    });

    if (Ti.Platform.osname === 'iphone') {
      var b = Titanium.UI.createButton({
        title:'Close',
        style:Titanium.UI.iPhone.SystemButtonStyle.PLAIN
      });
      b.addEventListener('click',function() {
        win.close();
      });
      win.setRightNavButton(b);
    }

    var data = [];
    var s1 = Ti.UI.createTableViewSection();
    // First Name Field
    var fnameRow = Ti.UI.createTableViewRow({
      height: 40,
      layout: "vertical",
      selectionStyle: "none"
    });
    var fname = Ti.UI.createTextField({
      height:40,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('First Name')
    });
    fnameRow.add(fname);
    s1.add(fnameRow);
    // Last Name Field
    var lnameRow = Ti.UI.createTableViewRow({
      height: 40,
      layout: "vertical",
      selectionStyle: "none"
    });
    var lname = Ti.UI.createTextField({
      height:40,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('Last Name')
    });
    lnameRow.add(lname);
    s1.add(lnameRow);

    data.push(s1);

    var s2 = Ti.UI.createTableViewSection({
      borderColor: 'transparent',
      borderWidth: 0
    });
    var genderRow = Ti.UI.createTableViewRow({
      backgroundColor: 'transparent',
      borderWidth: 0,
      borderColor: 'transparent',
      height: 40,
      selectionStyle: "none"
    });
    if (Ti.Platform.osname != 'android') {
      var gender = Titanium.UI.createTabbedBar({
        labels: ['Male', 'Female', 'Couple'],
        backgroundColor: '#336699',
        style: Titanium.UI.iPhone.SystemButtonStyle.BAR,
        height: 45,
        width: 302
      });
      genderRow.add(gender);
    }
    s2.add(genderRow);
    data.push(s2);

    // TODO add spacing to front of fields
    var s3 = Ti.UI.createTableViewSection();
    var streetRow = Ti.UI.createTableViewRow({
      height: 45,
      layout: "vertical",
      selectionStyle: "none"
    });
    var street = Ti.UI.createTextField({
      height:40,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('Street')
    });
    streetRow.add(street);
    s3.add(streetRow);
    var citystateRow = Ti.UI.createTableViewRow({
      height: 45,
      layout: "horizontal",
      selectionStyle: "none"
    });
    var city = Ti.UI.createTextField({
      width: 149,
      height:40,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('City')
    });
    var sep1 = Ti.UI.createView({
      width: 1,
      height: 45,
      left: 0,
      backgroundColor: '#cccccc'
    });
    var state = Ti.UI.createTextField({
      width: 149,
      height: 40,
      left: 0,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('State')
    });
    citystateRow.add(city);
    citystateRow.add(sep1);
    citystateRow.add(state);
    s3.add(citystateRow);
    var zipcountryRow = Ti.UI.createTableViewRow({
      height: 45,
      layout: "horizontal",
      selectionStyle: "none"
    });
    var zip = Ti.UI.createTextField({
      width: 149,
      height:40,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('Zip')
    });
    var sep2 = Ti.UI.createView({
      width: 1,
      height: 45,
      left: 0,
      backgroundColor: '#cccccc'
    });
    // TODO Change to a picker instead of textfield
    var country = Ti.UI.createTextField({
      width: 149,
      height:40,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('Country')
    });
    zipcountryRow.add(zip);
    zipcountryRow.add(sep2);
    zipcountryRow.add(country);
    s3.add(zipcountryRow);
    data.push(s3);

    // Phone Number section
    var s4 = Ti.UI.createTableViewSection();
    var homeRow = Ti.UI.createTableViewRow({
      height: 45,
      layout: "horizontal",
      selectionStyle: "none"
    });
    var homeLabel = Ti.UI.createLabel({
      text: 'Home',
      font: {fontWeight: 'bold', fontSize: 16},
      height: 45,
      width: 75,
      left: 10
    });
    var sep3 = Ti.UI.createView({
      width: 1,
      height: 45,
      left: 0,
      backgroundColor: '#cccccc'
    });
    var homeText = Ti.UI.createTextField({
      width: 200,
      height:40,
      left: 5,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
    });
    homeRow.add(homeLabel);
    homeRow.add(sep3);
    homeRow.add(homeText);
    s4.add(homeRow);
    var mobileRow = Ti.UI.createTableViewRow({
      height: 45,
      layout: "horizontal",
      selectionStyle: "none"
    });
    var mobileLabel = Ti.UI.createLabel({
      text: 'Mobile',
      font: {fontWeight: 'bold', fontSize: 16},
      height: 45,
      width: 75,
      left: 10
    });
    var sep4 = Ti.UI.createView({
      width: 1,
      height: 45,
      left: 0,
      backgroundColor: '#cccccc'
    });
    var mobileText = Ti.UI.createTextField({
      width: 200,
      height:40,
      left: 5,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
    });
    mobileRow.add(mobileLabel);
    mobileRow.add(sep4);
    mobileRow.add(mobileText);
    s4.add(mobileRow);
    data.push(s4);

    // Email field
    var s5 = Ti.UI.createTableViewSection();
    var emailRow = Ti.UI.createTableViewRow({
      height: 45,
      layout: "horizontal",
      selectionStyle: "none"
    });
    var email = Ti.UI.createTextField({
      width: 280,
      height: 40,
      left: 10,
      keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
      returnKeyType:Titanium.UI.RETURNKEY_DONE,
      borderStyle:Titanium.UI.INPUT_BORDERSTYLE_NONE,
      hintText:L('Email')
    });
    emailRow.add(email);
    s5.add(emailRow);
    data.push(s5);

    // Finally Make the TableView and add
    var tableView = Ti.UI.createTableView({
      data: data,
      style: Titanium.UI.iPhone.TableViewStyle.GROUPED
    });
    win.add(tableView);

    return win;
  };

  shl.ui.createAllWindow = function() {
    var win = Ti.UI.createWindow({
      title: 'All',
      activity: {
        onCreateOptionsMenu : function(e) {
          var menu = e.menu;
          var m1 = menu.add({title: 'Add'});
          m1.addEventListener('click', function(e) {
            shl.allTab.open(shl.ui.createAddWindow());
          });
        }
      }
    });
    win.add(shl.ui.createProspectTableView());

    if (Ti.Platform.osname === 'iphone') {
      var b = Ti.UI.createButton({
        title: 'Add',
        style: Ti.UI.iPhone.SystemButtonStyle.PLAIN
      });
      b.addEventListener('click', function() {
        shl.ui.createAddWindow().open({modal:true});
      });
      win.setRightNavButton(b);
    }
    return win;
  };

  shl.ui.createListsWindow = function() {
    var win = Ti.UI.createWindow({
      title: 'Lists',
      activity: {
        onCreateOptionsMenu : function(e) {
          var menu = e.menu;
          var m1 = menu.add({title: 'Add'});
          m1.addEventListener('click', function(e) {
            shl.allTab.open(shl.ui.createAddWindow());
          });
        }
      }
    });
    win.add(shl.ui.createProspectTableView());

    if (Ti.Platform.osname === 'iphone') {
      var b = Ti.UI.createButton({
        title: 'Add',
        style: Ti.UI.iPhone.SystemButtonStyle.PLAIN
      });
      b.addEventListener('click', function() {
        shl.ui.createAddWindow().open({modal:true});
      });
      win.setRightNavButton(b);
    }
    return win;
  };

  shl.ui.createSearchWindow = function() {
    var win = Ti.UI.createWindow({
      title: 'Search',
      activity: {
        onCreateOptionsMenu : function(e) {
          var menu = e.menu;
          var m1 = menu.add({title: 'Add'});
          m1.addEventListener('click', function(e) {
            shl.allTab.open(shl.ui.createAddWindow());
          });
        }
      }
    });
    win.add(shl.ui.createProspectTableView());

    if (Ti.Platform.osname === 'iphone') {
      var b = Ti.UI.createButton({
        title: 'Add',
        style: Ti.UI.iPhone.SystemButtonStyle.PLAIN
      });
      b.addEventListener('click', function() {
        shl.ui.createAddWindow().open({modal:true});
      });
      win.setRightNavButton(b);
    }
    return win;
  };

  shl.ui.createMoreWindow = function() {
    var win = Ti.UI.createWindow({
      title: 'More',
      activity: {
        onCreateOptionsMenu : function(e) {
          var menu = e.menu;
          var m1 = menu.add({title: 'Add'});
          m1.addEventListener('click', function(e) {
            shl.allTab.open(shl.ui.createAddWindow());
          });
        }
      }
    });
    win.add(shl.ui.createProspectTableView());

    if (Ti.Platform.osname === 'iphone') {
      var b = Ti.UI.createButton({
        title: 'Add',
        style: Ti.UI.iPhone.SystemButtonStyle.PLAIN
      });
      b.addEventListener('click', function() {
        shl.ui.createAddWindow().open({modal:true});
      });
      win.setRightNavButton(b);
    }
    return win;
  };

  shl.ui.createApplicationTabGroup = function() {
    var tabgroup = Ti.UI.createTabGroup();

    // all, lists, search, more
    var all = shl.ui.createAllWindow();
    var lists = shl.ui.createListsWindow();
    var search = shl.ui.createSearchWindow();
    var more = shl.ui.createMoreWindow();

    shl.allTab = Ti.UI.createTab({
      title: 'All',
      window: all,
      icon: 'images/112-group.png'
    });
    shl.listsTab = Ti.UI.createTab({
      title: 'Lists',
      window: lists,
      icon: 'images/179-notepad.png'
    });
    shl.searchTab = Ti.UI.createTab({
      title: 'Search',
      window: search,
      icon: 'images/06-magnify.png'
    });
    shl.moreTab = Ti.UI.createTab({
      title: 'More',
      window: more,
      icon: 'images/59-info.png'
    });

    tabgroup.addTab(shl.allTab);
    tabgroup.addTab(shl.listsTab);
    tabgroup.addTab(shl.searchTab);
    tabgroup.addTab(shl.moreTab);

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


<commit_before>var app = require('app');
var ipc = require('ipc');
var dialog = require('dialog');
var BrowserWindow = require('browser-window');
var Menu = require('menu');

var window = null;

app.commandLine.appendSwitch('js-flags', '--expose_gc');

ipc.on('message', function() {
  ipc.send.apply(this, arguments);
});

ipc.on('console.log', function(pid, rid, args) {
  console.log.apply(console, args);
});

ipc.on('console.error', function(pid, rid, args) {
  console.log.apply(console, args);
});

ipc.on('process.exit', function(pid, rid, code) {
  process.exit(code);
});

ipc.on('eval', function(ev, pid, rid, script) {
  ev.returnValue = eval(script);
});

ipc.on('echo', function(ev, pid, rid, msg) {
  ev.returnValue = msg;
});

process.on('uncaughtException', function() {
  window.openDevTools();
});

app.on('window-all-closed', function() {
  app.terminate();
});

app.on('finish-launching', function() {
  var template = [
    {
      label: 'Atom',
      submenu: [
        {
          label: 'Quit',
          accelerator: 'Command+Q',
          click: function(item, window) { app.quit(); }
        },
      ],
    },
    {
      label: 'Window',
      submenu: [
        {
          label: 'Open',
          accelerator: 'Command+O',
        },
        {
          label: 'Close',
          accelerator: 'Command+W',
          click: function(item, window) { window.close(); }
        },
      ]
    },
    {
      label: 'View',
      submenu: [
        {
          label: 'Reload',
          accelerator: 'Command+R',
          click: function(item, window) { window.restart(); }
        },
        {
          label: 'Enter Fullscreen',
          click: function(item, window) { window.setFullScreen(true); }
        },
        {
          label: 'Toggle DevTools',
          accelerator: 'Alt+Command+I',
          click: function(item, window) { window.toggleDevTools(); }
        },
      ]
    },
    {
      label: 'Help',
      submenu: [],
    }
  ];

  var menu = Menu.buildFromTemplate(template);
  app.setApplicationMenu(menu);

  // Test if using protocol module would crash.
  require('protocol').registerProtocol('test-if-crashes', function() {});

  window = new BrowserWindow({
    title: 'atom-shell tests',
    show: false,
    width: 800,
    height: 600
  });
  window.loadUrl('file://' + __dirname + '/index.html');
  window.on('unresponsive', function() {
    var chosen = dialog.showMessageBox(window, {
      type: 'warning',
      buttons: ['Close', 'Keep Waiting'],
      message: 'Window is not responsing',
      detail: 'The window is not responding. Would you like to force close it or just keep waiting?'
    });
    if (chosen == 0) window.destroy();
  });
});
<commit_msg>Use CommandOrControl to replace Command in specs windows.<commit_after>var app = require('app');
var ipc = require('ipc');
var dialog = require('dialog');
var BrowserWindow = require('browser-window');
var Menu = require('menu');

var window = null;

app.commandLine.appendSwitch('js-flags', '--expose_gc');

ipc.on('message', function() {
  ipc.send.apply(this, arguments);
});

ipc.on('console.log', function(pid, rid, args) {
  console.log.apply(console, args);
});

ipc.on('console.error', function(pid, rid, args) {
  console.log.apply(console, args);
});

ipc.on('process.exit', function(pid, rid, code) {
  process.exit(code);
});

ipc.on('eval', function(ev, pid, rid, script) {
  ev.returnValue = eval(script);
});

ipc.on('echo', function(ev, pid, rid, msg) {
  ev.returnValue = msg;
});

process.on('uncaughtException', function() {
  window.openDevTools();
});

app.on('window-all-closed', function() {
  app.terminate();
});

app.on('finish-launching', function() {
  var template = [
    {
      label: 'Atom',
      submenu: [
        {
          label: 'Quit',
          accelerator: 'CommandOrControl+Q',
          click: function(item, window) { app.quit(); }
        },
      ],
    },
    {
      label: 'Window',
      submenu: [
        {
          label: 'Open',
          accelerator: 'CommandOrControl+O',
        },
        {
          label: 'Close',
          accelerator: 'CommandOrControl+W',
          click: function(item, window) { window.close(); }
        },
      ]
    },
    {
      label: 'View',
      submenu: [
        {
          label: 'Reload',
          accelerator: 'CommandOrControl+R',
          click: function(item, window) { window.restart(); }
        },
        {
          label: 'Enter Fullscreen',
          click: function(item, window) { window.setFullScreen(true); }
        },
        {
          label: 'Toggle DevTools',
          accelerator: 'Alt+CommandOrControl+I',
          click: function(item, window) { window.toggleDevTools(); }
        },
      ]
    },
    {
      label: 'Help',
      submenu: [],
    }
  ];

  var menu = Menu.buildFromTemplate(template);
  app.setApplicationMenu(menu);

  // Test if using protocol module would crash.
  require('protocol').registerProtocol('test-if-crashes', function() {});

  window = new BrowserWindow({
    title: 'atom-shell tests',
    show: false,
    width: 800,
    height: 600
  });
  window.loadUrl('file://' + __dirname + '/index.html');
  window.on('unresponsive', function() {
    var chosen = dialog.showMessageBox(window, {
      type: 'warning',
      buttons: ['Close', 'Keep Waiting'],
      message: 'Window is not responsing',
      detail: 'The window is not responding. Would you like to force close it or just keep waiting?'
    });
    if (chosen == 0) window.destroy();
  });
});
<|endoftext|>


<commit_before>/*
 *
 * Spies are functions that keep track of how and often they were called, and what values were returned. This is phenomenally useful in asynchronous and event-driven applications as you can send a spy function off to keep track of what’s going on inside your methods, even if those methods are anonymous or closed off from direct inspection.
 */

(function() {
	var specs = [];

	describe("Sinon spy on Backbone Episode model", function() {
//		it("should fire a callback when 'foo' is triggered", function() {
//			// Create an anonymous spy
//			var spy = sinon.spy();
//
//			// Create a new Backbone 'Episode' model
//			var episode = new Backbone.Model({
//				title : "Hollywood - Part 2",
//				url: "/episodes/1"
//			});
//
//			// Call the anonymous spy method when 'foo' is triggered
//			episode.bind('foo', spy);
//
//			// Trigger the foo event
//			episode.trigger('foo');
//			// Expect that the spy was called at least once
//			expect(spy.called).toBeTruthy();
//		});
		it("should make the correct server request", function() {

			  var episode = new Backbone.Model({
			    title: "Hollywood - Part 2",
			    url: "/episodes/1"
			  });
			  episode.url ="/episodes/1";
			  // Spy on jQuery's ajax method
			  jQuery.ajax.restore();
			  var spy = sinon.spy(jQuery, 'ajax');

			  // Save the model
			  episode.save();

			  // Spy was called
//			  expect(spy).toHaveBeenCalled();
			  // Check url property of first argument
			  expect(spy.getCall(0).args[0].url)
			    .toEqual("/episodes/1");

			  // Restore jQuery.ajax to normal
			  jQuery.ajax.restore();
			});
	});

})();
/*
 * Fake server: http://msdn.microsoft.com/en-us/magazine//gg649850.aspx
 *
 * var blog = { posts : {},
 *
 * getPost : function(id, callback, errback) { if (this.posts[id]) { typeof
 * callback == "function" && callback(posts[id]); return; }
 *
 * jQuery.ajax({ url : "/posts/" + id, type : "get", dataType : "json",
 *
 * success : function(data, status, xhr) { this.posts[id] = data; typeof
 * callback == "function" && callback(data); },
 *
 * errback : function(xhr, status, exception) { typeof callback == "function" &&
 * errback(status); } }); },
 *
 * savePost : function(blogPost, callback, errback) { // ... } };
 * TestCase("BlogPostServiceTest", sinon.testCase({ setUp : function() {
 * this.server.respondWith("GET", "/posts/312", [ 200, { "Content-Type" :
 * "application/json" }, '{"title":"Unit test your
 * JavaScript","author":"Christian Johansen"' + ',"text":"..."}' ]); },
 *
 * "test should call callback with parsed data from server" : function() { var
 * blogPost;
 *
 * blog.getPost(312, function(post) { blogPost = post; });
 *
 * this.server.respond();
 *
 * assertEquals({ title : "Unit test your JavaScript", author : "Christian
 * Johansen", text : "..." }, blogPost); } }));
 *
 */
<commit_msg>backbone tests using fake server<commit_after>/*
 *
 * Spies are functions that keep track of how and often they were called, and what values were returned. This is phenomenally useful in asynchronous and event-driven applications as you can send a spy function off to keep track of what’s going on inside your methods, even if those methods are anonymous or closed off from direct inspection.
 */

(function() {
	var specs = [];

	describe("Sinon spy on Backbone Episode model", function() {
		beforeEach(function() {
			this.server = sinon.fakeServer.create();
		});

		afterEach(function() {
			this.server.restore();
		});

		it("should fire the change event", function() {

			var Episode = Backbone.Model.extend({
				  url: function() {
				    return "/episode/" + this.id;
				  }
				});

			var callback = sinon.spy();

			// Set how the fake server will respond
			// This reads: a GET request for /episode/123
			// will return a 200 response of type
			// application/json with the given JSON response body
			this.server.respondWith("GET", "/episode/123", [ 200, {
				"Content-Type" : "application/json"
			}, '{"id":123,"title":"Hollywood - Part 2"}' ]);

			var episode = new Episode({
				id : 123
			});

			// Bind to the change event on the model
			episode.bind('change', callback);

			// makes an ajax request to the server
			episode.fetch();

			// Fake server responds to the request
			this.server.respond();

			// Expect that the spy was called with the new model
			expect(callback.called).toBeTruthy();
			expect(callback.getCall(0).args[0].attributes).toEqual({
				id : 123,
				title : "Hollywood - Part 2"
			});

		});

	});

})();<|endoftext|>