<commit_before>/* test/device_routes_test.js -- test Device routes
 * Copyright 2014 Sergei Ianovich
 *
 * Licensed under AGPL-3.0 or later, see LICENSE
 * Process Control Service Web Interface
 */

var expect = require('expect.js');
var Device = require('../models/device');
var Routes = require('../routes/device');
var router = require('./support/router');

var deviceAttrs = {
  name: "Some device",
};

describe('Device routes', function() {
  var device;
  before(function(done) {
    Factory.create('device', function (d) { device = d; done(); });
  });

  var operator;
  before(function(done) {
    Factory.create('user', function (u) { operator = u; done(); });
  });

  var admin;
  before(function(done) {
    Factory.create('admin', function (a) { admin = a; done(); });
  });

  describe("#load", function() {
    it("should find by id and assign device to req", function(done) {
      var req = { },
      id = device._id;

      Routes.load(req, {}, function() {
        expect(req.device.toJSON()).to.eql(device.toJSON());
        done();
      }, id);
    });

    it("should respond with not found code", function(done) {
      var res = {
        send: function(code) {
          expect(code).to.eql(404);
          done();
        }
      };
      Routes.load({}, res, null, 0);
    });
  });

  describe("#show", function() {
    it("should deny access to non-signed-in users", function(done) {
      var req = { session: {} },
      res = { redirect: function(url) {
        expect(url).to.eql("/signin");
        done();
      }};
      router(Routes.show, req, res);
    });

    describe("when operator logged in", function() {
      var req;

      beforeEach(function() {
        req = { session: { operatorId: operator._id } };
      });

      it("should return 404 if no device", function(done) {
        var res = {
          locals: {},
          send: function(code) {
            expect(code).to.be(404);
            done();
          },
        };
        router(Routes.show, req, res);
      });

      it("should return only accessible fields", function(done) {
        var res = {
          locals: {},
          json_ng: function(dev) {
            expect(Object.keys(dev)).to.eql(['_id', 'name']);
            expect(dev._id).to.eql(device._id);
            expect(dev.name).to.eql(device.name);
            done();
          },
        };
        req.device = device;
        req.device.some_field = true;
        router(Routes.show, req, res);
      });
    });
  });

  describe("#update", function() {
    it("should deny access to non-signed-in users", function(done) {
      var req = { session: {} },
      res = { redirect: function(url) {
        expect(url).to.eql("/signin");
        done();
      }};
      router(Routes.update, req, res);
    });

    describe("when operator signed in", function() {
      var req;

      beforeEach(function() {
        req = { session: { operatorId: operator._id } };
      });

      it("should deny non-admins", function(done) {
        res = {
          locals: {},
          send: function(code) {
            expect(code).to.eql(403);
            done();
          },
        };
        router(Routes.update, req, res);
      });
    });

    describe("when administrator signed in", function() {
      var req;

      beforeEach(function() {
        req = { session: { operatorId: admin._id } };
      });

      it("should fail", function(done) {
        var res = {
          locals: {},
          json: function(code) {
            expect(code).to.eql(500);
            done();
          },
        };
        req.body = {
          name: "Some name",
        };
        req.device = device;
        router(Routes.update, req, res);
      });
    });
  });

  describe("#index", function() {
    it("should deny access to non-signed-in users", function(done) {
      var req = { session: {} },
      res = { redirect: function(url) {
        expect(url).to.eql("/signin");
        done();
      }};
      router(Routes.index, req, res);
    });
  });
});

// vim:ts=2 sts=2 sw=2 et:
<commit_msg>tests: routes: index first 25 devices<commit_after>/* test/device_routes_test.js -- test Device routes
 * Copyright 2014 Sergei Ianovich
 *
 * Licensed under AGPL-3.0 or later, see LICENSE
 * Process Control Service Web Interface
 */

var expect = require('expect.js');
var Device = require('../models/device');
var Routes = require('../routes/device');
var router = require('./support/router');

var deviceAttrs = {
  name: "Some device",
};

describe('Device routes', function() {
  var device, count;
  before(function(done) {
    Factory.create('device', 26, function (l) {
      device = l[0];
      Device.count(function (err, c) {
        if (err) throw err;
        count = c;
        done();
      });
    });
  });

  var operator;
  before(function(done) {
    Factory.create('user', function (u) { operator = u; done(); });
  });

  var admin;
  before(function(done) {
    Factory.create('admin', function (a) { admin = a; done(); });
  });

  describe("#load", function() {
    it("should find by id and assign device to req", function(done) {
      var req = { },
      id = device._id;

      Routes.load(req, {}, function() {
        expect(req.device.toJSON()).to.eql(device.toJSON());
        done();
      }, id);
    });

    it("should respond with not found code", function(done) {
      var res = {
        send: function(code) {
          expect(code).to.eql(404);
          done();
        }
      };
      Routes.load({}, res, null, 0);
    });
  });

  describe("#show", function() {
    it("should deny access to non-signed-in users", function(done) {
      var req = { session: {} },
      res = { redirect: function(url) {
        expect(url).to.eql("/signin");
        done();
      }};
      router(Routes.show, req, res);
    });

    describe("when operator logged in", function() {
      var req;

      beforeEach(function() {
        req = { session: { operatorId: operator._id } };
      });

      it("should return 404 if no device", function(done) {
        var res = {
          locals: {},
          send: function(code) {
            expect(code).to.be(404);
            done();
          },
        };
        router(Routes.show, req, res);
      });

      it("should return only accessible fields", function(done) {
        var res = {
          locals: {},
          json_ng: function(dev) {
            expect(Object.keys(dev)).to.eql(['_id', 'name']);
            expect(dev._id).to.eql(device._id);
            expect(dev.name).to.eql(device.name);
            done();
          },
        };
        req.device = device;
        req.device.some_field = true;
        router(Routes.show, req, res);
      });
    });
  });

  describe("#update", function() {
    it("should deny access to non-signed-in users", function(done) {
      var req = { session: {} },
      res = { redirect: function(url) {
        expect(url).to.eql("/signin");
        done();
      }};
      router(Routes.update, req, res);
    });

    describe("when operator signed in", function() {
      var req;

      beforeEach(function() {
        req = { session: { operatorId: operator._id } };
      });

      it("should deny non-admins", function(done) {
        res = {
          locals: {},
          send: function(code) {
            expect(code).to.eql(403);
            done();
          },
        };
        router(Routes.update, req, res);
      });
    });

    describe("when administrator signed in", function() {
      var req;

      beforeEach(function() {
        req = { session: { operatorId: admin._id } };
      });

      it("should fail", function(done) {
        var res = {
          locals: {},
          json: function(code) {
            expect(code).to.eql(500);
            done();
          },
        };
        req.body = {
          name: "Some name",
        };
        req.device = device;
        router(Routes.update, req, res);
      });
    });
  });

  describe("#index", function() {
    it("should deny access to non-signed-in users", function(done) {
      var req = { session: {} },
      res = { redirect: function(url) {
        expect(url).to.eql("/signin");
        done();
      }};
      router(Routes.index, req, res);
    });

    describe("when operator signed in", function() {
      var req;

      beforeEach(function() {
        req = { session: { operatorId: operator._id } };
        req.query = {};
        res = {
          locals: {},
        };
      });

      it("should retrieve first page if not specified", function(done) {
        res.json_ng = function(devices) {
          expect(devices.length).to.be(26);
          expect(devices[25].count).to.be(count);
          done();
        };
        router(Routes.index, req, res);
      });
    });
  });
});

// vim:ts=2 sts=2 sw=2 et:
<|endoftext|>


<commit_before>
const StencilLib = {

	featureOnBeforeRender: function ( renderer ) {

		const stencil = renderer.state.buffers.stencil;
		const gl = renderer.context;

		stencil.setTest( true );

		stencil.setOp( gl.KEEP, gl.KEEP, gl.INCR );
		stencil.setFunc( gl.ALWAYS );

	},

	featureOnAfterRender: function ( renderer ) {

		const stencil = renderer.state.buffers.stencil;

		stencil.setTest( false );

	},

	terrainOnBeforeRender: function ( renderer ) {

		const stencil = renderer.state.buffers.stencil;
		const gl = renderer.context;

		stencil.setTest( true );
		stencil.setFunc( gl.EQUAL, 0, 0xFFFF );

	},

	terrainOnAfterRender: function ( renderer ) {

		const stencil = renderer.state.buffers.stencil;

		stencil.setTest( false );

	}

};

export { StencilLib };
<commit_msg>prevent faulty break through of terrain (tiled only)<commit_after>
const StencilLib = {

	featureOnBeforeRender: function ( renderer ) {

		const stencil = renderer.state.buffers.stencil;
		const gl = renderer.context;

		stencil.setTest( true );

		stencil.setOp( gl.KEEP, gl.KEEP, gl.INCR );
		stencil.setFunc( gl.ALWAYS );

	},

	featureOnAfterRender: function ( renderer ) {

		const stencil = renderer.state.buffers.stencil;

		stencil.setTest( false );

	},

	terrainOnBeforeRender: function ( renderer ) {

		const stencil = renderer.state.buffers.stencil;
		const gl = renderer.context;

		stencil.setTest( true );
		stencil.setOp( gl.KEEP, gl.KEEP, gl.KEEP );
		stencil.setFunc( gl.EQUAL, 0, 0xFFFF );

	},

	terrainOnAfterRender: function ( renderer ) {

		const stencil = renderer.state.buffers.stencil;

		stencil.setTest( false );

	}

};

export { StencilLib };
<|endoftext|>


<commit_before>import test from 'ava';
import r from 'randomstring';
import LogSuppress from '../lib/log-suppress';

LogSuppress.init(console);

const environment = r.generate();
const { Requester, Responder } = require('../')({ environment });

test.cb('Supports directed requests targeted at single responder using callbacks', (t) => {
    const key = r.generate();
    const namespace = r.generate();
    const subset = r.generate();

    const targetResponder = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace, subset },
        { log: false });

    const wrongResponder = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace },
        { log: false });

    const requester = new Requester(
        { name: `PBR ${t.title}: directed requester`,
            key,
            namespace }, { log: false });

    const args = [1, 2, 6];

    // Send the request twice. It should end up in the same Responder both times
    // Also make sure the wrongResponder is connected
    wrongResponder.sock.on('bind', () => {
        requester.send({ __subset: subset, type: 'test', args }, (res) => {
            t.deepEqual(res, args);
            requester.send({ __subset: subset, type: 'test', args }, (res) => {
                t.deepEqual(res, args);
                t.end();
            });
        });
    });

    targetResponder.on('test', (req, cb) => {
        t.deepEqual(req.args, args);
        cb(req.args);
    });

    wrongResponder.on('test', (req, cb) => {
        t.fail('Not targeted responder should have never gotten a message');
        t.end();
    });
});

test('Supports directed requests targeted at multiple targeted requesters using promises', async (t) => {
    // Times to send requests, times/nrOfRequesters has to result in a just number
    const times = 10;
    const nrOfRequesters = 2;

    const key = r.generate();
    const namespace = r.generate();
    const subset = r.generate();
    const subset2 = r.generate();

    const responders = [];
    Array.from({ length: nrOfRequesters }).forEach(() => {
        const responder = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace, subset },
            { log: false });
        responder.count = 0;
        responder.on('test', async (req) => {
            responder.count++;
            return req.args;
        });
        responders.push(responder);
    });

    // Normal responder without subset
    const wrongResponder = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace },
        { log: false });
    wrongResponder.on('test', () => {
        t.fail('Not targeted responder should have never gotten a message');
    });

    // Responder in different subset
    const wrongResponder2 = new Responder({
        name: `PBR ${t.title}: directed responder`, key, namespace, subset: subset2,
    }, { log: false });
    wrongResponder2.on('test', () => {
        t.fail('Not targeted responder should have never gotten a message');
    });

    const requester = new Requester(
        { name: `PBR ${t.title}: directed requester`,
            key,
            namespace }, { log: false });

    const args = [1, 2, 6];
    // Send the request multiple times
    // It should end up in the both requesters somewhat
    // evenly distributed, but never in the wrong one
    for (let index = 0; index < times; index++) {
        await requester.send({ __subset: subset, type: 'test', args });
    }

    const totalRecieved = responders.reduce((accumulator, responder) => {
    // Both should have at least gotten one request
        t.true(responder.count > 0);
        return accumulator += responder.count;
    }, 0);

    t.is(totalRecieved, times);
});

test('Timeout works with directed requester', async (t) => {
    const key = r.generate();
    const namespace = r.generate();
    const subset = r.generate();

    const requester = new Requester({ name: `PBR ${t.title}: directed requester`, key, namespace, subset },
        { log: false });

    try {
        await requester.send({
            __subset: subset,
            __timeout: 1000,
            type: 'test',
            args: [1, 2, 6] });
        t.fail();
    } catch (error) {
        if (error.message.includes('Request timed out')) return t.pass();
        t.fail(error);
    }
});

test('Queuing works with directed requester', async (t) => {
    const key = r.generate();
    const namespace = r.generate();
    const subset = r.generate();
    const subset2 = r.generate();
    const args = [1, 2, 6];
    const requester = new Requester({ name: `PBR ${t.title}: directed requester`, key, namespace, subset },
        { log: false, checkInterval: 500 });

    const responder = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace, subset },
        { log: false, checkInterval: 500 });
    responder.on('test', async (req) => {
        return req.args;
    });

    // Make sure it does not sent to the wrong responder in a different subset
    // when there are no other responders available
    const responder2 = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace, subset: subset2 },
        { log: false, checkInterval: 500 });
    responder2.on('test', async (req) => {
        t.fail();
    });

    try {
    // Send an receive
        const res = await requester.send({
            __subset: subset,
            type: 'test',
            args });
        t.deepEqual(res, args);

        // Destroy responder and wait for heartbeat
        responder.close();
        await wait(501);

        // Next request
        let pending = true;
        const promise = requester.send({
            __subset: subset,
            type: 'test',
            args })
            .then((res) => {
                pending = false;
                return res;
            });
        await wait(500);
        t.true(pending);

        // Recreate responder
        const responder2 = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace, subset },
            { log: false });
        responder2.on('test', async (req) => {
            return req.args;
        });

        // make sure it received the message
        const res2 = await promise;
        t.false(pending);
        t.deepEqual(res2, args);
    } catch (error) {
        t.fail(error);
    }
});

function wait(ms) {
    return new Promise((res) => {
        setTimeout(() => {
            res();
        }, ms);
    });
}
<commit_msg>Introduce delays in directed requester tests to increase test stability<commit_after>import test from 'ava';
import r from 'randomstring';
import LogSuppress from '../lib/log-suppress';

LogSuppress.init(console);

const environment = r.generate();
const { Requester, Responder } = require('../')({ environment });

test.cb('Supports directed requests targeted at single responder using callbacks', (t) => {
    const key = r.generate();
    const namespace = r.generate();
    const subset = r.generate();

    const targetResponder = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace, subset },
        { log: false });

    const wrongResponder = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace },
        { log: false });

    const requester = new Requester(
        { name: `PBR ${t.title}: directed requester`,
            key,
            namespace }, { log: false });

    const args = [1, 2, 6];

    // Send the request twice. It should end up in the same Responder both times
    // Also make sure the wrongResponder is connected
    wrongResponder.sock.on('bind', () => {
        requester.send({ __subset: subset, type: 'test', args }, (res) => {
            t.deepEqual(res, args);
            requester.send({ __subset: subset, type: 'test', args }, (res) => {
                t.deepEqual(res, args);
                t.end();
            });
        });
    });

    targetResponder.on('test', (req, cb) => {
        t.deepEqual(req.args, args);
        cb(req.args);
    });

    wrongResponder.on('test', (req, cb) => {
        t.fail('Not targeted responder should have never gotten a message');
        t.end();
    });
});

test('Supports directed requests targeted at multiple targeted requesters using promises', async (t) => {
    // Times to send requests, times/nrOfRequesters has to result in a just number
    const times = 10;
    const nrOfRequesters = 2;

    const key = r.generate();
    const namespace = r.generate();
    const subset = r.generate();
    const subset2 = r.generate();

    const responders = [];
    Array.from({ length: nrOfRequesters }).forEach(() => {
        const responder = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace, subset },
            { log: false });
        responder.count = 0;
        responder.on('test', async (req) => {
            responder.count++;
            return req.args;
        });
        responders.push(responder);
    });

    // Normal responder without subset
    const wrongResponder = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace },
        { log: false });
    wrongResponder.on('test', () => {
        t.fail('Not targeted responder should have never gotten a message');
    });

    // Responder in different subset
    const wrongResponder2 = new Responder({
        name: `PBR ${t.title}: directed responder`, key, namespace, subset: subset2,
    }, { log: false });
    wrongResponder2.on('test', () => {
        t.fail('Not targeted responder should have never gotten a message');
    });

    const requester = new Requester(
        { name: `PBR ${t.title}: directed requester`,
            key,
            namespace }, { log: false });

    const args = [1, 2, 6];
    // Send the request multiple times
    // It should end up in the both requesters somewhat
    // evenly distributed, but never in the wrong one
    for (let index = 0; index < times; index++) {
        await new Promise((resolve) => setTimeout(resolve, 50));
        await requester.send({ __subset: subset, type: 'test', args });
    }

    const totalRecieved = responders.reduce((accumulator, responder) => {
    // Both should have at least gotten one request
        t.true(responder.count > 0);
        return accumulator += responder.count;
    }, 0);

    t.is(totalRecieved, times);
});

test('Timeout works with directed requester', async (t) => {
    const key = r.generate();
    const namespace = r.generate();
    const subset = r.generate();

    const requester = new Requester({ name: `PBR ${t.title}: directed requester`, key, namespace, subset },
        { log: false });

    try {
        await requester.send({
            __subset: subset,
            __timeout: 1000,
            type: 'test',
            args: [1, 2, 6] });
        t.fail();
    } catch (error) {
        if (error.message.includes('Request timed out')) return t.pass();
        t.fail(error);
    }
});

test('Queuing works with directed requester', async (t) => {
    const key = r.generate();
    const namespace = r.generate();
    const subset = r.generate();
    const subset2 = r.generate();
    const args = [1, 2, 6];
    const requester = new Requester({ name: `PBR ${t.title}: directed requester`, key, namespace, subset },
        { log: false, checkInterval: 500 });

    const responder = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace, subset },
        { log: false, checkInterval: 500 });
    responder.on('test', async (req) => {
        return req.args;
    });

    // Make sure it does not sent to the wrong responder in a different subset
    // when there are no other responders available
    const responder2 = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace, subset: subset2 },
        { log: false, checkInterval: 500 });
    responder2.on('test', async (req) => {
        t.fail();
    });

    try {
    // Send an receive
        const res = await requester.send({
            __subset: subset,
            type: 'test',
            args });
        t.deepEqual(res, args);

        // Destroy responder and wait for heartbeat
        responder.close();
        await wait(501);

        // Next request
        let pending = true;
        const promise = requester.send({
            __subset: subset,
            type: 'test',
            args })
            .then((res) => {
                pending = false;
                return res;
            });
        await wait(500);
        t.true(pending);

        // Recreate responder
        const responder2 = new Responder({ name: `PBR ${t.title}: directed responder`, key, namespace, subset },
            { log: false });
        responder2.on('test', async (req) => {
            return req.args;
        });

        // make sure it received the message
        const res2 = await promise;
        t.false(pending);
        t.deepEqual(res2, args);
    } catch (error) {
        t.fail(error);
    }
});

function wait(ms) {
    return new Promise((res) => {
        setTimeout(() => {
            res();
        }, ms);
    });
}
<|endoftext|>


<commit_before>/* global $:true */
/* jshint unused:false*/

+ function($) {
  "use strict";

  var defaults;

  var formatNumber = function (n) {
    return n < 10 ? "0" + n : n;
  }

  var Datetime = function(input, params) {
    this.input = $(input);
    this.params = params;

    this.initMonthes = ('01 02 03 04 05 06 07 08 09 10 11 12').split(' ');

    this.initYears = (function () {
      var arr = [];
      for (var i = 1950; i <= 2030; i++) { arr.push(i); }
      return arr;
    })();

    var p = $.extend({}, params, this.getConfig());
    $(this.input).picker(p);
  }

  Datetime.prototype = {
    getDays : function(max) {
      var days = [];
      for(var i=1; i<= (max||31);i++) {
        days.push(i < 10 ? "0"+i : i);
      }
      return days;
    },

    getDaysByMonthAndYear : function(month, year) {
      var int_d = new Date(year, parseInt(month)+1-1, 1);
      var d = new Date(int_d - 1);
      return this.getDays(d.getDate());
    },
    getConfig: function() {
      var today = new Date(),
          params = this.params,
          self = this,
          lastValidValues;

      var config = {
        rotateEffect: false,  //为了性能
        cssClass: 'datetime-picker',

        value: [today.getFullYear(), formatNumber(today.getMonth()+1), formatNumber(today.getDate()), formatNumber(today.getHours()), (formatNumber(today.getMinutes()))],

        onChange: function (picker, values, displayValues) {
          var cols = picker.cols;
          var days = self.getDaysByMonthAndYear(values[1], values[0]);
          var currentValue = values[2];
          if(currentValue > days.length) currentValue = days.length;
          picker.cols[4].setValue(currentValue);

          //check min and max
          var current = new Date(values[0]+'-'+values[1]+'-'+values[2]);
          var valid = true;
          if(params.min) {
            var min = new Date(typeof params.min === "function" ? params.min() : params.min);

            if(current < +min) {
              picker.setValue(lastValidValues);
              valid = false;
            }
          }
          if(params.max) {
            var max = new Date(typeof params.max === "function" ? params.max() : params.max);
            if(current > +max) {
              picker.setValue(lastValidValues);
              valid = false;
            }
          }

          valid && (lastValidValues = values);

          if (self.params.onChange) {
            self.params.onChange.apply(this, arguments);
          }
        },

        formatValue: function (p, values, displayValues) {
          return self.params.format(p, values, displayValues);
        },

        cols: [
          {
            values: (function () {
              var years = [];
              for (var i=1950; i<=2050; i++) years.push(i);
              return years;
            })()
          },
          {
            divider: true,  // 这是一个分隔符
            content: params.yearSplit
          },
          {
            values: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']
          },
          {
            divider: true,  // 这是一个分隔符
            content: params.monthSplit
          },
          {
            values: (function () {
              var dates = [];
              for (var i=1; i<=31; i++) dates.push(formatNumber(i));
              return dates;
            })()
          },

        ]
      }

      if (params.dateSplit) {
        config.cols.push({
          divider: true,
          content: params.dateSplit
        })
      }

      config.cols.push({
        divider: true,
        content: params.datetimeSplit
      })

      var times = self.params.times();
      if (times && times.length) {
        config.cols = config.cols.concat(times);
      }

      var inputValue = this.input.val();
      if(inputValue) config.value = params.parse(inputValue);
      if(this.params.value) {
        this.input.val(this.params.value);
        config.value = params.parse(this.params.value);
      }

      return config;
    }
  }

  $.fn.datetimePicker = function(params) {
    params = $.extend({}, defaults, params);
    return this.each(function() {
      if(!this) return;
      var $this = $(this);
      var datetime = $this.data("datetime");
      if(!datetime) $this.data("datetime", new Datetime(this, params));
      return datetime;
    });
  };

  defaults = $.fn.datetimePicker.prototype.defaults = {
    input: undefined, // 默认值
    min: undefined, // YYYY-MM-DD 最大最小值只比较年月日，不比较时分秒
    max: undefined,  // YYYY-MM-DD
    yearSplit: '-',
    monthSplit: '-',
    dateSplit: '',  // 默认为空
    datetimeSplit: ' ',  // 日期和时间之间的分隔符，不可为空
    times: function () {
      return [  // 自定义的时间
        {
          values: (function () {
            var hours = [];
            for (var i=0; i<24; i++) hours.push(formatNumber(i));
            return hours;
          })()
        },
        {
          divider: true,  // 这是一个分隔符
          content: ':'
        },
        {
          values: (function () {
            var minutes = [];
            for (var i=0; i<59; i++) minutes.push(formatNumber(i));
            return minutes;
          })()
        }
      ];
    },
    format: function (p, values) { // 数组转换成字符串
      return p.cols.map(function (col) {
        return col.value || col.content;
      }).join('');
    },
    parse: function (str) {
      // 把字符串转换成数组，用来解析初始值
      // 如果你的定制的初始值格式无法被这个默认函数解析，请自定义这个函数。比如你的时间是 '子时' 那么默认情况这个'时'会被当做分隔符而导致错误，所以你需要自己定义parse函数
      // 默认兼容的分隔符
      var t = str.split(this.datetimeSplit);
      return t[0].split(/\D/).concat(t[1].split(/:|时|分|秒/)).filter(function (d) {
        return !!d;
      })
    }
  }

}($);
<commit_msg>fix seconds lost in datetime<commit_after>/* global $:true */
/* jshint unused:false*/

+ function($) {
  "use strict";

  var defaults;

  var formatNumber = function (n) {
    return n < 10 ? "0" + n : n;
  }

  var Datetime = function(input, params) {
    this.input = $(input);
    this.params = params;

    this.initMonthes = ('01 02 03 04 05 06 07 08 09 10 11 12').split(' ');

    this.initYears = (function () {
      var arr = [];
      for (var i = 1950; i <= 2030; i++) { arr.push(i); }
      return arr;
    })();

    var p = $.extend({}, params, this.getConfig());
    $(this.input).picker(p);
  }

  Datetime.prototype = {
    getDays : function(max) {
      var days = [];
      for(var i=1; i<= (max||31);i++) {
        days.push(i < 10 ? "0"+i : i);
      }
      return days;
    },

    getDaysByMonthAndYear : function(month, year) {
      var int_d = new Date(year, parseInt(month)+1-1, 1);
      var d = new Date(int_d - 1);
      return this.getDays(d.getDate());
    },
    getConfig: function() {
      var today = new Date(),
          params = this.params,
          self = this,
          lastValidValues;

      var config = {
        rotateEffect: false,  //为了性能
        cssClass: 'datetime-picker',

        value: [today.getFullYear(), formatNumber(today.getMonth()+1), formatNumber(today.getDate()), formatNumber(today.getHours()), (formatNumber(today.getMinutes()))],

        onChange: function (picker, values, displayValues) {
          var cols = picker.cols;
          var days = self.getDaysByMonthAndYear(values[1], values[0]);
          var currentValue = values[2];
          if(currentValue > days.length) currentValue = days.length;
          picker.cols[4].setValue(currentValue);

          //check min and max
          var current = new Date(values[0]+'-'+values[1]+'-'+values[2]);
          var valid = true;
          if(params.min) {
            var min = new Date(typeof params.min === "function" ? params.min() : params.min);

            if(current < +min) {
              picker.setValue(lastValidValues);
              valid = false;
            }
          }
          if(params.max) {
            var max = new Date(typeof params.max === "function" ? params.max() : params.max);
            if(current > +max) {
              picker.setValue(lastValidValues);
              valid = false;
            }
          }

          valid && (lastValidValues = values);

          if (self.params.onChange) {
            self.params.onChange.apply(this, arguments);
          }
        },

        formatValue: function (p, values, displayValues) {
          return self.params.format(p, values, displayValues);
        },

        cols: [
          {
            values: (function () {
              var years = [];
              for (var i=1950; i<=2050; i++) years.push(i);
              return years;
            })()
          },
          {
            divider: true,  // 这是一个分隔符
            content: params.yearSplit
          },
          {
            values: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']
          },
          {
            divider: true,  // 这是一个分隔符
            content: params.monthSplit
          },
          {
            values: (function () {
              var dates = [];
              for (var i=1; i<=31; i++) dates.push(formatNumber(i));
              return dates;
            })()
          },

        ]
      }

      if (params.dateSplit) {
        config.cols.push({
          divider: true,
          content: params.dateSplit
        })
      }

      config.cols.push({
        divider: true,
        content: params.datetimeSplit
      })

      var times = self.params.times();
      if (times && times.length) {
        config.cols = config.cols.concat(times);
      }

      var inputValue = this.input.val();
      if(inputValue) config.value = params.parse(inputValue);
      if(this.params.value) {
        this.input.val(this.params.value);
        config.value = params.parse(this.params.value);
      }

      return config;
    }
  }

  $.fn.datetimePicker = function(params) {
    params = $.extend({}, defaults, params);
    return this.each(function() {
      if(!this) return;
      var $this = $(this);
      var datetime = $this.data("datetime");
      if(!datetime) $this.data("datetime", new Datetime(this, params));
      return datetime;
    });
  };

  defaults = $.fn.datetimePicker.prototype.defaults = {
    input: undefined, // 默认值
    min: undefined, // YYYY-MM-DD 最大最小值只比较年月日，不比较时分秒
    max: undefined,  // YYYY-MM-DD
    yearSplit: '-',
    monthSplit: '-',
    dateSplit: '',  // 默认为空
    datetimeSplit: ' ',  // 日期和时间之间的分隔符，不可为空
    times: function () {
      return [  // 自定义的时间
        {
          values: (function () {
            var hours = [];
            for (var i=0; i<24; i++) hours.push(formatNumber(i));
            return hours;
          })()
        },
        {
          divider: true,  // 这是一个分隔符
          content: ':'
        },
        {
          values: (function () {
            var minutes = [];
            for (var i=0; i<60; i++) minutes.push(formatNumber(i));
            return minutes;
          })()
        }
      ];
    },
    format: function (p, values) { // 数组转换成字符串
      return p.cols.map(function (col) {
        return col.value || col.content;
      }).join('');
    },
    parse: function (str) {
      // 把字符串转换成数组，用来解析初始值
      // 如果你的定制的初始值格式无法被这个默认函数解析，请自定义这个函数。比如你的时间是 '子时' 那么默认情况这个'时'会被当做分隔符而导致错误，所以你需要自己定义parse函数
      // 默认兼容的分隔符
      var t = str.split(this.datetimeSplit);
      return t[0].split(/\D/).concat(t[1].split(/:|时|分|秒/)).filter(function (d) {
        return !!d;
      })
    }
  }

}($);
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2013-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 * @format
 */

'use strict';

const RelayDataLoader = require('./RelayDataLoader');
const RelayModernRecord = require('./RelayModernRecord');
const RelayProfiler = require('../util/RelayProfiler');
const RelayReader = require('./RelayReader');
const RelayReferenceMarker = require('./RelayReferenceMarker');

const deepFreeze = require('../util/deepFreeze');
const hasOverlappingIDs = require('./hasOverlappingIDs');
const recycleNodesInto = require('../util/recycleNodesInto');
const resolveImmediate = require('resolveImmediate');

const {UNPUBLISH_RECORD_SENTINEL} = require('./RelayStoreUtils');

import type {Disposable} from '../util/RelayRuntimeTypes';
import type {
  MutableRecordSource,
  RecordSource,
  Selector,
  Snapshot,
  Store,
  UpdatedRecords,
} from './RelayStoreTypes';

type Subscription = {
  callback: (snapshot: Snapshot) => void,
  snapshot: Snapshot,
};

/**
 * @public
 *
 * An implementation of the `Store` interface defined in `RelayStoreTypes`.
 *
 * Note that a Store takes ownership of all records provided to it: other
 * objects may continue to hold a reference to such records but may not mutate
 * them. The static Relay core is architected to avoid mutating records that may have been
 * passed to a store: operations that mutate records will either create fresh
 * records or clone existing records and modify the clones. Record immutability
 * is also enforced in development mode by freezing all records passed to a store.
 */
class RelayMarkSweepStore implements Store {
  _gcEnabled: boolean;
  _hasScheduledGC: boolean;
  _index: number;
  _recordSource: MutableRecordSource;
  _roots: Map<number, Selector>;
  _subscriptions: Set<Subscription>;
  _updatedRecordIDs: UpdatedRecords;

  constructor(source: MutableRecordSource) {
    // Prevent mutation of a record from outside the store.
    if (__DEV__) {
      const storeIDs = source.getRecordIDs();
      for (let ii = 0; ii < storeIDs.length; ii++) {
        const record = source.get(storeIDs[ii]);
        if (record) {
          RelayModernRecord.freeze(record);
        }
      }
    }
    this._gcEnabled = true;
    this._hasScheduledGC = false;
    this._index = 0;
    this._recordSource = source;
    this._roots = new Map();
    this._subscriptions = new Set();
    this._updatedRecordIDs = {};
  }

  getSource(): RecordSource {
    return this._recordSource;
  }

  check(selector: Selector): boolean {
    return RelayDataLoader.check(
      this._recordSource,
      this._recordSource,
      selector,
      [],
    );
  }

  retain(selector: Selector): Disposable {
    const index = this._index++;
    const dispose = () => {
      this._roots.delete(index);
      this._scheduleGC();
    };
    this._roots.set(index, selector);
    return {dispose};
  }

  lookup(selector: Selector): Snapshot {
    const snapshot = RelayReader.read(this._recordSource, selector);
    if (__DEV__) {
      deepFreeze(snapshot);
    }
    return snapshot;
  }

  notify(): void {
    this._subscriptions.forEach(subscription => {
      this._updateSubscription(subscription);
    });
    this._updatedRecordIDs = {};
  }

  publish(source: RecordSource): void {
    updateTargetFromSource(this._recordSource, source, this._updatedRecordIDs);
  }

  subscribe(
    snapshot: Snapshot,
    callback: (snapshot: Snapshot) => void,
  ): Disposable {
    const subscription = {callback, snapshot};
    const dispose = () => {
      this._subscriptions.delete(subscription);
    };
    this._subscriptions.add(subscription);
    return {dispose};
  }

  // Internal API
  __getUpdatedRecordIDs(): UpdatedRecords {
    return this._updatedRecordIDs;
  }

  _updateSubscription(subscription: Subscription): void {
    const {callback, snapshot} = subscription;
    if (!hasOverlappingIDs(snapshot, this._updatedRecordIDs)) {
      return;
    }
    const {data, seenRecords} = RelayReader.read(this._recordSource, snapshot);
    const nextData = recycleNodesInto(snapshot.data, data);
    const nextSnapshot = {
      ...snapshot,
      data: nextData,
      seenRecords,
    };
    if (__DEV__) {
      deepFreeze(nextSnapshot);
    }
    subscription.snapshot = nextSnapshot;
    if (nextSnapshot.data !== snapshot.data) {
      callback(nextSnapshot);
    }
  }

  _scheduleGC() {
    if (!this._gcEnabled || this._hasScheduledGC) {
      return;
    }
    this._hasScheduledGC = true;
    resolveImmediate(() => {
      this._gc();
      this._hasScheduledGC = false;
    });
  }

  _gc(): void {
    const references = new Set();
    // Mark all records that are traversable from a root
    this._roots.forEach(selector => {
      RelayReferenceMarker.mark(this._recordSource, selector, references);
    });
    // Short-circuit if *nothing* is referenced
    if (!references.size) {
      this._recordSource.clear();
      return;
    }
    // Evict any unreferenced nodes
    const storeIDs = this._recordSource.getRecordIDs();
    for (let ii = 0; ii < storeIDs.length; ii++) {
      const dataID = storeIDs[ii];
      if (!references.has(dataID)) {
        this._recordSource.remove(dataID);
      }
    }
  }

  // Internal hooks to enable/disable garbage collection for experimentation
  __enableGC(): void {
    this._gcEnabled = true;
  }

  __disableGC(): void {
    this._gcEnabled = false;
  }
}

/**
 * Updates the target with information from source, also updating a mapping of
 * which records in the target were changed as a result.
 */
function updateTargetFromSource(
  target: MutableRecordSource,
  source: RecordSource,
  updatedRecordIDs: UpdatedRecords,
): void {
  const dataIDs = source.getRecordIDs();
  for (let ii = 0; ii < dataIDs.length; ii++) {
    const dataID = dataIDs[ii];
    const sourceRecord = source.get(dataID);
    const targetRecord = target.get(dataID);
    // Prevent mutation of a record from outside the store.
    if (__DEV__) {
      if (sourceRecord) {
        RelayModernRecord.freeze(sourceRecord);
      }
    }
    if (sourceRecord === UNPUBLISH_RECORD_SENTINEL) {
      // Unpublish a record
      target.remove(dataID);
      updatedRecordIDs[dataID] = true;
    } else if (sourceRecord && targetRecord) {
      const nextRecord = RelayModernRecord.update(targetRecord, sourceRecord);
      if (nextRecord !== targetRecord) {
        // Prevent mutation of a record from outside the store.
        if (__DEV__) {
          RelayModernRecord.freeze(nextRecord);
        }
        updatedRecordIDs[dataID] = true;
        target.set(dataID, nextRecord);
      }
    } else if (sourceRecord === null) {
      target.delete(dataID);
      if (targetRecord !== null) {
        updatedRecordIDs[dataID] = true;
      }
    } else if (sourceRecord) {
      target.set(dataID, sourceRecord);
      updatedRecordIDs[dataID] = true;
    } // don't add explicit undefined
  }
}

RelayProfiler.instrumentMethods(RelayMarkSweepStore.prototype, {
  lookup: 'RelayMarkSweepStore.prototype.lookup',
  notify: 'RelayMarkSweepStore.prototype.notify',
  publish: 'RelayMarkSweepStore.prototype.publish',
  retain: 'RelayMarkSweepStore.prototype.retain',
  subscribe: 'RelayMarkSweepStore.prototype.subscribe',
});

module.exports = RelayMarkSweepStore;
<commit_msg>Change `_gc` method name<commit_after>/**
 * Copyright (c) 2013-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 * @format
 */

'use strict';

const RelayDataLoader = require('./RelayDataLoader');
const RelayModernRecord = require('./RelayModernRecord');
const RelayProfiler = require('../util/RelayProfiler');
const RelayReader = require('./RelayReader');
const RelayReferenceMarker = require('./RelayReferenceMarker');

const deepFreeze = require('../util/deepFreeze');
const hasOverlappingIDs = require('./hasOverlappingIDs');
const recycleNodesInto = require('../util/recycleNodesInto');
const resolveImmediate = require('resolveImmediate');

const {UNPUBLISH_RECORD_SENTINEL} = require('./RelayStoreUtils');

import type {Disposable} from '../util/RelayRuntimeTypes';
import type {
  MutableRecordSource,
  RecordSource,
  Selector,
  Snapshot,
  Store,
  UpdatedRecords,
} from './RelayStoreTypes';

type Subscription = {
  callback: (snapshot: Snapshot) => void,
  snapshot: Snapshot,
};

/**
 * @public
 *
 * An implementation of the `Store` interface defined in `RelayStoreTypes`.
 *
 * Note that a Store takes ownership of all records provided to it: other
 * objects may continue to hold a reference to such records but may not mutate
 * them. The static Relay core is architected to avoid mutating records that may have been
 * passed to a store: operations that mutate records will either create fresh
 * records or clone existing records and modify the clones. Record immutability
 * is also enforced in development mode by freezing all records passed to a store.
 */
class RelayMarkSweepStore implements Store {
  _gcEnabled: boolean;
  _hasScheduledGC: boolean;
  _index: number;
  _recordSource: MutableRecordSource;
  _roots: Map<number, Selector>;
  _subscriptions: Set<Subscription>;
  _updatedRecordIDs: UpdatedRecords;

  constructor(source: MutableRecordSource) {
    // Prevent mutation of a record from outside the store.
    if (__DEV__) {
      const storeIDs = source.getRecordIDs();
      for (let ii = 0; ii < storeIDs.length; ii++) {
        const record = source.get(storeIDs[ii]);
        if (record) {
          RelayModernRecord.freeze(record);
        }
      }
    }
    this._gcEnabled = true;
    this._hasScheduledGC = false;
    this._index = 0;
    this._recordSource = source;
    this._roots = new Map();
    this._subscriptions = new Set();
    this._updatedRecordIDs = {};
  }

  getSource(): RecordSource {
    return this._recordSource;
  }

  check(selector: Selector): boolean {
    return RelayDataLoader.check(
      this._recordSource,
      this._recordSource,
      selector,
      [],
    );
  }

  retain(selector: Selector): Disposable {
    const index = this._index++;
    const dispose = () => {
      this._roots.delete(index);
      this._scheduleGC();
    };
    this._roots.set(index, selector);
    return {dispose};
  }

  lookup(selector: Selector): Snapshot {
    const snapshot = RelayReader.read(this._recordSource, selector);
    if (__DEV__) {
      deepFreeze(snapshot);
    }
    return snapshot;
  }

  notify(): void {
    this._subscriptions.forEach(subscription => {
      this._updateSubscription(subscription);
    });
    this._updatedRecordIDs = {};
  }

  publish(source: RecordSource): void {
    updateTargetFromSource(this._recordSource, source, this._updatedRecordIDs);
  }

  subscribe(
    snapshot: Snapshot,
    callback: (snapshot: Snapshot) => void,
  ): Disposable {
    const subscription = {callback, snapshot};
    const dispose = () => {
      this._subscriptions.delete(subscription);
    };
    this._subscriptions.add(subscription);
    return {dispose};
  }

  // Internal API
  __getUpdatedRecordIDs(): UpdatedRecords {
    return this._updatedRecordIDs;
  }

  _updateSubscription(subscription: Subscription): void {
    const {callback, snapshot} = subscription;
    if (!hasOverlappingIDs(snapshot, this._updatedRecordIDs)) {
      return;
    }
    const {data, seenRecords} = RelayReader.read(this._recordSource, snapshot);
    const nextData = recycleNodesInto(snapshot.data, data);
    const nextSnapshot = {
      ...snapshot,
      data: nextData,
      seenRecords,
    };
    if (__DEV__) {
      deepFreeze(nextSnapshot);
    }
    subscription.snapshot = nextSnapshot;
    if (nextSnapshot.data !== snapshot.data) {
      callback(nextSnapshot);
    }
  }

  _scheduleGC() {
    if (!this._gcEnabled || this._hasScheduledGC) {
      return;
    }
    this._hasScheduledGC = true;
    resolveImmediate(() => {
      this.__gc();
      this._hasScheduledGC = false;
    });
  }

  __gc(): void {
    const references = new Set();
    // Mark all records that are traversable from a root
    this._roots.forEach(selector => {
      RelayReferenceMarker.mark(this._recordSource, selector, references);
    });
    // Short-circuit if *nothing* is referenced
    if (!references.size) {
      this._recordSource.clear();
      return;
    }
    // Evict any unreferenced nodes
    const storeIDs = this._recordSource.getRecordIDs();
    for (let ii = 0; ii < storeIDs.length; ii++) {
      const dataID = storeIDs[ii];
      if (!references.has(dataID)) {
        this._recordSource.remove(dataID);
      }
    }
  }

  // Internal hooks to enable/disable garbage collection for experimentation
  __enableGC(): void {
    this._gcEnabled = true;
  }

  __disableGC(): void {
    this._gcEnabled = false;
  }
}

/**
 * Updates the target with information from source, also updating a mapping of
 * which records in the target were changed as a result.
 */
function updateTargetFromSource(
  target: MutableRecordSource,
  source: RecordSource,
  updatedRecordIDs: UpdatedRecords,
): void {
  const dataIDs = source.getRecordIDs();
  for (let ii = 0; ii < dataIDs.length; ii++) {
    const dataID = dataIDs[ii];
    const sourceRecord = source.get(dataID);
    const targetRecord = target.get(dataID);
    // Prevent mutation of a record from outside the store.
    if (__DEV__) {
      if (sourceRecord) {
        RelayModernRecord.freeze(sourceRecord);
      }
    }
    if (sourceRecord === UNPUBLISH_RECORD_SENTINEL) {
      // Unpublish a record
      target.remove(dataID);
      updatedRecordIDs[dataID] = true;
    } else if (sourceRecord && targetRecord) {
      const nextRecord = RelayModernRecord.update(targetRecord, sourceRecord);
      if (nextRecord !== targetRecord) {
        // Prevent mutation of a record from outside the store.
        if (__DEV__) {
          RelayModernRecord.freeze(nextRecord);
        }
        updatedRecordIDs[dataID] = true;
        target.set(dataID, nextRecord);
      }
    } else if (sourceRecord === null) {
      target.delete(dataID);
      if (targetRecord !== null) {
        updatedRecordIDs[dataID] = true;
      }
    } else if (sourceRecord) {
      target.set(dataID, sourceRecord);
      updatedRecordIDs[dataID] = true;
    } // don't add explicit undefined
  }
}

RelayProfiler.instrumentMethods(RelayMarkSweepStore.prototype, {
  lookup: 'RelayMarkSweepStore.prototype.lookup',
  notify: 'RelayMarkSweepStore.prototype.notify',
  publish: 'RelayMarkSweepStore.prototype.publish',
  retain: 'RelayMarkSweepStore.prototype.retain',
  subscribe: 'RelayMarkSweepStore.prototype.subscribe',
});

module.exports = RelayMarkSweepStore;
<|endoftext|>


<commit_before>/*!
 * Dialogs Manager v1.1.1
 * https://github.com/cobicarmel/dialogs-manager/
 *
 * Copyright Kobi Zaltzberg
 * Released under the MIT license
 * https://github.com/cobicarmel/dialogs-manager/blob/master/LICENSE.txt
 */

(function ($, global) {
	'use strict';

	/*
	 * Dialog Manager
	 */
	var DialogsManager = {
		widgetsTypes: {},
		createWidgetType: function (typeName, properties, Parent) {
			if (!Parent) {
				Parent = this.Widget;
			}

			var WidgetType = function () {

				Parent.apply(this, arguments);
			};

			var prototype = WidgetType.prototype = new Parent(typeName);

			$.extend(prototype, properties);

			prototype.constructor = WidgetType;

			WidgetType.extend = function (typeName, properties) {

				return DialogsManager.createWidgetType(typeName, properties, WidgetType);
			};

			return WidgetType;
		},
		addWidgetType: function (typeName, properties, Parent) {

			if (properties && properties.prototype instanceof this.Widget) {
				return this.widgetsTypes[typeName] = properties;
			}

			return this.widgetsTypes[typeName] = this.createWidgetType(typeName, properties, Parent);
		},
		getWidgetType: function (widgetType) {

			return this.widgetsTypes[widgetType];
		}
	};

	/*
	 * Dialog Manager instances constructor
	 */
	DialogsManager.Instance = function () {

		var self = this,
			components = {},
			settings = {};

		var initComponents = function () {

			components.$body = $('body');
		};

		var initSettings = function (options) {

			var defaultSettings = {
				classPrefix: 'dialog',
				effects: {
					show: 'fadeIn',
					hide: 'fadeOut'
				}
			};

			settings = $.extend(defaultSettings, options);
		};

		this.createWidget = function (widgetType, properties) {

			var WidgetTypeConstructor = DialogsManager.getWidgetType(widgetType),
				widget = new WidgetTypeConstructor(widgetType);

			properties = properties || {};

			widget.init(self, properties);

			widget.setMessage(properties.message);

			if (properties.linkedElement) {
				widget.linkElement(properties.linkedElement, widget);
			}

			return widget;
		};

		this.getSettings = function (property) {

			if (property) {
				return settings[property];
			}

			return Object.create(settings);
		};

		this.init = function (settings) {

			initSettings(settings);

			initComponents();

			return self;
		};

		this.popDialog = function (widget) {

			Widget.show();
		};

		self.init();
	};

	/*
	 * Widget types constructor
	 */
	DialogsManager.Widget = function (widgetName) {

		var self = this,
			settings = {},
			components = {
				$element: 0
			};

		var callEffect = function (intent) {

			var effect = settings.effects[intent],
				$widget = components.$widget;

			if ($.isFunction(effect)) {
				effect.call($widget);
			}
			else {

				if ($widget[effect]) {
					$widget[effect]();
				}
				else {
					throw 'Reference Error: The effect ' + effect + ' not found';
				}
			}
		};

		var initComponents = function () {

			self.addComponent('widget');

			self.addComponent('message');
		};

		var initSettings = function (parent, userSettings) {

			var parentSettings = parent.getSettings();

			settings = self.getDefaultSettings();

			settings.effects = parentSettings.effects;

			var prefix = parentSettings.classPrefix + '-' + widgetName;

			settings.classes = {
				globalPrefix: parentSettings.classPrefix,
				prefix: prefix,
				Widget: 'dialog-widget',
				linkedActive: prefix + '-linked-active'
			};

			$.extend(true, settings, userSettings);
		};

		var normalizeClassName = function (name) {

			return name.replace(/([a-z])([A-Z])/g, function () {
				return arguments[1] + '-' + arguments[2].toLowerCase();
			});
		};

		this.addComponent = function (name, component, type) {

			var $newComponent = components['$' + name] = $(component || '<div>'),
				className = settings.classes.prefix + '-';

			name = normalizeClassName(name);

			className += name;

			if (!type) {
				type = name;
			}

			className += ' ' + settings.classes.globalPrefix + '-' + type;

			$newComponent.addClass(className);

			return $newComponent;
		};

		this.getSettings = function (setting) {

			var copy = Object.create(settings);

			if (setting) {
				return copy[setting];
			}

			return copy;
		};

		this.init = function (parent, properties) {

			if (!(parent instanceof DialogsManager.Instance)) {
				throw 'The ' + self.widgetName + ' must to be initialized from an instance of DialogsManager.Instance';
			}

			self.onInit(properties);

			initSettings(parent, properties);

			initComponents();

			self.buildWidget();

			if (self.attachEvents) {
				self.attachEvents();
			}

			self.onReady();

			return self;
		};

		this.getComponents = function (item) {

			return item ? components['$' + item] : components;
		};

		this.hide = function () {

			callEffect('hide');

			if (components.$element.length) {
				components.$element.removeClass(settings.classes.linkedActive);
			}

			self.onHide();

			return self;
		};

		this.linkElement = function (element) {

			this.addComponent('element', element);

			return self;
		};

		this.setMessage = function (message) {

			components.$message.html(message);

			return self;
		};

		this.show = function (e, userSettings) {

			if (e) {
				e.stopPropagation();
			}

			components.$widget.appendTo('body');

			callEffect('show');

			if (components.$element.length) {
				components.$element.addClass(settings.classes.linkedActive);
			}

			self.onShow(userSettings);

			return self;
		};

	};

	// Inheritable widget methods
	DialogsManager.Widget.prototype.buildWidget = function () {

		var components = this.getComponents();

		components.$widget.html(components.$message);
	};

	DialogsManager.Widget.prototype.getDefaultSettings = function () {

		return {};
	};

	DialogsManager.Widget.prototype.onHide = function () {
	};

	DialogsManager.Widget.prototype.onShow = function () {
	};

	DialogsManager.Widget.prototype.onInit = function () {
	};

	DialogsManager.Widget.prototype.onReady = function () {
	};

	/*
	 * Default basic widget types
	 */
	DialogsManager.addWidgetType('tool-tip', {
		onShow: function () {

			var components = this.getComponents();

			if (components.$element.length) {

				components.$widget.position({
					at: 'left top-5',
					my: 'left+10 bottom',
					of: components.$element,
					collision: 'none none'
				});

				components.$element.focus();
			}

			setTimeout(this.hide, 5000);
		}
	});

	DialogsManager.addWidgetType('options', {
		activeKeyUp: function (event) {

			var ENTER_KEY = 13;

			if (event.which !== ENTER_KEY) {

				event.preventDefault();
			}

			if (this.hotKeys[event.which]) {
				this.hotKeys[event.which](this);
			}
		},
		activeKeyDown: function (event) {

			var TAB_KEY = 9,
				ENTER_KEY = 13;

			if (event.which !== ENTER_KEY) {

				event.preventDefault();
			}

			if (event.which === TAB_KEY) {

				var currentButtonIndex = this.focusedButton.index(),
					nextButtonIndex;

				if (event.shiftKey) {

					nextButtonIndex = currentButtonIndex - 1;

					if (nextButtonIndex < 0) {
						nextButtonIndex = this.buttons.length - 1;
					}
				} else {

					nextButtonIndex = currentButtonIndex + 1;

					if (nextButtonIndex >= this.buttons.length) {
						nextButtonIndex = 0;
					}
				}

				this.focusedButton = this.buttons[nextButtonIndex].focus();
			}
		},
		addButton: function (options) {

			var self = this,
				$button = self.addComponent(options.name, $('<button>').text(options.text));

			self.buttons.push($button);

			var buttonFn = function () {

				self.hide();

				if ($.isFunction(options.callback)) {
					options.callback.call(this, self);
				}
			};

			$button.on('click', buttonFn);

			if (options.hotKey) {
				this.hotKeys[options.hotKey] = buttonFn;
			}

			this.getComponents('buttonsWrapper').append($button);

			if (options.focus) {
				this.focusedButton = $button;
			}
		},
		bindHotKeys: function () {
			var self = this;

			self.bindKeyUpEvents = function (event) {

				self.activeKeyUp(event);
			};

			self.bindKeyDownEvents = function (event) {

				self.activeKeyDown(event);
			};

			$(window).on({
				keyup: self.bindKeyUpEvents,
				keydown: self.bindKeyDownEvents
			});
		},
		buildWidget: function () {

			var $widgetHeader = this.addComponent('widgetHeader'),
				$widgetContent = this.addComponent('widgetContent'),
				$buttonsWrapper = this.addComponent('buttonsWrapper');

			var components = this.getComponents();

			$widgetContent.append($widgetHeader, components.$message, $buttonsWrapper);

			components.$widget.html($widgetContent);
		},
		getDefaultSettings: function () {

			return {
				position: {
					my: 'center',
					at: 'center center-100'
				},
				headerMessage: ''
			};
		},
		onHide: function () {

			this.unbindHotKeys();
		},
		onInit: function () {

			this.buttons = [];

			this.hotKeys = {};

			this.focusedButton = null;
		},
		onReady: function(){

			this.setHeaderMessage(this.getSettings('headerMessage'));
		},
		onShow: function (userSettings) {

			var components = this.getComponents(),
				position = this.getSettings('position');

			position.of = components.$widget;

			if (userSettings) {
				$.extend(position, userSettings);
			}

			components.$widgetContent.position(position);

			this.bindHotKeys();

			if (!this.focusedButton) {
				this.focusedButton = this.buttons[0];
			}

			if (this.focusedButton) {
				this.focusedButton.focus();
			}
		},
		setHeaderMessage: function (message) {

			this.getComponents('widgetHeader').html(message);
		},
		unbindHotKeys: function () {

			$(window).off({
				keyup: this.bindKeyUpEvents,
				keydown: this.bindKeyDownEvents
			});
		}
	});

	DialogsManager.addWidgetType('confirm', DialogsManager.getWidgetType('options').extend('confirm', {
		onReady: function () {

			DialogsManager.getWidgetType('options').prototype.onReady.apply(this, arguments);

			var strings = this.getSettings('strings'),
				ESC_KEY = 27,
				isDefaultCancel = this.getSettings('defaultOption') === 'cancel';

			this.addButton({
				name: 'cancel',
				text: strings.cancel,
				callback: this.getSettings('onCancel'),
				hotKey: ESC_KEY,
				focus: isDefaultCancel
			});

			this.addButton({
				name: 'ok',
				text: strings.confirm,
				callback: this.getSettings('onConfirm'),
				focus: !isDefaultCancel
			});
		},
		getDefaultSettings: function () {

			var settings = DialogsManager.getWidgetType('options').prototype.getDefaultSettings.apply(this, arguments);

			settings.strings = {
				confirm: 'Ok',
				cancel: 'Cancel'
			};

			settings.defaultOption = 'cancel';

			return settings;
		}
	}));

	DialogsManager.addWidgetType('alert', DialogsManager.getWidgetType('options').extend('alert', {
		onReady: function () {
			var strings = this.getSettings('strings');

			this.addButton({
				name: 'ok',
				text: strings.confirm,
				callback: this.getSettings('onConfirm')
			});
		},
		getDefaultSettings: function () {
			var settings = DialogsManager.getWidgetType('options').prototype.getDefaultSettings.apply(this, arguments);

			settings.strings = {
				confirm: 'Ok'
			};

			return settings;
		}
	}));

	DialogsManager.addWidgetType('popup', {
		getDefaultSettings: function () {

			return {
				position: {
					my: 'center',
					at: 'center',
					of: window
				},
				hide: {
					delay: 5000
				}
			};
		},
		onShow: function () {

			var $widgetMessage = this.getComponents('message');

			$widgetMessage.position(this.getSettings('position'));

			setTimeout(this.hide, this.getSettings('hide').delay);
		}
	});

	// Exporting the DialogsManager variable to global
	global.DialogsManager = DialogsManager;
})('function' === typeof require ? require('jquery') : jQuery, 'undefined' !== typeof module && module.exports || window);<commit_msg>Changed key to lower-case<commit_after>/*!
 * Dialogs Manager v1.1.1
 * https://github.com/cobicarmel/dialogs-manager/
 *
 * Copyright Kobi Zaltzberg
 * Released under the MIT license
 * https://github.com/cobicarmel/dialogs-manager/blob/master/LICENSE.txt
 */

(function ($, global) {
	'use strict';

	/*
	 * Dialog Manager
	 */
	var DialogsManager = {
		widgetsTypes: {},
		createWidgetType: function (typeName, properties, Parent) {
			if (!Parent) {
				Parent = this.Widget;
			}

			var WidgetType = function () {

				Parent.apply(this, arguments);
			};

			var prototype = WidgetType.prototype = new Parent(typeName);

			$.extend(prototype, properties);

			prototype.constructor = WidgetType;

			WidgetType.extend = function (typeName, properties) {

				return DialogsManager.createWidgetType(typeName, properties, WidgetType);
			};

			return WidgetType;
		},
		addWidgetType: function (typeName, properties, Parent) {

			if (properties && properties.prototype instanceof this.Widget) {
				return this.widgetsTypes[typeName] = properties;
			}

			return this.widgetsTypes[typeName] = this.createWidgetType(typeName, properties, Parent);
		},
		getWidgetType: function (widgetType) {

			return this.widgetsTypes[widgetType];
		}
	};

	/*
	 * Dialog Manager instances constructor
	 */
	DialogsManager.Instance = function () {

		var self = this,
			components = {},
			settings = {};

		var initComponents = function () {

			components.$body = $('body');
		};

		var initSettings = function (options) {

			var defaultSettings = {
				classPrefix: 'dialog',
				effects: {
					show: 'fadeIn',
					hide: 'fadeOut'
				}
			};

			settings = $.extend(defaultSettings, options);
		};

		this.createWidget = function (widgetType, properties) {

			var WidgetTypeConstructor = DialogsManager.getWidgetType(widgetType),
				widget = new WidgetTypeConstructor(widgetType);

			properties = properties || {};

			widget.init(self, properties);

			widget.setMessage(properties.message);

			if (properties.linkedElement) {
				widget.linkElement(properties.linkedElement, widget);
			}

			return widget;
		};

		this.getSettings = function (property) {

			if (property) {
				return settings[property];
			}

			return Object.create(settings);
		};

		this.init = function (settings) {

			initSettings(settings);

			initComponents();

			return self;
		};

		this.popDialog = function (widget) {

			Widget.show();
		};

		self.init();
	};

	/*
	 * Widget types constructor
	 */
	DialogsManager.Widget = function (widgetName) {

		var self = this,
			settings = {},
			components = {
				$element: 0
			};

		var callEffect = function (intent) {

			var effect = settings.effects[intent],
				$widget = components.$widget;

			if ($.isFunction(effect)) {
				effect.call($widget);
			}
			else {

				if ($widget[effect]) {
					$widget[effect]();
				}
				else {
					throw 'Reference Error: The effect ' + effect + ' not found';
				}
			}
		};

		var initComponents = function () {

			self.addComponent('widget');

			self.addComponent('message');
		};

		var initSettings = function (parent, userSettings) {

			var parentSettings = parent.getSettings();

			settings = self.getDefaultSettings();

			settings.effects = parentSettings.effects;

			var prefix = parentSettings.classPrefix + '-' + widgetName;

			settings.classes = {
				globalPrefix: parentSettings.classPrefix,
				prefix: prefix,
				widget: 'dialog-widget',
				linkedActive: prefix + '-linked-active'
			};

			$.extend(true, settings, userSettings);
		};

		var normalizeClassName = function (name) {

			return name.replace(/([a-z])([A-Z])/g, function () {
				return arguments[1] + '-' + arguments[2].toLowerCase();
			});
		};

		this.addComponent = function (name, component, type) {

			var $newComponent = components['$' + name] = $(component || '<div>'),
				className = settings.classes.prefix + '-';

			name = normalizeClassName(name);

			className += name;

			if (!type) {
				type = name;
			}

			className += ' ' + settings.classes.globalPrefix + '-' + type;

			$newComponent.addClass(className);

			return $newComponent;
		};

		this.getSettings = function (setting) {

			var copy = Object.create(settings);

			if (setting) {
				return copy[setting];
			}

			return copy;
		};

		this.init = function (parent, properties) {

			if (!(parent instanceof DialogsManager.Instance)) {
				throw 'The ' + self.widgetName + ' must to be initialized from an instance of DialogsManager.Instance';
			}

			self.onInit(properties);

			initSettings(parent, properties);

			initComponents();

			self.buildWidget();

			if (self.attachEvents) {
				self.attachEvents();
			}

			self.onReady();

			return self;
		};

		this.getComponents = function (item) {

			return item ? components['$' + item] : components;
		};

		this.hide = function () {

			callEffect('hide');

			if (components.$element.length) {
				components.$element.removeClass(settings.classes.linkedActive);
			}

			self.onHide();

			return self;
		};

		this.linkElement = function (element) {

			this.addComponent('element', element);

			return self;
		};

		this.setMessage = function (message) {

			components.$message.html(message);

			return self;
		};

		this.show = function (e, userSettings) {

			if (e) {
				e.stopPropagation();
			}

			components.$widget.appendTo('body');

			callEffect('show');

			if (components.$element.length) {
				components.$element.addClass(settings.classes.linkedActive);
			}

			self.onShow(userSettings);

			return self;
		};

	};

	// Inheritable widget methods
	DialogsManager.Widget.prototype.buildWidget = function () {

		var components = this.getComponents();

		components.$widget.html(components.$message);
	};

	DialogsManager.Widget.prototype.getDefaultSettings = function () {

		return {};
	};

	DialogsManager.Widget.prototype.onHide = function () {
	};

	DialogsManager.Widget.prototype.onShow = function () {
	};

	DialogsManager.Widget.prototype.onInit = function () {
	};

	DialogsManager.Widget.prototype.onReady = function () {
	};

	/*
	 * Default basic widget types
	 */
	DialogsManager.addWidgetType('tool-tip', {
		onShow: function () {

			var components = this.getComponents();

			if (components.$element.length) {

				components.$widget.position({
					at: 'left top-5',
					my: 'left+10 bottom',
					of: components.$element,
					collision: 'none none'
				});

				components.$element.focus();
			}

			setTimeout(this.hide, 5000);
		}
	});

	DialogsManager.addWidgetType('options', {
		activeKeyUp: function (event) {

			var ENTER_KEY = 13;

			if (event.which !== ENTER_KEY) {

				event.preventDefault();
			}

			if (this.hotKeys[event.which]) {
				this.hotKeys[event.which](this);
			}
		},
		activeKeyDown: function (event) {

			var TAB_KEY = 9,
				ENTER_KEY = 13;

			if (event.which !== ENTER_KEY) {

				event.preventDefault();
			}

			if (event.which === TAB_KEY) {

				var currentButtonIndex = this.focusedButton.index(),
					nextButtonIndex;

				if (event.shiftKey) {

					nextButtonIndex = currentButtonIndex - 1;

					if (nextButtonIndex < 0) {
						nextButtonIndex = this.buttons.length - 1;
					}
				} else {

					nextButtonIndex = currentButtonIndex + 1;

					if (nextButtonIndex >= this.buttons.length) {
						nextButtonIndex = 0;
					}
				}

				this.focusedButton = this.buttons[nextButtonIndex].focus();
			}
		},
		addButton: function (options) {

			var self = this,
				$button = self.addComponent(options.name, $('<button>').text(options.text));

			self.buttons.push($button);

			var buttonFn = function () {

				self.hide();

				if ($.isFunction(options.callback)) {
					options.callback.call(this, self);
				}
			};

			$button.on('click', buttonFn);

			if (options.hotKey) {
				this.hotKeys[options.hotKey] = buttonFn;
			}

			this.getComponents('buttonsWrapper').append($button);

			if (options.focus) {
				this.focusedButton = $button;
			}
		},
		bindHotKeys: function () {
			var self = this;

			self.bindKeyUpEvents = function (event) {

				self.activeKeyUp(event);
			};

			self.bindKeyDownEvents = function (event) {

				self.activeKeyDown(event);
			};

			$(window).on({
				keyup: self.bindKeyUpEvents,
				keydown: self.bindKeyDownEvents
			});
		},
		buildWidget: function () {

			var $widgetHeader = this.addComponent('widgetHeader'),
				$widgetContent = this.addComponent('widgetContent'),
				$buttonsWrapper = this.addComponent('buttonsWrapper');

			var components = this.getComponents();

			$widgetContent.append($widgetHeader, components.$message, $buttonsWrapper);

			components.$widget.html($widgetContent);
		},
		getDefaultSettings: function () {

			return {
				position: {
					my: 'center',
					at: 'center center-100'
				},
				headerMessage: ''
			};
		},
		onHide: function () {

			this.unbindHotKeys();
		},
		onInit: function () {

			this.buttons = [];

			this.hotKeys = {};

			this.focusedButton = null;
		},
		onReady: function(){

			this.setHeaderMessage(this.getSettings('headerMessage'));
		},
		onShow: function (userSettings) {

			var components = this.getComponents(),
				position = this.getSettings('position');

			position.of = components.$widget;

			if (userSettings) {
				$.extend(position, userSettings);
			}

			components.$widgetContent.position(position);

			this.bindHotKeys();

			if (!this.focusedButton) {
				this.focusedButton = this.buttons[0];
			}

			if (this.focusedButton) {
				this.focusedButton.focus();
			}
		},
		setHeaderMessage: function (message) {

			this.getComponents('widgetHeader').html(message);
		},
		unbindHotKeys: function () {

			$(window).off({
				keyup: this.bindKeyUpEvents,
				keydown: this.bindKeyDownEvents
			});
		}
	});

	DialogsManager.addWidgetType('confirm', DialogsManager.getWidgetType('options').extend('confirm', {
		onReady: function () {

			DialogsManager.getWidgetType('options').prototype.onReady.apply(this, arguments);

			var strings = this.getSettings('strings'),
				ESC_KEY = 27,
				isDefaultCancel = this.getSettings('defaultOption') === 'cancel';

			this.addButton({
				name: 'cancel',
				text: strings.cancel,
				callback: this.getSettings('onCancel'),
				hotKey: ESC_KEY,
				focus: isDefaultCancel
			});

			this.addButton({
				name: 'ok',
				text: strings.confirm,
				callback: this.getSettings('onConfirm'),
				focus: !isDefaultCancel
			});
		},
		getDefaultSettings: function () {

			var settings = DialogsManager.getWidgetType('options').prototype.getDefaultSettings.apply(this, arguments);

			settings.strings = {
				confirm: 'Ok',
				cancel: 'Cancel'
			};

			settings.defaultOption = 'cancel';

			return settings;
		}
	}));

	DialogsManager.addWidgetType('alert', DialogsManager.getWidgetType('options').extend('alert', {
		onReady: function () {
			var strings = this.getSettings('strings');

			this.addButton({
				name: 'ok',
				text: strings.confirm,
				callback: this.getSettings('onConfirm')
			});
		},
		getDefaultSettings: function () {
			var settings = DialogsManager.getWidgetType('options').prototype.getDefaultSettings.apply(this, arguments);

			settings.strings = {
				confirm: 'Ok'
			};

			return settings;
		}
	}));

	DialogsManager.addWidgetType('popup', {
		getDefaultSettings: function () {

			return {
				position: {
					my: 'center',
					at: 'center',
					of: window
				},
				hide: {
					delay: 5000
				}
			};
		},
		onShow: function () {

			var $widgetMessage = this.getComponents('message');

			$widgetMessage.position(this.getSettings('position'));

			setTimeout(this.hide, this.getSettings('hide').delay);
		}
	});

	// Exporting the DialogsManager variable to global
	global.DialogsManager = DialogsManager;
})('function' === typeof require ? require('jquery') : jQuery, 'undefined' !== typeof module && module.exports || window);<|endoftext|>


<commit_before>define(['app', '/app/js/common.js'], function(app) {
    app.directive('ngPartyStatus', [
        '$rootScope', '$filter', '$timeout', 'commonjs', '$q',
        function($rootScope, $filter, $timeout, commonjs, $q) {
            return {
                restrict: 'EAC',
                templateUrl : '/app/views/directives/party-status.html',
                scope : {
                    government : '='
                },
                link: function($scope, elem, attrs) {
                    console.log($scope.government);
                    $q.when(commonjs.getCountry($scope.government.identifier.toUpperCase()))
                    .then(function(country){
                        console.log(country);
                        $scope.partyStatus = country;
                    });
                }
            };
        }
    ]);

});
<commit_msg>check if government is defined<commit_after>define(['app', '/app/js/common.js'], function(app) {
    app.directive('ngPartyStatus', [
        '$rootScope', '$filter', '$timeout', 'commonjs', '$q',
        function($rootScope, $filter, $timeout, commonjs, $q) {
            return {
                restrict: 'EAC',
                templateUrl : '/app/views/directives/party-status.html',
                scope : {
                    government : '='
                },
                link: function($scope, elem, attrs) {
                    if($scope.government){
                        $q.when(commonjs.getCountry($scope.government.identifier.toUpperCase()))
                        .then(function(country){
                            console.log(country);
                            $scope.partyStatus = country;
                        });
                    }
                }
            };
        }
    ]);

});
<|endoftext|>


<commit_before>// Todo
// Make sure UI scripts and styles get added to the build process
// Make sure UI dependencies get injected into app.service.js

const prompt = require("prompt");
const sh = require("shelljs");
const fs = require("fs");
const slice = require("./slice.js");

let vendorJS = require("./asset/vendor.js.json");
let vendorCSS = require("./asset/vendor.scss.json");

// Start the prompt
prompt.start();

const schema = {
	"properties": {
		"Bootstrap": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n",
			"description": "Install Bootstrap UI? [y/n]",
			"required": true
		},
		"Material Design": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install Material UI? [y/n]",
			"required": true
		},
		"Lodash": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install Lodash? [y/n]",
			"required": true
		},
		"Restangular": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install Restangular? [y/n]",
			"required": true
		},
		"Bluebird": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install Bluebird? [y/n]",
			"required": true
		},
		"NG File Upload": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install NG File Upload? [y/n]",
			"required": true
		},
		"MomentJS": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install MomentJS? [y/n]",
			"required": true
		},
		"Angular Translate": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install AngularTranslate? [y/n]",
			"required": true
		}
	}
};

prompt.get(schema, (err, input) => {
	if (input.Bootstrap.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Bootstrap...");

		!fs.exists("project/app/shared/service/ui/*")
			? sh.exec("mkdir project/app/shared/service/ui")
			: sh.exec("rm -rf project/app/shared/service/ui")
		;

		sh.exec("rm -rf project/app/extension/ng-strap && mkdir project/app/extension/ng-strap");
		sh.exec("cp -r dev/task/vendor/extension/ng-strap/* project/app/extension/ng-strap/");
		sh.exec("cp -r dev/task/vendor/shared/service/ui/bootstrap/* project/app/shared/service/ui/");
		sh.exec("cd project && npm i --save-dev angular-strap && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/angular-strap/dist/angular-strap.min.js");
		vendorJS = slice(vendorJS, "./node_modules/angular-strap/dist/angular-strap.tpl.min.js");
		vendorCSS = slice(vendorCSS, "./node_modules/bootstrap/dist/css/bootstrap.min.css");
		vendorCSS = slice(vendorCSS, "./node_modules/bootstrap/dist/css/bootstrap-theme.min.css");
	}

	if (input["Material Design"].match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Material Design...");

		!fs.exists("project/app/shared/service/ui")
			? sh.exec("mkdir project/app/shared/service/ui")
			: sh.exec("rm -rf project/app/shared/service/ui")
		;

		sh.exec("mkdir project/app/extension/angular-material");
		sh.exec("cp -r dev/task/vendor/extension/angular-material/* project/app/extension/angular-material/");
		sh.exec("cp -r dev/task/vendor/shared/service/ui/material-design/* project/app/shared/service/ui/");
		sh.exec("cd project && npm i --save-dev angular-material && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/angular-material/angular-material.min.js");
		vendorCSS = slice(vendorCSS, "./node_modules/angular-material/angular-material.min.css");
	}

	if (input.Bluebird.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Bluebird...");

		sh.exec("rm -rf project/app/extension/bluebird && mkdir project/app/extension/bluebird");
		sh.exec("rm -rf project/app/shared/service/promise && mkdir project/app/shared/service/promise");
		sh.exec("cp -r dev/task/vendor/extension/bluebird/* project/app/extension/bluebird/");
		sh.exec("cp -r dev/task/vendor/shared/service/promise/* project/app/shared/service/promise/");
		sh.exec("cd project && npm i --save-dev bluebird && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/bluebird/js/browser/bluebird.min.js");
	}

	if (input.MomentJS.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing MomentJS...");

		sh.exec("rm -rf project/app/extension/moment && mkdir project/app/extension/moment");
		sh.exec("rm -rf project/app/shared/service/date && mkdir project/app/shared/service/date");
		sh.exec("cp -r dev/task/vendor/extension/moment/* project/app/extension/moment/");
		sh.exec("cp -r dev/task/vendor/shared/service/date/* project/app/shared/service/date/");
		sh.exec("cd project && npm i --save-dev moment && cd ..");
		sh.exec("cd project && npm i --save-dev angular-moment && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/moment/min/moment.min.js");
		vendorJS = slice(vendorJS, "./node_modules/angular-moment/angular-moment.min.js");
	}

	if (input.Lodash.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Lodash...");

		sh.exec("rm -rf project/app/extension/lodash && mkdir project/app/extension/lodash");
		sh.exec("rm -rf project/app/shared/service/_ && mkdir project/app/shared/service/_");
		sh.exec("cp -r dev/task/vendor/extension/lodash/* project/app/extension/lodash/");
		sh.exec("cp -r dev/task/vendor/shared/service/_/* project/app/shared/service/_/");
		sh.exec("cd project && npm i --save-dev lodash && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/lodash/lodash.min.js");
	}

	if (input["Angular Translate"].match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Angular Translate...");

		sh.exec("rm -rf project/app/extension/angular-translate && mkdir project/app/extension/angular-translate");
		sh.exec("rm -rf project/app/shared/service/locale && mkdir project/app/shared/service/locale");
		sh.exec("cp -r dev/task/vendor/extension/angular-translate/* project/app/extension/angular-translate/");
		sh.exec("cp -r dev/task/vendor/shared/service/locale/* project/app/shared/service/locale/");
		sh.exec("cd project && npm i --save-dev angular-translate && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/angular-translate/dist/angular-translate.min.js");
	}

	if (input.Restangular.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Restangular...");

		sh.exec("rm -rf project/app/extension/restangular && mkdir project/app/extension/restangular");
		sh.exec("rm -rf project/app/shared/service/promise && mkdir project/app/shared/service/promise");
		sh.exec("cp -r dev/task/vendor/extension/restangular/* project/app/extension/restangular/");
		sh.exec("cp -r dev/task/vendor/shared/service/promise/* project/app/shared/service/promise/");
		sh.exec("cd project && npm i --save-dev restangular && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/restangular/dist/restangular.min.js");
	}

	if (input["NG File Upload"].match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing NG File Upload...");

		sh.exec("rm -rf project/app/extension/ng-file-upload && mkdir project/app/extension/ng-file-upload");
		sh.exec("rm -rf project/app/shared/service/upload && mkdir project/app/shared/service/upload");
		sh.exec("cp -r dev/task/vendor/extension/ng-file-upload/* project/app/extension/ng-file-upload/");
		sh.exec("cp -r dev/task/vendor/shared/service/upload/* project/app/shared/service/upload/");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/ng-file-upload/dist/ng-file-upload-shim.min.js");
		vendorJS = slice(vendorJS, "./node_modules/ng-file-upload/dist/ng-file-upload.min.js");
	}

	sh.exec("rm -rf project/node_modules");

	vendorJS.forEach((e, i, a) => {
		a[i] = a[i].replace(".", "./../..");
	});

	vendorCSS.forEach((e, i, a) => {
		a[i] = a[i].replace(".", "./../..");
	});

	vendorJS = JSON.stringify(vendorJS);
	vendorCSS = JSON.stringify(vendorCSS);

	fs.writeFile("project/dev/task/asset/vendor.js.json", vendorJS);
	fs.writeFile("project/dev/task/asset/vendor.scss.json", vendorCSS);
});
<commit_msg>Edits<commit_after>// Todo
// Make sure UI scripts and styles get added to the build process
// Make sure UI dependencies get injected into app.service.js

const prompt = require("prompt");
const sh = require("shelljs");
const fs = require("fs");
const slice = require("./slice.js");

let vendorJS = require("./asset/vendor.js.json");
let vendorCSS = require("./asset/vendor.scss.json");

// Start the prompt
prompt.start();

const schema = {
	"properties": {
		"Bootstrap": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n",
			"description": "Install Bootstrap UI? [y/n]",
			"required": true
		},
		"Material Design": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install Material UI? [y/n]",
			"required": true
		},
		"Lodash": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install Lodash? [y/n]",
			"required": true
		},
		"Restangular": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install Restangular? [y/n]",
			"required": true
		},
		"Bluebird": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install Bluebird? [y/n]",
			"required": true
		},
		"NG File Upload": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install NG File Upload? [y/n]",
			"required": true
		},
		"MomentJS": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install MomentJS? [y/n]",
			"required": true
		},
		"Angular Translate": {
			"pattern": /^(?:Yes|No|yes|no|Y|N|y|n)$/,
			"message": "Yes|No|yes|no|Y|N|y|n]",
			"description": "Install AngularTranslate? [y/n]",
			"required": true
		}
	}
};

prompt.get(schema, (err, input) => {
	if (input.Bootstrap.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Bootstrap...");

		!fs.exists("project/app/shared/service/ui/*")
			? sh.exec("mkdir project/app/shared/service/ui")
			: sh.exec("rm -rf project/app/shared/service/ui")
		;

		sh.exec("rm -rf project/app/extension/ng-strap && mkdir project/app/extension/ng-strap");
		sh.exec("cp -r dev/task/vendor/extension/ng-strap/* project/app/extension/ng-strap/");
		sh.exec("cp -r dev/task/vendor/shared/service/ui/bootstrap/* project/app/shared/service/ui/");
		sh.exec("cd project && npm i --save angular-strap && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/angular-strap/dist/angular-strap.min.js");
		vendorJS = slice(vendorJS, "./node_modules/angular-strap/dist/angular-strap.tpl.min.js");
		vendorCSS = slice(vendorCSS, "./node_modules/bootstrap/dist/css/bootstrap.min.css");
		vendorCSS = slice(vendorCSS, "./node_modules/bootstrap/dist/css/bootstrap-theme.min.css");
	}

	if (input["Material Design"].match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Material Design...");

		!fs.exists("project/app/shared/service/ui")
			? sh.exec("mkdir project/app/shared/service/ui")
			: sh.exec("rm -rf project/app/shared/service/ui")
		;

		sh.exec("mkdir project/app/extension/angular-material");
		sh.exec("cp -r dev/task/vendor/extension/angular-material/* project/app/extension/angular-material/");
		sh.exec("cp -r dev/task/vendor/shared/service/ui/material-design/* project/app/shared/service/ui/");
		sh.exec("cd project && npm i --save angular-material && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/angular-material/angular-material.min.js");
		vendorCSS = slice(vendorCSS, "./node_modules/angular-material/angular-material.min.css");
	}

	if (input.Bluebird.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Bluebird...");

		sh.exec("rm -rf project/app/extension/bluebird && mkdir project/app/extension/bluebird");
		sh.exec("rm -rf project/app/shared/service/promise && mkdir project/app/shared/service/promise");
		sh.exec("cp -r dev/task/vendor/extension/bluebird/* project/app/extension/bluebird/");
		sh.exec("cp -r dev/task/vendor/shared/service/promise/* project/app/shared/service/promise/");
		sh.exec("cd project && npm i --save bluebird && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/bluebird/js/browser/bluebird.min.js");
	}

	if (input.MomentJS.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing MomentJS...");

		sh.exec("rm -rf project/app/extension/moment && mkdir project/app/extension/moment");
		sh.exec("rm -rf project/app/shared/service/date && mkdir project/app/shared/service/date");
		sh.exec("cp -r dev/task/vendor/extension/moment/* project/app/extension/moment/");
		sh.exec("cp -r dev/task/vendor/shared/service/date/* project/app/shared/service/date/");
		sh.exec("cd project && npm i --save moment && cd ..");
		sh.exec("cd project && npm i --save angular-moment && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/moment/min/moment.min.js");
		vendorJS = slice(vendorJS, "./node_modules/angular-moment/angular-moment.min.js");
	}

	if (input.Lodash.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Lodash...");

		sh.exec("rm -rf project/app/extension/lodash && mkdir project/app/extension/lodash");
		sh.exec("rm -rf project/app/shared/service/_ && mkdir project/app/shared/service/_");
		sh.exec("cp -r dev/task/vendor/extension/lodash/* project/app/extension/lodash/");
		sh.exec("cp -r dev/task/vendor/shared/service/_/* project/app/shared/service/_/");
		sh.exec("cd project && npm i --save lodash && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/lodash/lodash.min.js");
	}

	if (input["Angular Translate"].match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Angular Translate...");

		sh.exec("rm -rf project/app/extension/angular-translate && mkdir project/app/extension/angular-translate");
		sh.exec("rm -rf project/app/shared/service/locale && mkdir project/app/shared/service/locale");
		sh.exec("cp -r dev/task/vendor/extension/angular-translate/* project/app/extension/angular-translate/");
		sh.exec("cp -r dev/task/vendor/shared/service/locale/* project/app/shared/service/locale/");
		sh.exec("cd project && npm i --save angular-translate && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/angular-translate/dist/angular-translate.min.js");
	}

	if (input.Restangular.match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing Restangular...");

		sh.exec("rm -rf project/app/extension/restangular && mkdir project/app/extension/restangular");
		sh.exec("rm -rf project/app/shared/service/promise && mkdir project/app/shared/service/promise");
		sh.exec("cp -r dev/task/vendor/extension/restangular/* project/app/extension/restangular/");
		sh.exec("cp -r dev/task/vendor/shared/service/promise/* project/app/shared/service/promise/");
		sh.exec("cd project && npm i --save restangular && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/restangular/dist/restangular.min.js");
	}

	if (input["NG File Upload"].match(/^(?:Yes|yes|Y|y)$/)) {
		console.log("");
		console.log("Installing NG File Upload...");

		sh.exec("rm -rf project/app/extension/ng-file-upload && mkdir project/app/extension/ng-file-upload");
		sh.exec("rm -rf project/app/shared/service/upload && mkdir project/app/shared/service/upload");
		sh.exec("cp -r dev/task/vendor/extension/ng-file-upload/* project/app/extension/ng-file-upload/");
		sh.exec("cp -r dev/task/vendor/shared/service/upload/* project/app/shared/service/upload/");
		sh.exec("cd project && npm i --save ng-file-upload && cd ..");
	}
	else {
		vendorJS = slice(vendorJS, "./node_modules/ng-file-upload/dist/ng-file-upload-shim.min.js");
		vendorJS = slice(vendorJS, "./node_modules/ng-file-upload/dist/ng-file-upload.min.js");
	}

	sh.exec("rm -rf project/node_modules");

	// Update paths to point to the root project directory
	vendorJS.forEach((e, i, a) => {
		a[i] = a[i].replace(".", "./../..");
	});

	vendorCSS.forEach((e, i, a) => {
		a[i] = a[i].replace(".", "./../..");
	});

	vendorJS = JSON.stringify(vendorJS);
	vendorCSS = JSON.stringify(vendorCSS);

	fs.writeFile("project/dev/task/asset/vendor.js.json", vendorJS);
	fs.writeFile("project/dev/task/asset/vendor.scss.json", vendorCSS);
});
<|endoftext|>