<commit_before>//= require ../../vendor/raphael-min
//= require ../../vendor/g.raphael-min
//= require ../../vendor/g.pie-min
//= require ../../vendor/g.line-min

var IslayShop = {};

/* -------------------------------------------------------------------------- */
/* UTILS
/* -------------------------------------------------------------------------- */
IslayShop.u = {
  formatMoney: function(v) {
    return '$' + v.toFixed(2);
  }
};

/* -------------------------------------------------------------------------- */
/* LINE GRAPH
/* Wraps gRaphael line graphs. Makes it easier to render.
/* -------------------------------------------------------------------------- */
IslayShop.LineGraph = Backbone.View.extend({
  className: 'graph',

  initialize: function() {
    this.x = this.options.values.x;
    this.y = this.options.values.y;
    this.xLabels = this.options.values.xLabels;
  },

  render: function() {
    this.paper = Raphael(this.el);

    var opts = {symbol: 'circle', axis: '0 0 1 1', axisxstep: this.x.length - 1, axisystep: 5, gutter: 10};
    this.line = this.paper.linechart(30, 0, 500, 250, this.x, this.y, opts);

    // These callbacks are defined inline, and we use the behaviour of closures
    // to keep our view in scope and call our own handlers. This is because of
    // gRaphael's limited callbacks.
    var view = this;
    this.line.hoverColumn(function() {view.hoverIn(this);}, function() {view.hoverOut(this);});

    if (this.xLabels) {this.renderXLabels(this.xLabels)};

    return this;
  },

  hoverIn: function(cover) {
    this.tags = []

    for (var i = 0, ii = cover.y.length; i < ii; i++) {
      var tag = $H('div.tag', IslayShop.u.formatMoney(cover.values[i]));
      this.tags.push(tag);
      this.$el.append(tag);
      tag.css({left: cover.x, top: cover.y[i] - (tag.outerHeight() / 2)});
    }
  },

  hoverOut: function() {
    this.tags && _.each(this.tags, function(tag) {tag.remove();});
  },

  renderXLabels: function(labels) {
    var els = this.line.axis[0].text.items;
    _.each(labels, function(label, i) {els[i].attr({text: label});});
  }
});

/* -------------------------------------------------------------------------- */
/* SERIES GRAPH
/* -------------------------------------------------------------------------- */
IslayShop.SeriesGraph = Backbone.View.extend({
  className: 'series-graph',

  initialize: function() {
    var value = {x: [], y: [], xLabels: []};

    _.each(this.options.table.find('tbody tr'), function(el, i) {
      var values = _.map($(el).find('td:not(:first-child)'), function(el) {
        return parseInt($(el).text());
      })

      value.x.push(i);
      value.xLabels.push(i + 1);
      value.y.push(values[0]);
    });

    this.valueGraph = new IslayShop.LineGraph({color: 'blue', values: value});

    this.render();
  },

  render: function() {
    this.$el.append(this.valueGraph.el);
    this.options.table.before(this.$el).remove();
    this.valueGraph.render();
    return this;
  }
});

/* -------------------------------------------------------------------------- */
/* SKU TOP TEN
/* -------------------------------------------------------------------------- */
IslayShop.TopTen = Backbone.View.extend({
  events: {'click .segmented li': 'click'},

  initialize: function() {
    this.tables = [];

    _.each(this.$el.find('table'), function(table, i) {
      var $table = $(table);
      this.tables.push({table: $table, caption: $table.find('caption').text()});
    }, this);

    this.render();
  },

  click: function(e) {
    var $target = $(e.target),
        index = parseInt($target.attr('data-index'));

    if (index !== this.current) {
      var current = this.tables[this.current];
      current.li.removeClass('current');
      current.table.hide();

      $target.addClass('current');
      this.tables[index].table.show();
      this.current = index;
    }
  },

  render: function() {
    this.links = $H('ul.segmented');

    _.each(this.tables, function(c, i) {
      var li = $H('li[data-index=' + i + ']', c.caption);
      this.links.append(li);
      c.li = li;

      if (i > 0) {
        c.table.hide();
        this.current = i;
        li.addClass('current');
      }
    }, this);

    this.$el.find('h3').after(this.links);

    return this;
  }
});

$SP.where('#islay-shop-admin-reports.index').run(function() {
  var graph = new IslayShop.SeriesGraph({table: $('.series-graph')});
  var topTen = new IslayShop.TopTen({el: $("#top-ten")});
});
<commit_msg>Render all three shop overview graphs.<commit_after>//= require ../../vendor/raphael-min
//= require ../../vendor/g.raphael-min
//= require ../../vendor/g.pie-min
//= require ../../vendor/g.line-min

var IslayShop = {};

/* -------------------------------------------------------------------------- */
/* UTILS
/* -------------------------------------------------------------------------- */
IslayShop.u = {
  formatMoney: function(v) {
    return '$' + v.toFixed(2);
  }
};

/* -------------------------------------------------------------------------- */
/* LINE GRAPH
/* Wraps gRaphael line graphs. Makes it easier to render.
/* -------------------------------------------------------------------------- */
IslayShop.LineGraph = Backbone.View.extend({
  className: 'graph',

  initialize: function() {
    this.x = this.options.values.x;
    this.y = this.options.values.y;
    this.xLabels = this.options.values.xLabels;
  },

  render: function() {
    this.paper = Raphael(this.el);

    var opts = {symbol: 'circle', axis: '0 0 1 1', axisxstep: this.x.length - 1, axisystep: 5, gutter: 10};
    this.line = this.paper.linechart(30, 0, 500, 250, this.x, this.y, opts);

    // These callbacks are defined inline, and we use the behaviour of closures
    // to keep our view in scope and call our own handlers. This is because of
    // gRaphael's limited callbacks.
    var view = this;
    this.line.hoverColumn(function() {view.hoverIn(this);}, function() {view.hoverOut(this);});

    if (this.xLabels) {this.renderXLabels(this.xLabels)};

    return this;
  },

  hoverIn: function(cover) {
    this.tags = []

    for (var i = 0, ii = cover.y.length; i < ii; i++) {
      var tag = $H('div.tag', IslayShop.u.formatMoney(cover.values[i]));
      this.tags.push(tag);
      this.$el.append(tag);
      tag.css({left: cover.x, top: cover.y[i] - (tag.outerHeight() / 2)});
    }
  },

  hoverOut: function() {
    this.tags && _.each(this.tags, function(tag) {tag.remove();});
  },

  renderXLabels: function(labels) {
    var els = this.line.axis[0].text.items;
    _.each(labels, function(label, i) {els[i].attr({text: label});});
  }
});

/* -------------------------------------------------------------------------- */
/* SERIES GRAPH
/* -------------------------------------------------------------------------- */
IslayShop.SeriesGraph = Backbone.View.extend({
  className: 'series-graph',

  initialize: function() {
    this.values = {
      value:      {x: [], y: [], xLabels: []},
      volume:     {x: [], y: [], xLabels: []},
      sku_volume: {x: [], y: [], xLabels: []}
    };

    _.each(this.options.table.find('tbody tr'), function(el, i) {
      var values = _.map($(el).find('td:not(:first-child)'), function(el) {
        return parseInt($(el).text());
      })

      this.update('value', i, values[0], i + 1);
      this.update('volume', i, values[1], i + 1);
      this.update('sku_volume', i, values[2], i + 1);
    }, this);

    this.graphs = _.map(this.values, function(v) {
      return new IslayShop.LineGraph({color: 'blue', values: v});
    });

    this.render();
  },

  update: function(key, x, y, label) {
    var v = this.values[key];
    v.x.push(x);
    v.y.push(y);
    if (label) {v.xLabels.push(label);}
  },

  render: function() {
    this.options.table.before(this.$el).remove();
    _.each(this.graphs, function(view) {
      this.$el.append(view.el);
      view.render();
    }, this);
    return this;
  }
});

/* -------------------------------------------------------------------------- */
/* SKU TOP TEN
/* -------------------------------------------------------------------------- */
IslayShop.TopTen = Backbone.View.extend({
  events: {'click .segmented li': 'click'},

  initialize: function() {
    this.tables = [];

    _.each(this.$el.find('table'), function(table, i) {
      var $table = $(table);
      this.tables.push({table: $table, caption: $table.find('caption').text()});
    }, this);

    this.render();
  },

  click: function(e) {
    var $target = $(e.target),
        index = parseInt($target.attr('data-index'));

    if (index !== this.current) {
      var current = this.tables[this.current];
      current.li.removeClass('current');
      current.table.hide();

      $target.addClass('current');
      this.tables[index].table.show();
      this.current = index;
    }
  },

  render: function() {
    this.links = $H('ul.segmented');

    _.each(this.tables, function(c, i) {
      var li = $H('li[data-index=' + i + ']', c.caption);
      this.links.append(li);
      c.li = li;

      if (i > 0) {
        c.table.hide();
        this.current = i;
        li.addClass('current');
      }
    }, this);

    this.$el.find('h3').after(this.links);

    return this;
  }
});

$SP.where('#islay-shop-admin-reports.index').run(function() {
  var graph = new IslayShop.SeriesGraph({table: $('.series-graph')});
  var topTen = new IslayShop.TopTen({el: $("#top-ten")});
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.crunch',
  name: 'MinMaxCapability',
  extends: 'foam.nanos.crunch.Capability',

  javaImports: [
    'foam.core.X',
    'foam.dao.ArraySink',
    'foam.dao.DAO',
    'java.util.List',
    'static foam.mlang.MLang.*',
    'foam.nanos.auth.Subject',
    'foam.nanos.auth.User'
  ],

  properties: [
    {
      name: 'min',
      class: 'Int',
      value: 1
    },
    {
      name: 'max',
      class: 'Int',
      value: 0
    },
    {
      class: 'Object',
      name: 'beforeWizardlet',
      documentation: `
        Defines a wizardlet used when displaying this capability on related client crunch wizards.
      `,
      factory: function() {
        return foam.nanos.crunch.ui.MinMaxCapabilityWizardlet.create({}, this);
      }
    },
  ],

  methods: [
    {
      name: 'getPrereqsChainedStatus',
      type: 'CapabilityJunctionStatus',
      args: [
        { name: 'x', type: 'Context' },
        { name: 'ucj', type: 'UserCapabilityJunction' }
      ],
      javaCode: `
        // Required services and DAOs
        CrunchService crunchService = (CrunchService) x.get("crunchService");
        DAO userCapabilityJunctionDAO = (DAO) x.get("userCapabilityJunctionDAO");
        DAO userDAO = (DAO) x.get("userDAO");
        Subject currentSubject = (Subject) x.get("subject");

        // Prepare to count statuses
        int numberGranted = 0;
        int numberPending = 0;

        // Create ccJunctions list
        DAO myPrerequisitesDAO = ((DAO)
          x.get("prerequisiteCapabilityJunctionDAO"))
            .where(
              EQ(CapabilityCapabilityJunction.SOURCE_ID, getId()));
        List<CapabilityCapabilityJunction> ccJunctions =
          ((ArraySink) myPrerequisitesDAO.select(new ArraySink()))
          .getArray();

        // Count junction statuses
        for ( CapabilityCapabilityJunction ccJunction : ccJunctions ) {
          Capability cap = (Capability) ccJunction.findTargetId(x);
          if ( ! cap.getEnabled() ) continue;

          // Use getSubject method of UCJ when NP-2436 (PR 4248) is merged
          Subject subject = new Subject(x);
          if ( ucj instanceof AgentCapabilityJunction ) {
            subject.setUser((User) userDAO.find(ucj.getSourceId()));
            AgentCapabilityJunction acj = (AgentCapabilityJunction) ucj;
            subject.setUser((User) userDAO.find(acj.getEffectiveUser())); // "user"
          } else if ( ucj.getSourceId() == currentSubject.getUser().getId() ) {
            subject.setUser(currentSubject.getRealUser());
            subject.setUser(currentSubject.getUser());
          } else {
            subject.setUser((User) userDAO.find(ucj.getSourceId()));
          }

          X subjectContext = x.put("subject", subject);

          UserCapabilityJunction ucJunction =
            crunchService.getJunction(subjectContext, ccJunction.getTargetId());
          if ( ucJunction.getStatus() == AVAILABLE ) continue;

          switch ( ucJunction.getStatus() ) {
            case GRANTED:
              numberGranted++;
              break;
            case PENDING:
            case APPROVED:
              numberPending++;
              break;
          }
        }

        if ( numberGranted >= getMin() ) {
          return CapabilityJunctionStatus.GRANTED;
        }
        if ( numberGranted + numberPending >= getMin() ) {
          return CapabilityJunctionStatus.PENDING;
        }
        return CapabilityJunctionStatus.ACTION_REQUIRED;
      `
    }
  ]
});
<commit_msg>Fix but introduced by NP-3188<commit_after>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.crunch',
  name: 'MinMaxCapability',
  extends: 'foam.nanos.crunch.Capability',

  javaImports: [
    'foam.core.X',
    'foam.dao.ArraySink',
    'foam.dao.DAO',
    'java.util.List',
    'static foam.mlang.MLang.*',
    'foam.nanos.auth.Subject',
    'foam.nanos.auth.User',
    'foam.nanos.crunch.ui.MinMaxCapabilityWizardlet'
  ],

  properties: [
    {
      name: 'min',
      class: 'Int',
      value: 1
    },
    {
      name: 'max',
      class: 'Int',
      value: 0
    },
    {
      class: 'Object',
      name: 'beforeWizardlet',
      documentation: `
        Defines a wizardlet used when displaying this capability on related client crunch wizards.
      `,
      factory: function() {
        return foam.nanos.crunch.ui.MinMaxCapabilityWizardlet.create({}, this);
      },
      javaFactory: `
        return new MinMaxCapabilityWizardlet();
      `
    },
  ],

  methods: [
    {
      name: 'getPrereqsChainedStatus',
      type: 'CapabilityJunctionStatus',
      args: [
        { name: 'x', type: 'Context' },
        { name: 'ucj', type: 'UserCapabilityJunction' }
      ],
      javaCode: `
        // Required services and DAOs
        CrunchService crunchService = (CrunchService) x.get("crunchService");
        DAO userCapabilityJunctionDAO = (DAO) x.get("userCapabilityJunctionDAO");
        DAO userDAO = (DAO) x.get("userDAO");
        Subject currentSubject = (Subject) x.get("subject");

        // Prepare to count statuses
        int numberGranted = 0;
        int numberPending = 0;

        // Create ccJunctions list
        DAO myPrerequisitesDAO = ((DAO)
          x.get("prerequisiteCapabilityJunctionDAO"))
            .where(
              EQ(CapabilityCapabilityJunction.SOURCE_ID, getId()));
        List<CapabilityCapabilityJunction> ccJunctions =
          ((ArraySink) myPrerequisitesDAO.select(new ArraySink()))
          .getArray();

        // Count junction statuses
        for ( CapabilityCapabilityJunction ccJunction : ccJunctions ) {
          Capability cap = (Capability) ccJunction.findTargetId(x);
          if ( ! cap.getEnabled() ) continue;

          // Use getSubject method of UCJ when NP-2436 (PR 4248) is merged
          Subject subject = new Subject(x);
          if ( ucj instanceof AgentCapabilityJunction ) {
            subject.setUser((User) userDAO.find(ucj.getSourceId()));
            AgentCapabilityJunction acj = (AgentCapabilityJunction) ucj;
            subject.setUser((User) userDAO.find(acj.getEffectiveUser())); // "user"
          } else if ( ucj.getSourceId() == currentSubject.getUser().getId() ) {
            subject.setUser(currentSubject.getRealUser());
            subject.setUser(currentSubject.getUser());
          } else {
            subject.setUser((User) userDAO.find(ucj.getSourceId()));
          }

          X subjectContext = x.put("subject", subject);

          UserCapabilityJunction ucJunction =
            crunchService.getJunction(subjectContext, ccJunction.getTargetId());
          if ( ucJunction.getStatus() == AVAILABLE ) continue;

          switch ( ucJunction.getStatus() ) {
            case GRANTED:
              numberGranted++;
              break;
            case PENDING:
            case APPROVED:
              numberPending++;
              break;
          }
        }

        if ( numberGranted >= getMin() ) {
          return CapabilityJunctionStatus.GRANTED;
        }
        if ( numberGranted + numberPending >= getMin() ) {
          return CapabilityJunctionStatus.PENDING;
        }
        return CapabilityJunctionStatus.ACTION_REQUIRED;
      `
    }
  ]
});
<|endoftext|>


<commit_before>'use strict'
describe('multiple upstreams, multiple scopes, multiple clients over single connection', function () {
  var Hub = require('../../../lib')
  var Mock = require('../../../lib/protocol/mock')
  var getScope = Hub.prototype.getScope
  // servers
  var a = new Hub({ key: 'server_a' })
  var b = new Hub({
    key: 'server_b',
    define: {
      getScope (val, event) {
        var scope = getScope.apply(this, arguments)
        scope.set({
          key: 'server_bSCOPE_' + val,
          adapter: {
            mock: 'scope_connection_server_a',
            scope: val
          }
        })
        return scope
      }
    }
  })

  a.set({
    adapter: {
      id: 'scope_connection_server_a',
      mock: new Mock()
    }
  })

  b.set({
    adapter: {
      id: 'scope_connection_server_b',
      mock: new Mock()
    }
  })

  a.adapter.mock.set({ server: 'scope_connection_server_a' })
  b.adapter.mock.set({ server: 'scope_connection_server_b' })

  // recievers
  var receiverA1 = new Hub({ key: 'receiverA1' })
  var receiverA2 = new Hub({ key: 'receiverA2' })

  receiverA1.set({
    adapter: {
      id: 'scope_connection_receiver_A1',
      mock: new Mock()
    }
  })

  receiverA2.set({
    adapter: {
      id: 'scope_connection_receiver_A2',
      mock: new Mock()
    }
  })

  it('receiverA1 can connect to b, b._scopes.A1 gets connected to a', function (done) {
    receiverA1.adapter.set({
      scope: 'a1',
      mock: 'scope_connection_server_b'
    })
    receiverA1.adapter.mock.once('connect', function () {
      setTimeout(done, 50) // once b connects to a
    })
  })

  it('a1 has scope with correct clients object', function () {
    expect(a).to.have.property('_scopes')
      .which.has.property('a1')
      .which.has.property('clients')
      .which.has.property('scope_connection_server_b')
  })

  it('a set a field on scope a1', function () {
    a._scopes.a1.set({
      somefield: true
    })
    expect(receiverA1).to.have.property('somefield')
  })

  it('receiverA2 can connect to b, b._scopes.A2 gets connected to a, shares connection', function (done) {
    receiverA2.adapter.set({
      scope: 'a2',
      mock: 'scope_connection_server_b'
    })
    receiverA2.adapter.mock.once('connect', function () {
      setTimeout(done, 50)
    })
  })

  it('a2 has scope with correct clients object', function () {
    expect(a).to.have.property('_scopes')
      .which.has.property('a2')
      .which.has.property('clients')
      .which.has.property('scope_connection_server_b')
  })

  it('a set a field on scope a2', function () {
    a._scopes.a2.set({
      anotherfield: true
    })
    expect(receiverA2).to.have.property('anotherfield')
    expect(receiverA1).to.not.have.property('anotherfield')
  })
})
<commit_msg>removed timouts from multiple connection tests<commit_after>'use strict'
describe('multiple upstreams, multiple scopes, multiple clients over single connection', function () {
  var Hub = require('../../../lib')
  var Mock = require('../../../lib/protocol/mock')
  var getScope = Hub.prototype.getScope
  // servers
  var a = new Hub({ key: 'server_a' })
  var b = new Hub({
    key: 'server_b',
    define: {
      getScope (val, event) {
        var scope = getScope.apply(this, arguments)
        scope.set({
          key: 'server_bSCOPE_' + val,
          adapter: {
            mock: 'scope_connection_server_a',
            scope: val
          }
        })
        return scope
      }
    }
  })

  a.set({
    adapter: {
      id: 'scope_connection_server_a',
      mock: new Mock()
    }
  })

  b.set({
    adapter: {
      id: 'scope_connection_server_b',
      mock: new Mock()
    }
  })

  a.adapter.mock.set({ server: 'scope_connection_server_a' })
  b.adapter.mock.set({ server: 'scope_connection_server_b' })

  // recievers
  var receiverA1 = new Hub({ key: 'receiverA1' })
  var receiverA2 = new Hub({ key: 'receiverA2' })

  receiverA1.set({
    adapter: {
      id: 'scope_connection_receiver_A1',
      mock: new Mock()
    }
  })

  receiverA2.set({
    adapter: {
      id: 'scope_connection_receiver_A2',
      mock: new Mock()
    }
  })

  it('receiverA1 can connect to b, b._scopes.A1 gets connected to a', function (done) {
    receiverA1.adapter.set({
      scope: 'a1',
      mock: 'scope_connection_server_b'
    })
    b.once('new', function (data) {
      this.adapter.mock.connected.once(function () {
        expect(receiverA1.adapter.mock.connected.val).to.equal(true)
        done()
      })
    })
  })

  it('a1 has scope with correct clients object', function () {
    expect(a).to.have.property('_scopes')
      .which.has.property('a1')
      .which.has.property('clients')
      .which.has.property('scope_connection_server_b')
  })

  it('a set a field on scope a1', function () {
    a._scopes.a1.set({
      somefield: true
    })
    expect(receiverA1).to.have.property('somefield')
  })

  it('receiverA2 can connect to b, b._scopes.A2 gets connected to a, shares connection', function (done) {
    b.once('new', function (data) {
      this.adapter.mock.connected.once(function () {
        expect(receiverA2.adapter.mock.connected.val).to.equal(true)
        done()
      })
    })
    receiverA2.adapter.set({
      scope: 'a2',
      mock: 'scope_connection_server_b'
    })
  })

  it('a2 has scope with correct clients object', function () {
    expect(a).to.have.property('_scopes')
      .which.has.property('a2')
      .which.has.property('clients')
      .which.has.property('scope_connection_server_b')
  })

  it('a set a field on scope a2', function () {
    a._scopes.a2.set({
      anotherfield: true
    })
    expect(receiverA2).to.have.property('anotherfield')
    expect(receiverA1).to.not.have.property('anotherfield')
  })
})
<|endoftext|>


<commit_before>define(['ash', 'utils/MathUtils', 'game/constants/CampConstants', 'game/constants/GameConstants'],
function (Ash, MathUtils, CampConstants, GameConstants) {

    var OccurrenceConstants = {

		campOccurrenceTypes: {
			trader: "trader",
			raid: "raid",
		},

		OCCURRENCE_CAMP_TRADER_LENGTH: 60 * 5,
		OCCURRENCE_CAMP_TRADER_COOLDOWN: 60 * 15,
		OCCURRENCE_CAMP_TRADER_VARIATION: 60 * 30,

		OCCURRENCE_CAMP_RAID_LENGTH: 5,
		OCCURRENCE_CAMP_RAID_COOLDOWN: 60 * 15,
		OCCURRENCE_CAMP_RAID_VARIATION: 60 * 60,

		scheduleNext: function (occurrenceType, upgradeFactor, campPopulation, campMaxPopulation) {
			var minimumTime = 1;
            var baseTime = 1;
			var randomFactor = Math.random();

            var pop = (campPopulation + campMaxPopulation)/2;
            var populationFactor = MathUtils.clamp(2.25-Math.log(pop+1)/2.5, 0.5, 2);

            switch (occurrenceType) {
				case this.campOccurrenceTypes.trader:
					minimumTime = this.OCCURRENCE_CAMP_TRADER_COOLDOWN;
					baseTime = this.OCCURRENCE_CAMP_TRADER_VARIATION;
					break;

				case this.campOccurrenceTypes.raid:
					minimumTime = this.OCCURRENCE_CAMP_RAID_COOLDOWN;
					baseTime = this.OCCURRENCE_CAMP_RAID_VARIATION;
					break;
			}

            minimumTime *= Math.max(1, populationFactor);

            return Math.floor(minimumTime + baseTime * randomFactor * upgradeFactor * populationFactor) / GameConstants.gameSpeedCamp;
		},

		getDuration: function(occurrenceType) {
			switch(occurrenceType) {
			case this.campOccurrenceTypes.trader:
				return this.OCCURRENCE_CAMP_TRADER_LENGTH;

			case this.campOccurrenceTypes.raid:
				return this.OCCURRENCE_CAMP_RAID_LENGTH;
			}
			return 0;
		},

		getRaidDanger: function (improvements, soldiers, soldierLevel) {
			var dangerPoints = this.getRaidDangerPoints(improvements)
			var defencePoints = this.getRaidDefencePoints(improvements, soldiers, soldierLevel);
            var result = (dangerPoints - defencePoints)/20;
			return Math.max(0, Math.min(1, result));
		},

        getRaidDangerPoints: function (improvements) {
			var dangerPoints = 0;
			dangerPoints += improvements.getTotal(improvementTypes.camp);
			dangerPoints -= improvements.getCount(improvementTypes.home);
            dangerPoints -= improvements.getCount(improvementNames.fortification);
            dangerPoints -= improvements.getCount(improvementNames.fortification2);
            return dangerPoints;
        },

		getRaidDefencePoints: function (improvements, soldiers, soldierLevel) {
            return CampConstants.CAMP_BASE_DEFENCE + this.getFortificationsDefencePoints(improvements) + this.getSoldierDefencePoints(soldiers, soldierLevel);
		},

        getRaidDefenceString: function (improvements, soldiers, soldierLevel) {
            var result = "Base: " + CampConstants.CAMP_BASE_DEFENCE;
            var fortificationsPoints = this.getFortificationsDefencePoints(improvements);
            if (fortificationsPoints > 0) result += "
Fortifications:" + fortificationsPoints;
            var soldierPoints = this.getSoldierDefencePoints(soldiers, soldierLevel);
            if (soldierPoints > 0) result += "
Soldiers:" + soldierPoints;
            return result;
		},

        getFortificationsDefencePoints: function (improvements) {
			var regularFortifications = improvements.getCount(improvementNames.fortification);
            var improvedFortifications = improvements.getCount(improvementNames.fortification2);
            return regularFortifications * CampConstants.FORTIFICATION_1_DEFENCE + improvedFortifications * CampConstants.FORTIFICATION_2_DEFENCE;
        },

        getSoldierDefencePoints: function (soldiers, soldierLevel) {
            return soldiers * CampConstants.getSoldierDefence(soldierLevel);
        },

    };

    return OccurrenceConstants;

});
<commit_msg>make incoming traders less frequent<commit_after>define(['ash', 'utils/MathUtils', 'game/constants/CampConstants', 'game/constants/GameConstants'],
function (Ash, MathUtils, CampConstants, GameConstants) {

    var OccurrenceConstants = {

		campOccurrenceTypes: {
			trader: "trader",
			raid: "raid",
		},

		OCCURRENCE_CAMP_TRADER_LENGTH: 60 * 5,
		OCCURRENCE_CAMP_TRADER_COOLDOWN: 60 * 20,
		OCCURRENCE_CAMP_TRADER_VARIATION: 60 * 75,

		OCCURRENCE_CAMP_RAID_LENGTH: 5,
		OCCURRENCE_CAMP_RAID_COOLDOWN: 60 * 15,
		OCCURRENCE_CAMP_RAID_VARIATION: 60 * 60,

		scheduleNext: function (occurrenceType, upgradeFactor, campPopulation, campMaxPopulation) {
			var minimumTime = 1;
            var baseTime = 1;
			var randomFactor = Math.random();

            var pop = (campPopulation + campMaxPopulation)/2;
            var populationFactor = MathUtils.clamp(2.25-Math.log(pop+1)/2.5, 0.5, 2);

            switch (occurrenceType) {
				case this.campOccurrenceTypes.trader:
					minimumTime = this.OCCURRENCE_CAMP_TRADER_COOLDOWN;
					baseTime = this.OCCURRENCE_CAMP_TRADER_VARIATION;
					break;

				case this.campOccurrenceTypes.raid:
					minimumTime = this.OCCURRENCE_CAMP_RAID_COOLDOWN;
					baseTime = this.OCCURRENCE_CAMP_RAID_VARIATION;
					break;
			}

            minimumTime *= Math.max(1, populationFactor);

            return Math.floor(minimumTime + baseTime * randomFactor * upgradeFactor * populationFactor) / GameConstants.gameSpeedCamp;
		},

		getDuration: function(occurrenceType) {
			switch(occurrenceType) {
			case this.campOccurrenceTypes.trader:
				return this.OCCURRENCE_CAMP_TRADER_LENGTH;

			case this.campOccurrenceTypes.raid:
				return this.OCCURRENCE_CAMP_RAID_LENGTH;
			}
			return 0;
		},

		getRaidDanger: function (improvements, soldiers, soldierLevel) {
			var dangerPoints = this.getRaidDangerPoints(improvements)
			var defencePoints = this.getRaidDefencePoints(improvements, soldiers, soldierLevel);
            var result = (dangerPoints - defencePoints)/20;
			return Math.max(0, Math.min(1, result));
		},

        getRaidDangerPoints: function (improvements) {
			var dangerPoints = 0;
			dangerPoints += improvements.getTotal(improvementTypes.camp);
			dangerPoints -= improvements.getCount(improvementTypes.home);
            dangerPoints -= improvements.getCount(improvementNames.fortification);
            dangerPoints -= improvements.getCount(improvementNames.fortification2);
            return dangerPoints;
        },

		getRaidDefencePoints: function (improvements, soldiers, soldierLevel) {
            return CampConstants.CAMP_BASE_DEFENCE + this.getFortificationsDefencePoints(improvements) + this.getSoldierDefencePoints(soldiers, soldierLevel);
		},

        getRaidDefenceString: function (improvements, soldiers, soldierLevel) {
            var result = "Base: " + CampConstants.CAMP_BASE_DEFENCE;
            var fortificationsPoints = this.getFortificationsDefencePoints(improvements);
            if (fortificationsPoints > 0) result += "
Fortifications:" + fortificationsPoints;
            var soldierPoints = this.getSoldierDefencePoints(soldiers, soldierLevel);
            if (soldierPoints > 0) result += "
Soldiers:" + soldierPoints;
            return result;
		},

        getFortificationsDefencePoints: function (improvements) {
			var regularFortifications = improvements.getCount(improvementNames.fortification);
            var improvedFortifications = improvements.getCount(improvementNames.fortification2);
            return regularFortifications * CampConstants.FORTIFICATION_1_DEFENCE + improvedFortifications * CampConstants.FORTIFICATION_2_DEFENCE;
        },

        getSoldierDefencePoints: function (soldiers, soldierLevel) {
            return soldiers * CampConstants.getSoldierDefence(soldierLevel);
        },

    };

    return OccurrenceConstants;

});
<|endoftext|>


<commit_before>/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2015 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* The LoadTexture component manages the loading of a texture into the Game Object and the changing of frames.
*
* @class
*/
Phaser.Component.LoadTexture = function () {};

Phaser.Component.LoadTexture.prototype = {

    /**
    * @property {Phaser.Rectangle} _frame - Internal cache var.
    * @private
    */
    _frame: null,

    /**
    * Changes the base texture the Game Object is using. The old texture is removed and the new one is referenced or fetched from the Cache.
    *
    * If your Game Object is using a frame from a texture atlas and you just wish to change to another frame, then see the `frame` or `frameName` properties instead.
    *
    * You should only use `loadTexture` if you want to replace the base texture entirely.
    *
    * Calling this method causes a WebGL texture update, so use sparingly or in low-intensity portions of your game, or if you know the new texture is already on the GPU.
    *
    * @method
    * @param {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture, BitmapData or PIXI.Texture.
    * @param {string|number} [frame] - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
    * @param {boolean} [stopAnimation=true] - If an animation is already playing on this Sprite you can choose to stop it or let it carry on playing.
    */
    loadTexture: function (key, frame, stopAnimation) {

        frame = frame || 0;

        if ((stopAnimation || typeof stopAnimation === 'undefined') && this.animations)
        {
            this.animations.stop();
        }

        this.key = key;

        var setFrame = true;
        var smoothed = !this.texture.baseTexture.scaleMode;
        var isRenderTexture = false;

        if (Phaser.RenderTexture && key instanceof Phaser.RenderTexture)
        {
            this.key = key.key;
            this.setTexture(key);
            isRenderTexture = true;
        }
        else if (Phaser.BitmapData && key instanceof Phaser.BitmapData)
        {
            //  This works from a reference, which probably isn't what we need here
            this.setTexture(key.texture);

            if (this.game.cache.getFrameData(key.key, Phaser.Cache.BITMAPDATA))
            {
                setFrame = !this.animations.loadFrameData(this.game.cache.getFrameData(key.key, Phaser.Cache.BITMAPDATA), frame);
            }
        }
        else if (key instanceof PIXI.Texture)
        {
            this.setTexture(key);
        }
        else
        {
            if (key === null || typeof key === 'undefined')
            {
                this.key = '__default';
                this.setTexture(PIXI.TextureCache[this.key]);
            }
            else if (typeof key === 'string' && !this.game.cache.checkImageKey(key))
            {
                console.warn("Texture with key '" + key + "' not found.");
                this.key = '__missing';
                this.setTexture(PIXI.TextureCache[this.key]);
            }
            else
            {
                this.setTexture(new PIXI.Texture(PIXI.BaseTextureCache[key]));

                setFrame = !this.animations.loadFrameData(this.game.cache.getFrameData(key), frame);
            }
        }

        if (setFrame)
        {
            this._frame = Phaser.Rectangle.clone(this.texture.frame);
        }

        if (!smoothed)
        {
            this.texture.baseTexture.scaleMode = 1;
        }

    },

    /**
    * Sets the texture frame the Game Object uses for rendering.
    *
    * This is primarily an internal method used by `loadTexture`, but is exposed for the use of plugins and custom classes.
    *
    * @method
    * @param {Phaser.Frame} frame - The Frame to be used by the texture.
    */
    setFrame: function (frame) {

        this._frame = frame;

        this.texture.frame.x = frame.x;
        this.texture.frame.y = frame.y;
        this.texture.frame.width = frame.width;
        this.texture.frame.height = frame.height;

        this.texture.crop.x = frame.x;
        this.texture.crop.y = frame.y;
        this.texture.crop.width = frame.width;
        this.texture.crop.height = frame.height;

        if (frame.trimmed)
        {
            if (this.texture.trim)
            {
                this.texture.trim.x = frame.spriteSourceSizeX;
                this.texture.trim.y = frame.spriteSourceSizeY;
                this.texture.trim.width = frame.sourceSizeW;
                this.texture.trim.height = frame.sourceSizeH;
            }
            else
            {
                this.texture.trim = { x: frame.spriteSourceSizeX, y: frame.spriteSourceSizeY, width: frame.sourceSizeW, height: frame.sourceSizeH };
            }

            this.texture.width = frame.sourceSizeW;
            this.texture.height = frame.sourceSizeH;
            this.texture.frame.width = frame.sourceSizeW;
            this.texture.frame.height = frame.sourceSizeH;
        }
        else if (!frame.trimmed && this.texture.trim)
        {
            this.texture.trim = null;
        }

        if (this.cropRect)
        {
            this.updateCrop();
        }

        if (this.tint !== 0xFFFFFF)
        {
            this.cachedTint = -1;
        }

        this.texture._updateUvs();

    },

    /**
    * Resets the texture frame dimensions that the Game Object uses for rendering.
    *
    * @method
    */
    resetFrame: function () {

        if (this._frame)
        {
            this.setFrame(this._frame);
        }

    },

    /**
    * Gets or sets the current frame index of the texture being used to render this Game Object.
    *
    * To change the frame set `frame` to the index of the new frame in the sprite sheet you wish this Game Object to use,
    * for example: `player.frame = 4`.
    *
    * If the frame index given doesn't exist it will revert to the first frame found in the texture.
    *
    * If you are using a texture atlas then you should use the `frameName` property instead.
    *
    * If you wish to fully replace the texture being used see `loadTexture`.
    * @property {integer} frame
    */
    frame: {

        get: function () {
            return this.animations.frame;
        },

        set: function (value) {
            this.animations.frame = value;
        }

    },

    /**
    * Gets or sets the current frame name of the texture being used to render this Game Object.
    *
    * To change the frame set `frameName` to the name of the new frame in the texture atlas you wish this Game Object to use,
    * for example: `player.frameName = "idle"`.
    *
    * If the frame name given doesn't exist it will revert to the first frame found in the texture and throw a console warning.
    *
    * If you are using a sprite sheet then you should use the `frame` property instead.
    *
    * If you wish to fully replace the texture being used see `loadTexture`.
    * @property {string} frameName
    */
    frameName: {

        get: function () {
            return this.animations.frameName;
        },

        set: function (value) {
            this.animations.frameName = value;
        }

    }

};
<commit_msg>close #1755<commit_after>/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2015 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

/**
* The LoadTexture component manages the loading of a texture into the Game Object and the changing of frames.
*
* @class
*/
Phaser.Component.LoadTexture = function () {};

Phaser.Component.LoadTexture.prototype = {

    /**
    * @property {Phaser.Rectangle} _frame - Internal cache var.
    * @private
    */
    _frame: null,

    /**
    * Changes the base texture the Game Object is using. The old texture is removed and the new one is referenced or fetched from the Cache.
    *
    * If your Game Object is using a frame from a texture atlas and you just wish to change to another frame, then see the `frame` or `frameName` properties instead.
    *
    * You should only use `loadTexture` if you want to replace the base texture entirely.
    *
    * Calling this method causes a WebGL texture update, so use sparingly or in low-intensity portions of your game, or if you know the new texture is already on the GPU.
    *
    * @method
    * @param {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache Image entry, or an instance of a RenderTexture, BitmapData or PIXI.Texture.
    * @param {string|number} [frame] - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
    * @param {boolean} [stopAnimation=true] - If an animation is already playing on this Sprite you can choose to stop it or let it carry on playing.
    */
    loadTexture: function (key, frame, stopAnimation) {

        frame = frame || 0;

        if ((stopAnimation || typeof stopAnimation === 'undefined') && this.animations)
        {
            this.animations.stop();
        }

        this.key = key;

        var setFrame = true;
        var smoothed = !this.texture.baseTexture.scaleMode;
        var isRenderTexture = false;

        if (Phaser.RenderTexture && key instanceof Phaser.RenderTexture)
        {
            this.key = key.key;
            this.setTexture(key);
            isRenderTexture = true;
        }
        else if (Phaser.BitmapData && key instanceof Phaser.BitmapData)
        {
            //  This works from a reference, which probably isn't what we need here
            this.setTexture(key.texture);

            if (this.game.cache.getFrameData(key.key, Phaser.Cache.BITMAPDATA))
            {
                setFrame = !this.animations.loadFrameData(this.game.cache.getFrameData(key.key, Phaser.Cache.BITMAPDATA), frame);
            }
        }
        else if (key instanceof PIXI.Texture)
        {
            this.setTexture(key);
        }
        else
        {
            if (key === null || typeof key === 'undefined')
            {
                this.key = '__default';
                this.setTexture(PIXI.TextureCache[this.key]);
            }
            else if (typeof key === 'string' && !this.game.cache.checkImageKey(key))
            {
                console.warn("Texture with key '" + key + "' not found.");
                this.key = '__missing';
                this.setTexture(PIXI.TextureCache[this.key]);
            }
            else
            {
                this.setTexture(new PIXI.Texture(PIXI.BaseTextureCache[key]));

                setFrame = !this.animations.loadFrameData(this.game.cache.getFrameData(key), frame);
            }
        }

        if (setFrame)
        {
            this._frame = Phaser.Rectangle.clone(this.texture.frame);
        }

        if (!smoothed)
        {
            this.texture.baseTexture.scaleMode = 1;
        }

    },

    /**
    * Sets the texture frame the Game Object uses for rendering.
    *
    * This is primarily an internal method used by `loadTexture`, but is exposed for the use of plugins and custom classes.
    *
    * @method
    * @param {Phaser.Frame} frame - The Frame to be used by the texture.
    */
    setFrame: function (frame) {

        this._frame = frame;

        this.texture.frame.x = frame.x;
        this.texture.frame.y = frame.y;
        this.texture.frame.width = frame.width;
        this.texture.frame.height = frame.height;

        this.texture.crop.x = frame.x;
        this.texture.crop.y = frame.y;
        this.texture.crop.width = frame.width;
        this.texture.crop.height = frame.height;

        if (frame.trimmed)
        {
            if (this.texture.trim)
            {
                this.texture.trim.x = frame.spriteSourceSizeX;
                this.texture.trim.y = frame.spriteSourceSizeY;
                this.texture.trim.width = frame.sourceSizeW;
                this.texture.trim.height = frame.sourceSizeH;
            }
            else
            {
                this.texture.trim = { x: frame.spriteSourceSizeX, y: frame.spriteSourceSizeY, width: frame.sourceSizeW, height: frame.sourceSizeH };
            }

            this.texture.width = frame.sourceSizeW;
            this.texture.height = frame.sourceSizeH;
            this.texture.frame.width = frame.sourceSizeW;
            this.texture.frame.height = frame.sourceSizeH;
        }
        else if (!frame.trimmed && this.texture.trim)
        {
            this.texture.trim = null;
        }

        if (this.cropRect)
        {
            this.updateCrop();
        }

        if (this.tint !== 0xFFFFFF)
        {
            this.cachedTint = -1;
        }

        this.texture._updateUvs();

    },

    /**
    * Resets the texture frame dimensions that the Game Object uses for rendering.
    *
    * @method
    */
    resetFrame: function () {

        if (this._frame)
        {
            this.setFrame(this._frame);
        }

    },

    /**
    * Gets or sets the current frame index of the texture being used to render this Game Object.
    *
    * To change the frame set `frame` to the index of the new frame in the sprite sheet you wish this Game Object to use,
    * for example: `player.frame = 4`.
    *
    * If the frame index given doesn't exist it will revert to the first frame found in the texture.
    *
    * If you are using a texture atlas then you should use the `frameName` property instead.
    *
    * If you wish to fully replace the texture being used see `loadTexture`.
    * @property {integer} frame
    */
    frame: {

        get: function () {
            return this.animations.frame;
        },

        set: function (value) {
            this.animations.frame = value;
        }

    },

    /**
    * Gets or sets the current frame name of the texture being used to render this Game Object.
    *
    * To change the frame set `frameName` to the name of the new frame in the texture atlas you wish this Game Object to use,
    * for example: `player.frameName = "idle"`.
    *
    * If the frame name given doesn't exist it will revert to the first frame found in the texture and throw a console warning.
    *
    * If you are using a sprite sheet then you should use the `frame` property instead.
    *
    * If you wish to fully replace the texture being used see `loadTexture`.
    * @property {string} frameName
    */
    frameName: {

        get: function () {
            return this.animations.frameName;
        },

        set: function (value) {
            this.animations.frameName = value;
        }

    }

};
<|endoftext|>


<commit_before>'use strict';

describe('ng-include', function() {
  var element;

  afterEach(function(){
    dealoc(element);
  });

  function putIntoCache(url, content) {
    return function($templateCache) {
      $templateCache.put(url, [200, content, {}]);
    };
  }

  it('should include on external file', inject(putIntoCache('myUrl', '{{name}}'),
      function($rootScope, $compile, $browser) {
    element = jqLite('<ng:include src="url" scope="childScope"></ng:include>');
    jqLite(document.body).append(element);
    element = $compile(element)($rootScope);
    $rootScope.childScope = $rootScope.$new();
    $rootScope.childScope.name = 'misko';
    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    expect(element.text()).toEqual('misko');
    jqLite(document.body).html('');
  }));

  it('should remove previously included text if a falsy value is bound to src', inject(
        putIntoCache('myUrl', '{{name}}'),
        function($rootScope, $compile, $browser) {
    element = jqLite('

');
    element = $compile(element)($rootScope);
    $rootScope.childScope = $rootScope.$new();
    $rootScope.childScope.name = 'igor';
    $rootScope.url = 'myUrl';
    $rootScope.$digest();

    expect(element.text()).toEqual('igor');

    $rootScope.url = undefined;
    $rootScope.$digest();

    expect(element.text()).toEqual('');
  }));

  it('should allow this for scope', inject(putIntoCache('myUrl', '{{"abc"}}'),
        function($rootScope, $compile, $browser) {
    element = jqLite('<ng:include src="url" scope="this"></ng:include>');
    element = $compile(element)($rootScope);
    $rootScope.url = 'myUrl';
    $rootScope.$digest();

    // TODO(misko): because we are using scope==this, the eval gets registered
    // during the flush phase and hence does not get called.
    // I don't think passing 'this' makes sense. Does having scope on ng-include makes sense?
    // should we make scope="this" illegal?
    $rootScope.$digest();

    expect(element.text()).toEqual('abc');
  }));

  it('should fire $includeContentLoaded event after linking the content', inject(
      function($rootScope, $compile, $templateCache) {
    var contentLoadedSpy = jasmine.createSpy('content loaded').andCallFake(function() {
      expect(element.text()).toBe('partial content');
    });

    $templateCache.put('url', [200, 'partial content', {}]);
    $rootScope.$on('$includeContentLoaded', contentLoadedSpy);

    element = $compile('<ng:include src="\'url\'"></ng:include>')($rootScope);
    $rootScope.$digest();

    expect(contentLoadedSpy).toHaveBeenCalledOnce();
  }));

  it('should evaluate onload expression when a partial is loaded', inject(
      putIntoCache('myUrl', 'my partial'),
      function($rootScope, $compile, $browser) {
    element = jqLite('<ng:include src="url" onload="loaded = true"></ng:include>');
    element = $compile(element)($rootScope);

    expect($rootScope.loaded).not.toBeDefined();

    $rootScope.url = 'myUrl';
    $rootScope.$digest();

    expect(element.text()).toEqual('my partial');
    expect($rootScope.loaded).toBe(true);
  }));

  it('should destroy old scope', inject(putIntoCache('myUrl', 'my partial'),
        function($rootScope, $compile, $browser) {
    element = jqLite('<ng:include src="url"></ng:include>');
    element = $compile(element)($rootScope);

    expect($rootScope.$$childHead).toBeFalsy();

    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    expect($rootScope.$$childHead).toBeTruthy();

    $rootScope.url = null;
    $rootScope.$digest();
    expect($rootScope.$$childHead).toBeFalsy();
  }));

  it('should do xhr request and cache it',
      inject(function($rootScope, $httpBackend, $compile, $browser) {
    element = $compile('<ng:include src="url"></ng:include>')($rootScope);
    $httpBackend.expect('GET', 'myUrl').respond('my partial');

    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    $httpBackend.flush();
    expect(element.text()).toEqual('my partial');

    $rootScope.url = null;
    $rootScope.$digest();
    expect(element.text()).toEqual('');

    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    expect(element.text()).toEqual('my partial');
    dealoc($rootScope);
  }));

  it('should clear content when error during xhr request',
      inject(function($httpBackend, $compile, $rootScope) {
    element = $compile('<ng:include src="url">content</ng:include>')($rootScope);
    $httpBackend.expect('GET', 'myUrl').respond(404, '');

    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    $httpBackend.flush();

    expect(element.text()).toBe('');
  }));

  it('should be async even if served from cache', inject(
        putIntoCache('myUrl', 'my partial'),
        function($rootScope, $compile, $browser) {
    element = $compile('<ng:include src="url"></ng:include>')($rootScope);

    $rootScope.url = 'myUrl';

    var called = 0;
    // we want to assert only during first watch
    $rootScope.$watch(function() {
      if (!called++) expect(element.text()).toBe('');
    });

    $rootScope.$digest();
    expect(element.text()).toBe('my partial');
  }));

  it('should discard pending xhr callbacks if a new template is requested before the current ' +
      'finished loading', inject(function($rootScope, $compile, $httpBackend) {
    element = jqLite("<ng:include src='templateUrl'></ng:include>");
    var log = [];

    $rootScope.templateUrl = 'myUrl1';
    $rootScope.logger = function(msg) {
      log.push(msg);
    }
    $compile(element)($rootScope);
    expect(log.join('; ')).toEqual('');

    $httpBackend.expect('GET', 'myUrl1').respond('
{{logger("url1")}}
');
    $rootScope.$digest();
    expect(log.join('; ')).toEqual('');
    $rootScope.templateUrl = 'myUrl2';
    $httpBackend.expect('GET', 'myUrl2').respond('
{{logger("url2")}}
');
    $rootScope.$digest();
    $httpBackend.flush(); // now that we have two requests pending, flush!

    expect(log.join('; ')).toEqual('url2; url2'); // it's here twice because we go through at
                                                  // least two digest cycles
  }));

  it('should compile only the content', inject(function($compile, $rootScope, $templateCache) {
    // regression

    var onload = jasmine.createSpy('$includeContentLoaded');
    $rootScope.$on('$includeContentLoaded', onload);
    $templateCache.put('tpl.html', [200, 'partial {{tpl}}', {}]);

    element = $compile('

' +
        '<ng:include src="tpl"></ng:include>

')($rootScope);
    expect(onload).not.toHaveBeenCalled();

    $rootScope.$apply(function() {
      $rootScope.tpl = 'tpl.html';
    });
    expect(onload).toHaveBeenCalledOnce();
  }));

  describe('autoscoll', function() {
    var autoScrollSpy;

    function spyOnAnchorScroll() {
      return function($provide) {
        autoScrollSpy = jasmine.createSpy('$anchorScroll');
        $provide.value('$anchorScroll', autoScrollSpy);
      };
    }

    function compileAndLink(tpl) {
      return function($compile, $rootScope) {
        element = $compile(tpl)($rootScope);
      };
    }

    function changeTplAndValueTo(template, value) {
      return function($rootScope, $browser) {
        $rootScope.$apply(function() {
          $rootScope.tpl = template;
          $rootScope.value = value;
        });
      };
    }

    beforeEach(module(spyOnAnchorScroll()));
    beforeEach(inject(
        putIntoCache('template.html', 'CONTENT'),
        putIntoCache('another.html', 'CONTENT')));

    it('should call $anchorScroll if autoscroll attribute is present', inject(
        compileAndLink('<ng:include src="tpl" autoscroll></ng:include>'),
        changeTplAndValueTo('template.html'), function() {
      expect(autoScrollSpy).toHaveBeenCalledOnce();
    }));

    it('should call $anchorScroll if autoscroll evaluates to true', inject(
        compileAndLink('<ng:include src="tpl" autoscroll="value"></ng:include>'),
        changeTplAndValueTo('template.html', true),
        changeTplAndValueTo('another.html', 'some-string'),
        changeTplAndValueTo('template.html', 100), function() {
      expect(autoScrollSpy).toHaveBeenCalled();
      expect(autoScrollSpy.callCount).toBe(3);
    }));

    it('should not call $anchorScroll if autoscroll attribute is not present', inject(
        compileAndLink('<ng:include src="tpl"></ng:include>'),
        changeTplAndValueTo('template.html'), function() {
      expect(autoScrollSpy).not.toHaveBeenCalled();
    }));

    it('should not call $anchorScroll if autoscroll evaluates to false', inject(
        compileAndLink('<ng:include src="tpl" autoscroll="value"></ng:include>'),
        changeTplAndValueTo('template.html', false),
        changeTplAndValueTo('template.html', undefined),
        changeTplAndValueTo('template.html', null), function() {
      expect(autoScrollSpy).not.toHaveBeenCalled();
    }));
  });
});
<commit_msg>test(ng-include): add ng-include=src test<commit_after>'use strict';

describe('ng-include', function() {
  var element;

  afterEach(function(){
    dealoc(element);
  });

  function putIntoCache(url, content) {
    return function($templateCache) {
      $templateCache.put(url, [200, content, {}]);
    };
  }

  it('should include on external file', inject(putIntoCache('myUrl', '{{name}}'),
      function($rootScope, $compile, $browser) {
    element = jqLite('<ng:include src="url" scope="childScope"></ng:include>');
    jqLite(document.body).append(element);
    element = $compile(element)($rootScope);
    $rootScope.childScope = $rootScope.$new();
    $rootScope.childScope.name = 'misko';
    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    expect(element.text()).toEqual('misko');
    jqLite(document.body).html('');
  }));

  it('should support ng-include="src" syntax', inject(putIntoCache('myUrl', '{{name}}'),
      function($rootScope, $compile) {
    element = jqLite('

');
    jqLite(document.body).append(element);
    element = $compile(element)($rootScope);
    $rootScope.name = 'Alibaba';
    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    expect(element.text()).toEqual('Alibaba');
    jqLite(document.body).html('');
  }));

  it('should remove previously included text if a falsy value is bound to src', inject(
        putIntoCache('myUrl', '{{name}}'),
        function($rootScope, $compile) {
    element = jqLite('<ng:include src="url" scope="childScope"></ng:include>');
    element = $compile(element)($rootScope);
    $rootScope.childScope = $rootScope.$new();
    $rootScope.childScope.name = 'igor';
    $rootScope.url = 'myUrl';
    $rootScope.$digest();

    expect(element.text()).toEqual('igor');

    $rootScope.url = undefined;
    $rootScope.$digest();

    expect(element.text()).toEqual('');
  }));

  it('should allow this for scope', inject(putIntoCache('myUrl', '{{"abc"}}'),
        function($rootScope, $compile, $browser) {
    element = jqLite('<ng:include src="url" scope="this"></ng:include>');
    element = $compile(element)($rootScope);
    $rootScope.url = 'myUrl';
    $rootScope.$digest();

    // TODO(misko): because we are using scope==this, the eval gets registered
    // during the flush phase and hence does not get called.
    // I don't think passing 'this' makes sense. Does having scope on ng-include makes sense?
    // should we make scope="this" illegal?
    $rootScope.$digest();

    expect(element.text()).toEqual('abc');
  }));

  it('should fire $includeContentLoaded event after linking the content', inject(
      function($rootScope, $compile, $templateCache) {
    var contentLoadedSpy = jasmine.createSpy('content loaded').andCallFake(function() {
      expect(element.text()).toBe('partial content');
    });

    $templateCache.put('url', [200, 'partial content', {}]);
    $rootScope.$on('$includeContentLoaded', contentLoadedSpy);

    element = $compile('<ng:include src="\'url\'"></ng:include>')($rootScope);
    $rootScope.$digest();

    expect(contentLoadedSpy).toHaveBeenCalledOnce();
  }));

  it('should evaluate onload expression when a partial is loaded', inject(
      putIntoCache('myUrl', 'my partial'),
      function($rootScope, $compile, $browser) {
    element = jqLite('<ng:include src="url" onload="loaded = true"></ng:include>');
    element = $compile(element)($rootScope);

    expect($rootScope.loaded).not.toBeDefined();

    $rootScope.url = 'myUrl';
    $rootScope.$digest();

    expect(element.text()).toEqual('my partial');
    expect($rootScope.loaded).toBe(true);
  }));

  it('should destroy old scope', inject(putIntoCache('myUrl', 'my partial'),
        function($rootScope, $compile, $browser) {
    element = jqLite('<ng:include src="url"></ng:include>');
    element = $compile(element)($rootScope);

    expect($rootScope.$$childHead).toBeFalsy();

    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    expect($rootScope.$$childHead).toBeTruthy();

    $rootScope.url = null;
    $rootScope.$digest();
    expect($rootScope.$$childHead).toBeFalsy();
  }));

  it('should do xhr request and cache it',
      inject(function($rootScope, $httpBackend, $compile, $browser) {
    element = $compile('<ng:include src="url"></ng:include>')($rootScope);
    $httpBackend.expect('GET', 'myUrl').respond('my partial');

    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    $httpBackend.flush();
    expect(element.text()).toEqual('my partial');

    $rootScope.url = null;
    $rootScope.$digest();
    expect(element.text()).toEqual('');

    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    expect(element.text()).toEqual('my partial');
    dealoc($rootScope);
  }));

  it('should clear content when error during xhr request',
      inject(function($httpBackend, $compile, $rootScope) {
    element = $compile('<ng:include src="url">content</ng:include>')($rootScope);
    $httpBackend.expect('GET', 'myUrl').respond(404, '');

    $rootScope.url = 'myUrl';
    $rootScope.$digest();
    $httpBackend.flush();

    expect(element.text()).toBe('');
  }));

  it('should be async even if served from cache', inject(
        putIntoCache('myUrl', 'my partial'),
        function($rootScope, $compile, $browser) {
    element = $compile('<ng:include src="url"></ng:include>')($rootScope);

    $rootScope.url = 'myUrl';

    var called = 0;
    // we want to assert only during first watch
    $rootScope.$watch(function() {
      if (!called++) expect(element.text()).toBe('');
    });

    $rootScope.$digest();
    expect(element.text()).toBe('my partial');
  }));

  it('should discard pending xhr callbacks if a new template is requested before the current ' +
      'finished loading', inject(function($rootScope, $compile, $httpBackend) {
    element = jqLite("<ng:include src='templateUrl'></ng:include>");
    var log = [];

    $rootScope.templateUrl = 'myUrl1';
    $rootScope.logger = function(msg) {
      log.push(msg);
    }
    $compile(element)($rootScope);
    expect(log.join('; ')).toEqual('');

    $httpBackend.expect('GET', 'myUrl1').respond('
{{logger("url1")}}
');
    $rootScope.$digest();
    expect(log.join('; ')).toEqual('');
    $rootScope.templateUrl = 'myUrl2';
    $httpBackend.expect('GET', 'myUrl2').respond('
{{logger("url2")}}
');
    $rootScope.$digest();
    $httpBackend.flush(); // now that we have two requests pending, flush!

    expect(log.join('; ')).toEqual('url2; url2'); // it's here twice because we go through at
                                                  // least two digest cycles
  }));

  it('should compile only the content', inject(function($compile, $rootScope, $templateCache) {
    // regression

    var onload = jasmine.createSpy('$includeContentLoaded');
    $rootScope.$on('$includeContentLoaded', onload);
    $templateCache.put('tpl.html', [200, 'partial {{tpl}}', {}]);

    element = $compile('

' +
        '<ng:include src="tpl"></ng:include>

')($rootScope);
    expect(onload).not.toHaveBeenCalled();

    $rootScope.$apply(function() {
      $rootScope.tpl = 'tpl.html';
    });
    expect(onload).toHaveBeenCalledOnce();
  }));

  describe('autoscoll', function() {
    var autoScrollSpy;

    function spyOnAnchorScroll() {
      return function($provide) {
        autoScrollSpy = jasmine.createSpy('$anchorScroll');
        $provide.value('$anchorScroll', autoScrollSpy);
      };
    }

    function compileAndLink(tpl) {
      return function($compile, $rootScope) {
        element = $compile(tpl)($rootScope);
      };
    }

    function changeTplAndValueTo(template, value) {
      return function($rootScope, $browser) {
        $rootScope.$apply(function() {
          $rootScope.tpl = template;
          $rootScope.value = value;
        });
      };
    }

    beforeEach(module(spyOnAnchorScroll()));
    beforeEach(inject(
        putIntoCache('template.html', 'CONTENT'),
        putIntoCache('another.html', 'CONTENT')));

    it('should call $anchorScroll if autoscroll attribute is present', inject(
        compileAndLink('<ng:include src="tpl" autoscroll></ng:include>'),
        changeTplAndValueTo('template.html'), function() {
      expect(autoScrollSpy).toHaveBeenCalledOnce();
    }));

    it('should call $anchorScroll if autoscroll evaluates to true', inject(
        compileAndLink('<ng:include src="tpl" autoscroll="value"></ng:include>'),
        changeTplAndValueTo('template.html', true),
        changeTplAndValueTo('another.html', 'some-string'),
        changeTplAndValueTo('template.html', 100), function() {
      expect(autoScrollSpy).toHaveBeenCalled();
      expect(autoScrollSpy.callCount).toBe(3);
    }));

    it('should not call $anchorScroll if autoscroll attribute is not present', inject(
        compileAndLink('<ng:include src="tpl"></ng:include>'),
        changeTplAndValueTo('template.html'), function() {
      expect(autoScrollSpy).not.toHaveBeenCalled();
    }));

    it('should not call $anchorScroll if autoscroll evaluates to false', inject(
        compileAndLink('<ng:include src="tpl" autoscroll="value"></ng:include>'),
        changeTplAndValueTo('template.html', false),
        changeTplAndValueTo('template.html', undefined),
        changeTplAndValueTo('template.html', null), function() {
      expect(autoScrollSpy).not.toHaveBeenCalled();
    }));
  });
});
<|endoftext|>


<commit_before>const moment               = require('moment');
const DigitTicker          = require('./digit_ticker');
const ViewPopupUI          = require('../user/view_popup/view_popup.ui');
const showLocalTimeOnHover = require('../../base/clock').showLocalTimeOnHover;
const BinarySocket         = require('../../base/socket');
const addComma             = require('../../../_common/base/currency_base').addComma;
const localize             = require('../../../_common/localize').localize;
const getPropertyValue     = require('../../../_common/utility').getPropertyValue;

const DigitDisplay = (() => {
    let $container,
        contract,
        tick_count,
        spot_times;

    const subscribe = (request) => {
        // Subscribe if contract is still ongoing/running.
        if (contract.current_spot_time < contract.date_expiry) {
            request.subscribe = 1;
            request.end       = 'latest';
        } else {
            request.end = contract.date_expiry;
        }
    };

    const init = (id_render, proposal_open_contract) => {
        tick_count = 1;
        contract   = proposal_open_contract;
        spot_times = [];

        $container = $(`#${id_render}`);
        $container
            .addClass('normal-font')
            .html($('<h5 />', { text: contract.display_name, class: 'center-text' }))
            .append($('<div />', { class: 'gr-8 gr-centered gr-12-m' })
                .append($('<div />', { class: 'gr-row', id: 'table_digits' })
                    .append($('<strong />', { class: 'gr-3', text: localize('Tick') }))
                    .append($('<strong />', { class: 'gr-3', text: localize('Spot') }))
                    .append($('<strong />', { class: 'gr-6', text: localize('Spot Time (GMT)') }))))
            .append($('<div />', { class: 'digit-ticker invisible', id: 'digit_ticker_container' }));

        DigitTicker.init(
            'digit_ticker_container',
            contract.contract_type,
            contract.shortcode,
            contract.tick_count,
            contract.status
        );
        const request = {
            ticks_history: contract.underlying,
            start        : contract.date_start,
        };

        subscribe(request);

        BinarySocket.send(request, { callback: update });
    };

    const updateTable = (spot, time) => {
        if (spot_times.some(item => item.spot === spot && item.time === time)) {
            return;
        }
        spot_times.push({
            spot,
            time,
        });

        const csv_spot = addComma(spot);

        $container
            .find('#table_digits')
            .append($('<p />', { class: 'gr-3', text: tick_count }))
            .append($('<p />', { class: 'gr-3 gray', html: tick_count === contract.tick_count ? `${csv_spot.slice(0, csv_spot.length - 1)}<strong>${csv_spot.substr(-1)}</strong>` : csv_spot }))
            .append($('<p />', { class: 'gr-6 gray digit-spot-time no-underline', text: moment(+time * 1000).utc().format('YYYY-MM-DD HH:mm:ss') }));

        DigitTicker.update(
            tick_count,
            {
                quote: contract.status !== 'open' ? contract.exit_tick : spot,
                epoch: contract.status !== 'open' ? contract.exit_tick_time : contract.date_expiry,
            }
        );
    };

    const redrawFromHistory = (response) => {
        tick_count = 1;
        if (!$container.is(':visible') || !response || (!response.history)) {
            return;
        }
        $container.find('#table_digits').empty();

        response.history.times.some((time, idx) => {
            if (+time >= +contract.entry_tick_time && +contract.exit_tick_time) {
                const spot = response.history.prices[idx];
                const csv_spot = addComma(spot);

                $container
                    .find('#table_digits')
                    .append($('<p />', { class: 'gr-3', text: tick_count }))
                    .append($('<p />', { class: 'gr-3 gray', html: tick_count === contract.tick_count ? `${csv_spot.slice(0, csv_spot.length - 1)}<strong>${csv_spot.substr(-1)}</strong>` : csv_spot }))
                    .append($('<p />', { class: 'gr-6 gray digit-spot-time no-underline', text: moment(+time * 1000).utc().format('YYYY-MM-DD HH:mm:ss') }));

                tick_count += 1;
            }
            return tick_count > contract.tick_count;
        });

        showLocalTimeOnHover('.digit-spot-time');

    };

    const update = (response) => {
        if (!$container.is(':visible') || !response || (!response.tick && !response.history)) {
            return;
        }

        if (getPropertyValue(response, ['tick', 'id']) && document.getElementById('sell_content_wrapper')) {
            ViewPopupUI.storeSubscriptionID(response.tick.id);
        }

        if (response.history) {
            response.history.times.some((time, idx) => {
                if (+time >= +contract.entry_tick_time) {
                    updateTable(response.history.prices[idx], time);
                    tick_count += 1;
                }
                return tick_count > contract.tick_count;
            });
        } else if (response.tick) {
            if (tick_count <= contract.tick_count &&
                +response.tick.epoch >= +contract.entry_tick_time) {
                updateTable(response.tick.quote, response.tick.epoch);
                tick_count += 1;
            }
        }
        showLocalTimeOnHover('.digit-spot-time');
    };

    const end = (proposal_open_contract) => {
        if (proposal_open_contract.status !== 'open') {
            DigitTicker.update(proposal_open_contract.tick_count, {
                quote: proposal_open_contract.exit_tick,
                epoch: proposal_open_contract.exit_tick_time,
            });
            if ($container.find('#digit_table').length < proposal_open_contract.tick_count) {
                const request = {
                    ticks_history: contract.underlying,
                    start        : contract.entry_tick_time,
                    end          : contract.exit_tick_time,
                };

                // force rerender the table by sending the history
                BinarySocket.send(request, { callback: redrawFromHistory });
            }
        }
        if (proposal_open_contract.status === 'won') {
            DigitTicker.markAsWon();
            DigitTicker.markDigitAsWon(proposal_open_contract.exit_tick.slice(-1));
        }
        if (proposal_open_contract.status === 'lost') {
            DigitTicker.markAsLost();
            DigitTicker.markDigitAsLost(proposal_open_contract.exit_tick.slice(-1));
        }
    };

    return {
        end,
        init,
        update,
    };
})();

module.exports = DigitDisplay;
<commit_msg>Redraw portfolio if rendered ticks not matching the tick_count of the contract.<commit_after>const moment               = require('moment');
const DigitTicker          = require('./digit_ticker');
const ViewPopupUI          = require('../user/view_popup/view_popup.ui');
const showLocalTimeOnHover = require('../../base/clock').showLocalTimeOnHover;
const BinarySocket         = require('../../base/socket');
const addComma             = require('../../../_common/base/currency_base').addComma;
const localize             = require('../../../_common/localize').localize;
const getPropertyValue     = require('../../../_common/utility').getPropertyValue;

const DigitDisplay = (() => {
    let $container,
        contract,
        tick_count,
        spot_times;

    const subscribe = (request) => {
        // Subscribe if contract is still ongoing/running.
        if (contract.current_spot_time < contract.date_expiry) {
            request.subscribe = 1;
            request.end       = 'latest';
        } else {
            request.end = contract.date_expiry;
        }
    };

    const init = (id_render, proposal_open_contract) => {
        tick_count = 1;
        contract   = proposal_open_contract;
        spot_times = [];

        $container = $(`#${id_render}`);
        $container
            .addClass('normal-font')
            .html($('<h5 />', { text: contract.display_name, class: 'center-text' }))
            .append($('<div />', { class: 'gr-8 gr-centered gr-12-m' })
                .append($('<div />', { class: 'gr-row', id: 'table_digits' })
                    .append($('<strong />', { class: 'gr-3', text: localize('Tick') }))
                    .append($('<strong />', { class: 'gr-3', text: localize('Spot') }))
                    .append($('<strong />', { class: 'gr-6', text: localize('Spot Time (GMT)') }))))
            .append($('<div />', { class: 'digit-ticker invisible', id: 'digit_ticker_container' }));

        DigitTicker.init(
            'digit_ticker_container',
            contract.contract_type,
            contract.shortcode,
            contract.tick_count,
            contract.status
        );
        const request = {
            ticks_history: contract.underlying,
            start        : contract.date_start,
        };

        subscribe(request);

        BinarySocket.send(request, { callback: update });
    };

    const updateTable = (spot, time) => {
        if (spot_times.some(item => item.spot === spot && item.time === time)) {
            return;
        }
        spot_times.push({
            spot,
            time,
        });

        const csv_spot = addComma(spot);

        $container
            .find('#table_digits')
            .append($('<p />', { class: 'gr-3', text: tick_count }))
            .append($('<p />', { class: 'gr-3 gray', html: tick_count === contract.tick_count ? `${csv_spot.slice(0, csv_spot.length - 1)}<strong>${csv_spot.substr(-1)}</strong>` : csv_spot }))
            .append($('<p />', { class: 'gr-6 gray digit-spot-time no-underline', text: moment(+time * 1000).utc().format('YYYY-MM-DD HH:mm:ss') }));

        DigitTicker.update(
            tick_count,
            {
                quote: contract.status !== 'open' ? contract.exit_tick : spot,
                epoch: contract.status !== 'open' ? contract.exit_tick_time : contract.date_expiry,
            }
        );
    };

    const redrawFromHistory = (response) => {
        tick_count = 1;
        if (!$container.is(':visible') || !response || (!response.history)) {
            return;
        }
        $container.find('#table_digits').empty();

        response.history.times.some((time, idx) => {
            if (+time >= +contract.entry_tick_time && +contract.exit_tick_time) {
                const spot = response.history.prices[idx];
                const csv_spot = addComma(spot);

                $container
                    .find('#table_digits')
                    .append($('<p />', { class: 'gr-3', text: tick_count }))
                    .append($('<p />', { class: 'gr-3 gray', html: tick_count === contract.tick_count ? `${csv_spot.slice(0, csv_spot.length - 1)}<strong>${csv_spot.substr(-1)}</strong>` : csv_spot }))
                    .append($('<p />', { class: 'gr-6 gray digit-spot-time no-underline', text: moment(+time * 1000).utc().format('YYYY-MM-DD HH:mm:ss') }));

                tick_count += 1;
            }
            return tick_count > contract.tick_count;
        });

        showLocalTimeOnHover('.digit-spot-time');

    };

    const update = (response) => {
        if (!$container.is(':visible') || !response || (!response.tick && !response.history)) {
            return;
        }

        if (getPropertyValue(response, ['tick', 'id']) && document.getElementById('sell_content_wrapper')) {
            ViewPopupUI.storeSubscriptionID(response.tick.id);
        }

        if (response.history) {
            response.history.times.some((time, idx) => {
                if (+time >= +contract.entry_tick_time) {
                    updateTable(response.history.prices[idx], time);
                    tick_count += 1;
                }
                return tick_count > contract.tick_count;
            });
        } else if (response.tick) {
            if (tick_count <= contract.tick_count &&
                +response.tick.epoch >= +contract.entry_tick_time) {
                updateTable(response.tick.quote, response.tick.epoch);
                tick_count += 1;
            }
        }
        showLocalTimeOnHover('.digit-spot-time');
    };

    const end = (proposal_open_contract) => {
        if (proposal_open_contract.status !== 'open') {
            DigitTicker.update(proposal_open_contract.tick_count, {
                quote: proposal_open_contract.exit_tick,
                epoch: proposal_open_contract.exit_tick_time,
            });
            if ($container.find('#digit_table').length !== proposal_open_contract.tick_count) {
                const request = {
                    ticks_history: contract.underlying,
                    start        : contract.entry_tick_time,
                    end          : contract.exit_tick_time,
                };

                // force rerender the table by sending the history
                BinarySocket.send(request, { callback: redrawFromHistory });
            }
        }
        if (proposal_open_contract.status === 'won') {
            DigitTicker.markAsWon();
            DigitTicker.markDigitAsWon(proposal_open_contract.exit_tick.slice(-1));
        }
        if (proposal_open_contract.status === 'lost') {
            DigitTicker.markAsLost();
            DigitTicker.markDigitAsLost(proposal_open_contract.exit_tick.slice(-1));
        }
    };

    return {
        end,
        init,
        update,
    };
})();

module.exports = DigitDisplay;
<|endoftext|>


<commit_before>import defaultImage from './images/default.png';
import darkImage from './images/dark.png';
import landsatImage from './images/landsat.png';
import satelliteImage from './images/satellite.png';

export const labels = {
  default: {
    value: 'default',
    label: 'Dark Labels',
    paint: {
      'text-color': '#1a1a1a',
      'text-halo-color': '#ffffff'
    },
    layout: {
      visibility: 'visible'
    }
  },
  lightLabels: {
    value: 'lightLabels',
    label: 'Light Labels',
    paint: {
      'text-color': '#ffffff',
      'text-halo-color': '#1a1a1a'
    },
    layout: {
      visibility: 'visible'
    }
  },
  noLabels: {
    label: 'No Labels',
    value: 'noLabels',
    url: '',
    layout: {
      visibility: 'none'
    }
  }
};

export default {
  default: {
    value: 'default',
    label: 'default',
    labelsKey: 'default',
    color: '#A2DFFF',
    image: defaultImage,
    layerStyles: [
      {
        id: 'background',
        'background-color': '#ffffff'
      },
      {
        id: 'waterway-river-canal',
        'line-color': '#8dcbf7'
      },
      {
        id: 'waterway-river-canal-shadow',
        'line-color': '#6ea5f2'
      },
      {
        id: 'waterway-small',
        'line-color': '#8dcbf7'
      },
      {
        id: 'water',
        'fill-color': '#aedffd'
      }
    ]
  },
  dark: {
    value: 'dark',
    label: 'dark matter',
    labelsKey: 'lightLabels',
    color: '#31312F',
    image: darkImage,
    layerStyles: [
      {
        id: 'background',
        'background-color': '#31312f'
      },
      {
        id: 'waterway-river-canal',
        'line-color': '#000000'
      },
      {
        id: 'waterway-river-canal-shadow',
        'line-color': '#000000'
      },
      {
        id: 'waterway-small',
        'line-color': '#000000'
      },
      {
        id: 'water',
        'fill-color': '#20201d'
      }
    ]
  },
  satellite: {
    value: 'satellite',
    label: 'Satellite',
    labelsKey: 'lightLabels',
    color: '#131620',
    image: satelliteImage,
    url: 'https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',
    layerStyles: [
      {
        id: 'background',
        'background-color': '#ffffff'
      },
      {
        id: 'waterway-river-canal',
        'line-color': '#131620'
      },
      {
        id: 'waterway-river-canal-shadow',
        'line-color': '#131620'
      },
      {
        id: 'waterway-small',
        'line-color': '#131620'
      },
      {
        id: 'water',
        'fill-color': '#131620'
      }
    ]
  },
  landsat: {
    value: 'landsat',
    label: 'landsat',
    labelsKey: 'lightLabels',
    color: '#0C0045',
    image: landsatImage,
    url:
      'https://production-api.globalforestwatch.org/v2/landsat-tiles/{year}/{z}/{x}/{y}',
    availableYears: [2017, 2016, 2015, 2014, 2013],
    defaultYear: 2017,
    layerStyles: [
      {
        id: 'background',
        'background-color': '#ffffff'
      },
      {
        id: 'waterway-river-canal',
        'line-color': '#0C0045'
      },
      {
        id: 'waterway-river-canal-shadow',
        'line-color': '#0C0045'
      },
      {
        id: 'waterway-small',
        'line-color': '#0C0045'
      },
      {
        id: 'water',
        'fill-color': '#0C0045'
      }
    ]
  },
  planet: {
    value: 'planet',
    label: 'Planet',
    labelsKey: 'default',
    color: '#131620',
    image: satelliteImage,
    url: `https://tiles.planet.com/basemaps/v1/planet-tiles/global_{frequency}_{period}_mosaic/gmap/{z}/{x}/{y}.png?api_key=${
      process.env.PLANET_API_KEY
    }`,
    layerStyles: [
      {
        id: 'background',
        'background-color': '#ffffff'
      },
      {
        id: 'waterway-river-canal',
        'line-color': '#03132e'
      },
      {
        id: 'waterway-river-canal-shadow',
        'line-color': '#03132e'
      },
      {
        id: 'waterway-small',
        'line-color': '#03132e'
      },
      {
        id: 'water',
        'fill-color': '#03132e'
      }
    ]
  }
};
<commit_msg>add light labels as planet labels color<commit_after>import defaultImage from './images/default.png';
import darkImage from './images/dark.png';
import landsatImage from './images/landsat.png';
import satelliteImage from './images/satellite.png';

export const labels = {
  default: {
    value: 'default',
    label: 'Dark Labels',
    paint: {
      'text-color': '#1a1a1a',
      'text-halo-color': '#ffffff'
    },
    layout: {
      visibility: 'visible'
    }
  },
  lightLabels: {
    value: 'lightLabels',
    label: 'Light Labels',
    paint: {
      'text-color': '#ffffff',
      'text-halo-color': '#1a1a1a'
    },
    layout: {
      visibility: 'visible'
    }
  },
  noLabels: {
    label: 'No Labels',
    value: 'noLabels',
    url: '',
    layout: {
      visibility: 'none'
    }
  }
};

export default {
  default: {
    value: 'default',
    label: 'default',
    labelsKey: 'default',
    color: '#A2DFFF',
    image: defaultImage,
    layerStyles: [
      {
        id: 'background',
        'background-color': '#ffffff'
      },
      {
        id: 'waterway-river-canal',
        'line-color': '#8dcbf7'
      },
      {
        id: 'waterway-river-canal-shadow',
        'line-color': '#6ea5f2'
      },
      {
        id: 'waterway-small',
        'line-color': '#8dcbf7'
      },
      {
        id: 'water',
        'fill-color': '#aedffd'
      }
    ]
  },
  dark: {
    value: 'dark',
    label: 'dark matter',
    labelsKey: 'lightLabels',
    color: '#31312F',
    image: darkImage,
    layerStyles: [
      {
        id: 'background',
        'background-color': '#31312f'
      },
      {
        id: 'waterway-river-canal',
        'line-color': '#000000'
      },
      {
        id: 'waterway-river-canal-shadow',
        'line-color': '#000000'
      },
      {
        id: 'waterway-small',
        'line-color': '#000000'
      },
      {
        id: 'water',
        'fill-color': '#20201d'
      }
    ]
  },
  satellite: {
    value: 'satellite',
    label: 'Satellite',
    labelsKey: 'lightLabels',
    color: '#131620',
    image: satelliteImage,
    url: 'https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',
    layerStyles: [
      {
        id: 'background',
        'background-color': '#ffffff'
      },
      {
        id: 'waterway-river-canal',
        'line-color': '#131620'
      },
      {
        id: 'waterway-river-canal-shadow',
        'line-color': '#131620'
      },
      {
        id: 'waterway-small',
        'line-color': '#131620'
      },
      {
        id: 'water',
        'fill-color': '#131620'
      }
    ]
  },
  landsat: {
    value: 'landsat',
    label: 'landsat',
    labelsKey: 'lightLabels',
    color: '#0C0045',
    image: landsatImage,
    url:
      'https://production-api.globalforestwatch.org/v2/landsat-tiles/{year}/{z}/{x}/{y}',
    availableYears: [2017, 2016, 2015, 2014, 2013],
    defaultYear: 2017,
    layerStyles: [
      {
        id: 'background',
        'background-color': '#ffffff'
      },
      {
        id: 'waterway-river-canal',
        'line-color': '#0C0045'
      },
      {
        id: 'waterway-river-canal-shadow',
        'line-color': '#0C0045'
      },
      {
        id: 'waterway-small',
        'line-color': '#0C0045'
      },
      {
        id: 'water',
        'fill-color': '#0C0045'
      }
    ]
  },
  planet: {
    value: 'planet',
    label: 'Planet',
    labelsKey: 'lightLabels',
    color: '#131620',
    image: satelliteImage,
    url: `https://tiles.planet.com/basemaps/v1/planet-tiles/global_{frequency}_{period}_mosaic/gmap/{z}/{x}/{y}.png?api_key=${
      process.env.PLANET_API_KEY
    }`,
    layerStyles: [
      {
        id: 'background',
        'background-color': '#ffffff'
      },
      {
        id: 'waterway-river-canal',
        'line-color': '#03132e'
      },
      {
        id: 'waterway-river-canal-shadow',
        'line-color': '#03132e'
      },
      {
        id: 'waterway-small',
        'line-color': '#03132e'
      },
      {
        id: 'water',
        'fill-color': '#03132e'
      }
    ]
  }
};
<|endoftext|>