<commit_before>/* eslint-disable no-param-reassign */

import axios from 'axios';
import parse from 'date-fns/parse';
import isPast from 'date-fns/is_past';

import formatTransaction from './utils/format-transaction';
import { PORTAL_API_URL } from '../../constants';

const SET_RAW_DATA = 'SET_RAW_DATA';

const initialState = { data: {} };

const mutations = {
  [SET_RAW_DATA](currentState, data) {
    currentState.data = data;
  },
};

const actions = {
  getOtherUser: async ({ commit, rootState }, email) => {
    const { accessToken } = rootState.tokenUser;
    const { data } = await axios.get(`${PORTAL_API_URL}persons/`, {
      params: { email },
      headers: { Authorization: `Bearer ${accessToken}` },
    });

    commit(SET_RAW_DATA, data[0]);
  },

  getUser: async ({ commit, rootState }) => {
    const { accessToken } = rootState.tokenUser;
    const { data } = await axios.get(`${PORTAL_API_URL}self/`, {
      headers: { Authorization: `Bearer ${accessToken}` },
    });

    commit(SET_RAW_DATA, data);
  },

  updateUser: async ({ getters, rootState }, updates) => {
    const { accessToken } = rootState.tokenUser;
    const { userId } = getters;

    await axios.patch(`${PORTAL_API_URL}persons/${userId}/`, updates, {
      headers: { Authorization: `Bearer ${accessToken}` },
    });
  },

  updateIdentity: async ({ getters, rootState }, updates) => {
    const { accessToken } = rootState.tokenUser;
    const { userId, identityId } = getters;

    await axios.patch(
      `${PORTAL_API_URL}persons/${userId}/identities/${identityId}/`,
      updates,
      {
        headers: { Authorization: `Bearer ${accessToken}` },
      }
    );
  },

  linkIdentity: async ({ getters, rootState }, identity) => {
    const { accessToken } = rootState.tokenUser;
    const { userId, email } = getters;

    await axios.put(
      `${PORTAL_API_URL}persons/${userId}/identities/${email}/`,
      identity,
      {
        headers: { Authorization: `Bearer ${accessToken}` },
      }
    );
  },

  confirmLinkedIdentity: async ({ getters, rootState }, ticket) => {
    const { accessToken } = rootState.tokenUser;
    const { userId, email } = getters;

    await axios.put(
      `${PORTAL_API_URL}persons/${userId}/identities/${email}/?ticket=${ticket}`,
      {},
      {
        headers: { Authorization: `Bearer ${accessToken}` },
      }
    );
  },
};

const getters = {
  email: (
    _,
    __,
    {
      tokenUser: {
        idTokenPayload: { email },
      },
    }
  ) => email,

  identity: ({ data: { identities = [] } }, { email }) => {
    if (!identities.length) return {};

    const [goodIdentity] = identities.filter(
      ({ email: identityEmail }) => identityEmail === email
    );

    return goodIdentity;
  },

  userId: ({ data: { id } }) => id,

  identityId: (_, { identity: { id } }) => id,

  firstName: ({ data: { first_name: firstName } }) => firstName,

  lastName: ({ data: { last_name: lastName } }) => lastName,

  greeting: ({ data: { greeting } }) => greeting,

  zip: ({ data: { postal_code: zip } }) => zip,

  lastYearAmount: ({ data: { total_gifts_last_year: lastYearAmount } }) =>
    lastYearAmount,

  didConsent: (_, { identity: { tribune_offers_consent: didConsent } }) =>
    didConsent,

  linkedEmails: ({ data: { identities = [] } }) =>
    identities.map(({ email }) => email),

  twitterUrl: ({ data: { twitter_share_url: twitterUrl } }) => twitterUrl,

  facebookUrl: ({ data: { facebook_share_url: facebookUrl } }) => facebookUrl,

  emailUrl: ({ data: { email_share_url: emailUrl } }) => emailUrl,

  ambassadorUrl: ({ data: { ambassador_url: ambassadorUrl } }) => ambassadorUrl,

  membershipExpirationDate: ({
    data: { membership_expiration_date: membershipExpirationDate },
  }) => membershipExpirationDate,

  membershipLevel: ({ data: { membership_level: membershipLevel } }) =>
    membershipLevel,

  isNeverGiven: ({ data: { never_given: isNeverGiven } }) => isNeverGiven,

  isCurrentBlastSubscriber: ({
    data: { is_current_blast_subscriber: isCurrentBlastSubscriber },
  }) => isCurrentBlastSubscriber,

  isFormerBlastSubscriber: ({
    data: { is_former_blast_subscriber: isFormerBlastSubscriber },
  }) => isFormerBlastSubscriber,

  isBlastSubscriber: (
    _,
    { isCurrentBlastSubscriber, isFormerBlastSubscriber }
  ) => isCurrentBlastSubscriber || isFormerBlastSubscriber,

  isCircleDonor: (
    {
      data: {
        is_current_circle: isCurrentCircle,
        is_former_circle: isFormerCircle,
      },
    },
    { membershipExpirationDate }
  ) => (isCurrentCircle || isFormerCircle) && !!membershipExpirationDate,

  isSingleDonor: (
    { data: { is_recurring_donor: isRecurringDonor, is_mdev: isMDev } },
    { isNeverGiven, membershipExpirationDate }
  ) =>
    !isNeverGiven && !isRecurringDonor && !!membershipExpirationDate && !isMDev,

  isRecurringDonor: (
    { data: { is_recurring_donor: isRecurringDonor, is_mdev: isMDev } },
    { isCircleDonor, membershipExpirationDate }
  ) =>
    isRecurringDonor && !!membershipExpirationDate && !isMDev && !isCircleDonor,

  isCustomDonor: (
    { data: { is_mdev: isMDev } },
    { isNeverGiven, isCircleDonor, membershipExpirationDate }
  ) =>
    (isMDev && !isCircleDonor) || (!isNeverGiven && !membershipExpirationDate),

  hasGivenNotCustom: (_, { isCircleDonor, isSingleDonor, isRecurringDonor }) =>
    isCircleDonor || isSingleDonor || isRecurringDonor,

  isExpired: (_, { membershipExpirationDate }) => {
    if (membershipExpirationDate) {
      return isPast(parse(membershipExpirationDate));
    }
    return null;
  },

  willExpire: (_, { isExpired, nextTransaction, membershipExpirationDate }) => {
    if (membershipExpirationDate) {
      return !nextTransaction && !isExpired;
    }
    return null;
  },

  allTransactions: ({ data: { transactions = [] } }) => {
    const nonBlastTransactions = transactions.filter(
      ({ type }) => type.toLowerCase() !== 'the blast'
    );

    return nonBlastTransactions.map(transaction =>
      formatTransaction(transaction)
    );
  },

  nextTransaction: ({ data: { next_transaction: nextTransaction } }) => {
    if (nextTransaction) {
      return formatTransaction(nextTransaction);
    }
    return null;
  },

  lastTransaction: ({ data: { last_transaction: lastTransaction } }) => {
    if (lastTransaction) {
      return formatTransaction(lastTransaction);
    }
    return null;
  },

  pastTransactions: (_, { allTransactions }) => {
    const pastTransactions = allTransactions.filter(({ date }) => isPast(date));

    return pastTransactions.sort(
      ({ date: firstDate }, { date: secondDate }) => {
        if (parse(firstDate) > parse(secondDate)) return -1;
        if (parse(firstDate) < parse(secondDate)) return 1;
        return 0;
      }
    );
  },

  allBlastTransactions: ({ data: { transactions = [] } }) => {
    const blastTransactions = transactions.filter(
      ({ type }) => type.toLowerCase() === 'the blast'
    );

    return blastTransactions.map(transaction => formatTransaction(transaction));
  },

  nextBlastTransaction: ({
    data: { next_blast_transaction: nextBlastTransaction },
  }) => {
    if (nextBlastTransaction) {
      return formatTransaction(nextBlastTransaction);
    }
    return null;
  },

  lastBlastTransaction: ({
    data: { last_blast_transaction: lastBlastTransaction },
  }) => {
    if (lastBlastTransaction) {
      return formatTransaction(lastBlastTransaction);
    }
    return null;
  },

  pastBlastTransactions: (_, { allBlastTransactions }) => {
    const pastBlastTransactions = allBlastTransactions.filter(({ date }) =>
      isPast(date)
    );

    return pastBlastTransactions.sort(
      ({ date: firstDate }, { date: secondDate }) => {
        if (parse(firstDate) > parse(secondDate)) return -1;
        if (parse(firstDate) < parse(secondDate)) return 1;
        return 0;
      }
    );
  },
};

export default {
  namespaced: true,
  state: initialState,
  mutations,
  actions,
  getters,
};
<commit_msg>give fallbacks if first, last, zip are null<commit_after>/* eslint-disable no-param-reassign */

import axios from 'axios';
import parse from 'date-fns/parse';
import isPast from 'date-fns/is_past';

import formatTransaction from './utils/format-transaction';
import { PORTAL_API_URL } from '../../constants';

const SET_RAW_DATA = 'SET_RAW_DATA';

const initialState = { data: {} };

const mutations = {
  [SET_RAW_DATA](currentState, data) {
    currentState.data = data;
  },
};

const actions = {
  getOtherUser: async ({ commit, rootState }, email) => {
    const { accessToken } = rootState.tokenUser;
    const { data } = await axios.get(`${PORTAL_API_URL}persons/`, {
      params: { email },
      headers: { Authorization: `Bearer ${accessToken}` },
    });

    commit(SET_RAW_DATA, data[0]);
  },

  getUser: async ({ commit, rootState }) => {
    const { accessToken } = rootState.tokenUser;
    const { data } = await axios.get(`${PORTAL_API_URL}self/`, {
      headers: { Authorization: `Bearer ${accessToken}` },
    });

    commit(SET_RAW_DATA, data);
  },

  updateUser: async ({ getters, rootState }, updates) => {
    const { accessToken } = rootState.tokenUser;
    const { userId } = getters;

    await axios.patch(`${PORTAL_API_URL}persons/${userId}/`, updates, {
      headers: { Authorization: `Bearer ${accessToken}` },
    });
  },

  updateIdentity: async ({ getters, rootState }, updates) => {
    const { accessToken } = rootState.tokenUser;
    const { userId, identityId } = getters;

    await axios.patch(
      `${PORTAL_API_URL}persons/${userId}/identities/${identityId}/`,
      updates,
      {
        headers: { Authorization: `Bearer ${accessToken}` },
      }
    );
  },

  linkIdentity: async ({ getters, rootState }, identity) => {
    const { accessToken } = rootState.tokenUser;
    const { userId, email } = getters;

    await axios.put(
      `${PORTAL_API_URL}persons/${userId}/identities/${email}/`,
      identity,
      {
        headers: { Authorization: `Bearer ${accessToken}` },
      }
    );
  },

  confirmLinkedIdentity: async ({ getters, rootState }, ticket) => {
    const { accessToken } = rootState.tokenUser;
    const { userId, email } = getters;

    await axios.put(
      `${PORTAL_API_URL}persons/${userId}/identities/${email}/?ticket=${ticket}`,
      {},
      {
        headers: { Authorization: `Bearer ${accessToken}` },
      }
    );
  },
};

const getters = {
  email: (
    _,
    __,
    {
      tokenUser: {
        idTokenPayload: { email },
      },
    }
  ) => email,

  identity: ({ data: { identities = [] } }, { email }) => {
    if (!identities.length) return {};

    const [goodIdentity] = identities.filter(
      ({ email: identityEmail }) => identityEmail === email
    );

    return goodIdentity;
  },

  userId: ({ data: { id } }) => id,

  identityId: (_, { identity: { id } }) => id,

  firstName: ({ data: { first_name: firstName } }) => firstName || '',

  lastName: ({ data: { last_name: lastName } }) => lastName || '',

  greeting: ({ data: { greeting } }) => greeting || '',

  zip: ({ data: { postal_code: zip } }) => zip || '',

  lastYearAmount: ({ data: { total_gifts_last_year: lastYearAmount } }) =>
    lastYearAmount,

  didConsent: (_, { identity: { tribune_offers_consent: didConsent } }) =>
    didConsent,

  linkedEmails: ({ data: { identities = [] } }) =>
    identities.map(({ email }) => email),

  twitterUrl: ({ data: { twitter_share_url: twitterUrl } }) => twitterUrl,

  facebookUrl: ({ data: { facebook_share_url: facebookUrl } }) => facebookUrl,

  emailUrl: ({ data: { email_share_url: emailUrl } }) => emailUrl,

  ambassadorUrl: ({ data: { ambassador_url: ambassadorUrl } }) => ambassadorUrl,

  membershipExpirationDate: ({
    data: { membership_expiration_date: membershipExpirationDate },
  }) => membershipExpirationDate,

  membershipLevel: ({ data: { membership_level: membershipLevel } }) =>
    membershipLevel,

  isNeverGiven: ({ data: { never_given: isNeverGiven } }) => isNeverGiven,

  isCurrentBlastSubscriber: ({
    data: { is_current_blast_subscriber: isCurrentBlastSubscriber },
  }) => isCurrentBlastSubscriber,

  isFormerBlastSubscriber: ({
    data: { is_former_blast_subscriber: isFormerBlastSubscriber },
  }) => isFormerBlastSubscriber,

  isBlastSubscriber: (
    _,
    { isCurrentBlastSubscriber, isFormerBlastSubscriber }
  ) => isCurrentBlastSubscriber || isFormerBlastSubscriber,

  isCircleDonor: (
    {
      data: {
        is_current_circle: isCurrentCircle,
        is_former_circle: isFormerCircle,
      },
    },
    { membershipExpirationDate }
  ) => (isCurrentCircle || isFormerCircle) && !!membershipExpirationDate,

  isSingleDonor: (
    { data: { is_recurring_donor: isRecurringDonor, is_mdev: isMDev } },
    { isNeverGiven, membershipExpirationDate }
  ) =>
    !isNeverGiven && !isRecurringDonor && !!membershipExpirationDate && !isMDev,

  isRecurringDonor: (
    { data: { is_recurring_donor: isRecurringDonor, is_mdev: isMDev } },
    { isCircleDonor, membershipExpirationDate }
  ) =>
    isRecurringDonor && !!membershipExpirationDate && !isMDev && !isCircleDonor,

  isCustomDonor: (
    { data: { is_mdev: isMDev } },
    { isNeverGiven, isCircleDonor, membershipExpirationDate }
  ) =>
    (isMDev && !isCircleDonor) || (!isNeverGiven && !membershipExpirationDate),

  hasGivenNotCustom: (_, { isCircleDonor, isSingleDonor, isRecurringDonor }) =>
    isCircleDonor || isSingleDonor || isRecurringDonor,

  isExpired: (_, { membershipExpirationDate }) => {
    if (membershipExpirationDate) {
      return isPast(parse(membershipExpirationDate));
    }
    return null;
  },

  willExpire: (_, { isExpired, nextTransaction, membershipExpirationDate }) => {
    if (membershipExpirationDate) {
      return !nextTransaction && !isExpired;
    }
    return null;
  },

  allTransactions: ({ data: { transactions = [] } }) => {
    const nonBlastTransactions = transactions.filter(
      ({ type }) => type.toLowerCase() !== 'the blast'
    );

    return nonBlastTransactions.map(transaction =>
      formatTransaction(transaction)
    );
  },

  nextTransaction: ({ data: { next_transaction: nextTransaction } }) => {
    if (nextTransaction) {
      return formatTransaction(nextTransaction);
    }
    return null;
  },

  lastTransaction: ({ data: { last_transaction: lastTransaction } }) => {
    if (lastTransaction) {
      return formatTransaction(lastTransaction);
    }
    return null;
  },

  pastTransactions: (_, { allTransactions }) => {
    const pastTransactions = allTransactions.filter(({ date }) => isPast(date));

    return pastTransactions.sort(
      ({ date: firstDate }, { date: secondDate }) => {
        if (parse(firstDate) > parse(secondDate)) return -1;
        if (parse(firstDate) < parse(secondDate)) return 1;
        return 0;
      }
    );
  },

  allBlastTransactions: ({ data: { transactions = [] } }) => {
    const blastTransactions = transactions.filter(
      ({ type }) => type.toLowerCase() === 'the blast'
    );

    return blastTransactions.map(transaction => formatTransaction(transaction));
  },

  nextBlastTransaction: ({
    data: { next_blast_transaction: nextBlastTransaction },
  }) => {
    if (nextBlastTransaction) {
      return formatTransaction(nextBlastTransaction);
    }
    return null;
  },

  lastBlastTransaction: ({
    data: { last_blast_transaction: lastBlastTransaction },
  }) => {
    if (lastBlastTransaction) {
      return formatTransaction(lastBlastTransaction);
    }
    return null;
  },

  pastBlastTransactions: (_, { allBlastTransactions }) => {
    const pastBlastTransactions = allBlastTransactions.filter(({ date }) =>
      isPast(date)
    );

    return pastBlastTransactions.sort(
      ({ date: firstDate }, { date: secondDate }) => {
        if (parse(firstDate) > parse(secondDate)) return -1;
        if (parse(firstDate) < parse(secondDate)) return 1;
        return 0;
      }
    );
  },
};

export default {
  namespaced: true,
  state: initialState,
  mutations,
  actions,
  getters,
};
<|endoftext|>


<commit_before>//= require ../view

(function () {
  'use strict';

  var app = window.app;

  var _ = window._;
  var PIXI = window.PIXI;
  var requestAnimFrame = window.requestAnimFrame;

  app.GamesShowView = app.View.extend({
    width: app.config.game.width,

    height: app.config.game.height,

    listeners: {
      users: {add: 'addCharacter', 'remove change:isDead': 'removeCharacter'}
    },

    initialize: function () {
      this.stage = new PIXI.Stage(0xffffff);
      this.renderer = new PIXI.autoDetectRenderer(this.width, this.height);
      this.characters = new app.Character.Collection();
      this.container = new PIXI.DisplayObjectContainer();
      this.container.addChild(this.layer1 = new PIXI.DisplayObjectContainer());
      this.container.addChild(this.layer2 = new PIXI.DisplayObjectContainer());
      this.container.position.x = this.width / 2;
      this.container.position.y = this.height - 100;
      this.stage.addChild(this.container);
      this.$el.append(this.renderer.view);
      this.users = this.model.get('users');
      var line = new PIXI.Graphics();
      line.lineStyle(2, 0xFF0000);
      line.moveTo(-(this.width / 2), 0);
      line.lineTo(this.width / 2, 0);
      this.layer1.addChild(line);
      this.createSawblades();
      _.bindAll(this, 'render');
      this.render();
    },

    render: function () {
      this.renderer.render(this.stage);
      requestAnimFrame(this.render);
    },

    createSawblades: function () {
      var sawBlades = _.flatten(_.map([-1, 1], function (dir) {
        return _.times(30, function (y) {
          var sawBlade = new PIXI.Sprite(PIXI.TextureCache['saw-blade.png']);
          sawBlade.anchor.x = sawBlade.anchor.y = 0.5;
          sawBlade.position.x = dir * (app.config.game.width / 2);
          sawBlade.position.y = -((0.5 + y) * (sawBlade.height / 2));
          sawBlade.scale.x = dir;
          sawBlade.rotation = Math.PI * 2 * Math.random();
          this.layer2.addChildAt(
            sawBlade,
            _.random(this.layer2.children.length)
          );
          return sawBlade;
        }, this);
      }, this));
      this.listenTo(this.model, 'step', function (dt) {
        _.each(sawBlades, function (sawBlade) {
          sawBlade.rotation += sawBlade.scale.x * Math.PI * 10 * dt;
        });
      });
    },

    addCharacter: function (user) {
      var character = new app.Character({user: user});
      this.characters.add(character);
      this.layer2.addChild(character.get('sprite'));
    },

    removeCharacter: function (user) {
      var character = this.characters.findWhere({user: user});
      if (!character) return;
      var sprite = character.get('sprite');
      this.characters.remove(character);
      this.layer2.removeChild(sprite);
      var killForce = user.get('killForce');
      new app.ExplosionPiece.Collection(null, {
        sprite: sprite,
        rows: 20,
        columns: 10,
        game: this.model,
        container: this.layer2,
        xv: user.get('xv') + ((killForce && killForce.xv) || 0),
        yv: -(user.get('yv') + ((killForce && killForce.yv) || 0))
      });
    }
  });
})();
<commit_msg>Death should strictly follow kill force<commit_after>//= require ../view

(function () {
  'use strict';

  var app = window.app;

  var _ = window._;
  var PIXI = window.PIXI;
  var requestAnimFrame = window.requestAnimFrame;

  app.GamesShowView = app.View.extend({
    width: app.config.game.width,

    height: app.config.game.height,

    listeners: {
      users: {add: 'addCharacter', 'remove change:isDead': 'removeCharacter'}
    },

    initialize: function () {
      this.stage = new PIXI.Stage(0xffffff);
      this.renderer = new PIXI.autoDetectRenderer(this.width, this.height);
      this.characters = new app.Character.Collection();
      this.container = new PIXI.DisplayObjectContainer();
      this.container.addChild(this.layer1 = new PIXI.DisplayObjectContainer());
      this.container.addChild(this.layer2 = new PIXI.DisplayObjectContainer());
      this.container.position.x = this.width / 2;
      this.container.position.y = this.height - 100;
      this.stage.addChild(this.container);
      this.$el.append(this.renderer.view);
      this.users = this.model.get('users');
      var line = new PIXI.Graphics();
      line.lineStyle(2, 0xFF0000);
      line.moveTo(-(this.width / 2), 0);
      line.lineTo(this.width / 2, 0);
      this.layer1.addChild(line);
      this.createSawblades();
      _.bindAll(this, 'render');
      this.render();
    },

    render: function () {
      this.renderer.render(this.stage);
      requestAnimFrame(this.render);
    },

    createSawblades: function () {
      var sawBlades = _.flatten(_.map([-1, 1], function (dir) {
        return _.times(30, function (y) {
          var sawBlade = new PIXI.Sprite(PIXI.TextureCache['saw-blade.png']);
          sawBlade.anchor.x = sawBlade.anchor.y = 0.5;
          sawBlade.position.x = dir * (app.config.game.width / 2);
          sawBlade.position.y = -((0.5 + y) * (sawBlade.height / 2));
          sawBlade.scale.x = dir;
          sawBlade.rotation = Math.PI * 2 * Math.random();
          this.layer2.addChildAt(
            sawBlade,
            _.random(this.layer2.children.length)
          );
          return sawBlade;
        }, this);
      }, this));
      this.listenTo(this.model, 'step', function (dt) {
        _.each(sawBlades, function (sawBlade) {
          sawBlade.rotation += sawBlade.scale.x * Math.PI * 10 * dt;
        });
      });
    },

    addCharacter: function (user) {
      var character = new app.Character({user: user});
      this.characters.add(character);
      this.layer2.addChild(character.get('sprite'));
    },

    removeCharacter: function (user) {
      var character = this.characters.findWhere({user: user});
      if (!character) return;
      var sprite = character.get('sprite');
      this.characters.remove(character);
      this.layer2.removeChild(sprite);
      var killForce = user.get('killForce');
      new app.ExplosionPiece.Collection(null, {
        sprite: sprite,
        rows: 20,
        columns: 10,
        game: this.model,
        container: this.layer2,
        xv: (killForce && killForce.xv) || 0,
        yv: (killForce && -killForce.yv) || 0
      });
    }
  });
})();
<|endoftext|>


<commit_before>
/* This script determines the relative strength of the actors by making them
 * fight each other. */

require('babel-register');

const RG = require('../client/src/battles');
const fs = require('fs');

const parser = RG.ObjectShell.getParser();
const Actors = require('../client/data/actors.js');

const histogram = {};

const matchLimit = 200000;
let nMatches = 0;
let matchesLeftOut = 0;
const nRounds = 2;

const startTime = new Date().getTime();
const names = Actors.filter(a => a.name);

for (let n = 0; n < nRounds; n++) {
    console.error(`Starting round ${n}`);
    for (let i = 0; i < names.length; i++) {
        for (let j = 0; j < names.length; j++) {
            if (i !== j) {
                const a1 = Actors[i];
                const a2 = Actors[j];
                if (validActorsForTest(a1, a2)) {
                    if (nMatches < matchLimit) {
                        runBattleTest(a1, a2);
                        ++nMatches;
                        // const msg = `${a1.name} VS ${a2.name}`;
                        // console.log(`Finished match ${nMatches}: ${msg}`);
                    }
                    else {
                        ++matchesLeftOut;
                    }
                }
            }
        }
    }
    console.error(`Round ${n} finished. Matches: ${nMatches}`);
}

printOutputs();
const endTime = new Date().getTime();
const durationMs = endTime - startTime;
console.log('Total duration ' + (durationMs / 1000) + ' s');

//---------------------------------------------------------------------------
// HELPER FUNCTIONS
//---------------------------------------------------------------------------

function validActorsForTest(a1, a2) {
    if (a1.name !== a2.name) {
        if (!a1.dontCreate && !a2.dontCreate) {
            if (a1.base !== 'SpecialBase' && a2.base !== 'SpecialBase') {
                if (a1.type !== 'spirit' && a2.type !== 'spirit') {
                    return true;
                }
            }
        }
    }
    return false;
}

function runBattleTest(a1, a2) {
    initHistograms(a1, a2);

    let watchdog = 200;
    const arena = RG.FACT.createLevel('arena', 7, 7);
    const actor1 = parser.createActor(a1.name);
    const actor2 = parser.createActor(a2.name);
    arena.addActor(actor1, 1, 1);
    arena.addActor(actor2, 6, 6);

    actor1.addEnemy(actor2);
    actor2.addEnemy(actor1);

    const game = new RG.Game.Main();
    game.addLevel(arena);
    game.addActiveLevel(arena);

    const h1 = actor1.get('Health');
    const h2 = actor2.get('Health');

    while (h1.isAlive() && h2.isAlive()) {
        game.simulate();
        if (--watchdog === 0) {break;}
    }

    if (watchdog === 0) {
        histogram[a1.name].tied += 1;
        histogram[a2.name].tied += 1;
    }
    else if (h1.isAlive()) {
        histogram[a1.name].won += 1;
        histogram[a2.name].lost += 1;
    }
    else {
        histogram[a1.name].lost += 1;
        histogram[a2.name].won += 1;
    }

}

function initHistograms(a1, a2) {
    if (!histogram[a1.name]) {
        histogram[a1.name] = {won: 0, lost: 0, tied: 0};
    }
    if (!histogram[a2.name]) {
        histogram[a2.name] = {won: 0, lost: 0, tied: 0};
    }
}

function printOutputs() {
    console.log('======= RESULTS =======');
    console.log(JSON.stringify(histogram, null, 1));
    console.log('Matches still remaining: ' + matchesLeftOut);

    const outputFile = 'actor_fight_results.csv';
    fs.writeFileSync(outputFile, 'Actor,Won,Tied,Lost\n');
    Object.keys(histogram).forEach(key => {
        const {won, lost, tied} = histogram[key];
        const newKey = key.replace(',', '');
        const csvData = `${newKey},${won},${tied},${lost}\n`;
        fs.appendFileSync(outputFile, csvData);
    });
}

<commit_msg>Added monitoring feature for individual actor.<commit_after>
/* This script determines the relative strength of the actors by making them
 * fight each other. */

require('babel-register');

const RG = require('../client/src/battles');
const fs = require('fs');

const parser = RG.ObjectShell.getParser();
const Actors = require('../client/data/actors.js');

const histogram = {};

const matchLimit = 200000;
let nMatches = 0;
let matchesLeftOut = 0;
const nRounds = 2;

const startTime = new Date().getTime();
const shells = Actors.filter(a => !((/spirit/i).test(a.name)));

const monitorActor = 'lich';
const monitor = {
    name: monitorActor,
    won: {},
    lost: {},
    tied: {}
};

for (let n = 0; n < nRounds; n++) {
    console.error(`Starting round ${n}`);
    for (let i = 0; i < shells.length; i++) {
        for (let j = 0; j < shells.length; j++) {
            if (i !== j) {
                const a1 = shells[i];
                const a2 = shells[j];
                if (validActorsForTest(a1, a2)) {
                    if (nMatches < matchLimit) {
                        runBattleTest(a1, a2);
                        ++nMatches;
                        // const msg = `${a1.name} VS ${a2.name}`;
                        // console.log(`Finished match ${nMatches}: ${msg}`);
                    }
                    else {
                        ++matchesLeftOut;
                    }
                }
            }
        }
    }
    console.error(`Round ${n} finished. Matches: ${nMatches}`);
}

printOutputs();
const endTime = new Date().getTime();
const durationMs = endTime - startTime;
console.log('Total duration ' + (durationMs / 1000) + ' s');

//---------------------------------------------------------------------------
// HELPER FUNCTIONS
//---------------------------------------------------------------------------

function validActorsForTest(a1, a2) {
    if (a1.name !== a2.name) {
        if (!a1.dontCreate && !a2.dontCreate) {
            if (a1.base !== 'SpecialBase' && a2.base !== 'SpecialBase') {
                if (a1.type !== 'spirit' && a2.type !== 'spirit') {
                    return true;
                }
            }
        }
    }
    return false;
}

function runBattleTest(a1, a2) {
    initHistograms(a1, a2);

    let watchdog = 300;
    const arena = RG.FACT.createLevel('arena', 7, 7);
    const actor1 = parser.createActor(a1.name);
    const actor2 = parser.createActor(a2.name);
    arena.addActor(actor1, 1, 1);
    arena.addActor(actor2, 6, 6);

    actor1.addEnemy(actor2);
    actor2.addEnemy(actor1);

    const game = new RG.Game.Main();
    game.addLevel(arena);
    game.addActiveLevel(arena);

    const h1 = actor1.get('Health');
    const h2 = actor2.get('Health');

    while (h1.isAlive() && h2.isAlive()) {
        game.simulate();
        if (--watchdog === 0) {break;}
    }

    if (watchdog === 0) {
        histogram[a1.name].tied += 1;
        histogram[a2.name].tied += 1;
        if (a1.name === monitorActor) {
            monitor.tied[a2.name] += 1;
        }
        else if (a2.name === monitorActor) {
            monitor.tiedt[a1.name] += 1;
        }
    }
    else if (h1.isAlive()) {
        histogram[a1.name].won += 1;
        histogram[a2.name].lost += 1;
        if (a1.name === monitorActor) {
            monitor.won[a2.name] += 1;
        }
        else if (a2.name === monitorActor) {
            monitor.lost[a1.name] += 1;
        }
    }
    else {
        histogram[a1.name].lost += 1;
        histogram[a2.name].won += 1;
        if (a1.name === monitorActor) {
            monitor.lost[a2.name] += 1;
        }
        else if (a2.name === monitorActor) {
            monitor.won[a1.name] += 1;
        }
    }

}

function initHistograms(a1, a2) {
    if (!histogram[a1.name]) {
        histogram[a1.name] = {won: 0, lost: 0, tied: 0};
    }
    if (!histogram[a2.name]) {
        histogram[a2.name] = {won: 0, lost: 0, tied: 0};
    }
}

function printOutputs() {
    console.log('======= RESULTS =======');
    console.log(JSON.stringify(histogram, null, 1));
    console.log('Matches still remaining: ' + matchesLeftOut);

    console.log(JSON.stringify(monitor));

    const outputFile = 'actor_fight_results.csv';
    fs.writeFileSync(outputFile, 'Actor,Won,Tied,Lost\n');
    Object.keys(histogram).forEach(key => {
        const {won, lost, tied} = histogram[key];
        const newKey = key.replace(',', '');
        const csvData = `${newKey},${won},${tied},${lost}\n`;
        fs.appendFileSync(outputFile, csvData);
    });
}

<|endoftext|>


<commit_before>define('Mobile/SalesLogix/Views/History/Edit', [
    'dojo/_base/declare',
    'dojo/_base/array',
    'dojo/string',
    'Mobile/SalesLogix/Validator',
    'Sage/Platform/Mobile/Utility',
    'Sage/Platform/Mobile/Edit'
], function(
    declare,
    array,
    string,
    validator,
    utility,
    Edit
) {

    return declare('Mobile.SalesLogix.Views.History.Edit', [Edit], {
        //Localization
        accountText: 'account',
        noteDescriptionTitleText: 'Note Description',
        contactText: 'contact',
        longNotesText: 'notes',
        longNotesTitleText: 'Notes',
        opportunityText: 'opportunity',
        ticketNumberText: 'ticket',
        regardingText: 'regarding',
        isLeadText: 'for lead',
        startingText: 'time',
		startingFormatText : 'M/d/yyyy h:mm tt',
        titleText: 'Note',
        companyText: 'company',
        leadText: 'lead',
        relatedItemsText: 'Related Items',

        //View Properties
        id: 'history_edit',
        fieldsForLeads: ['AccountName', 'Lead'],
        fieldsForStandard: ['Account', 'Contact', 'Opportunity', 'Ticket'],
        entityName: 'History',
        resourceKind: 'history',
        insertSecurity: null, //'Entities/History/Add',
        updateSecurity: null, //'Entities/History/Edit',
        querySelect: [
            'AccountId',
            'AccountName',
            'ContactId',
            'ContactName',
            'Description',
            'LongNotes',
            'Notes',
            'OpportunityId',
            'OpportunityName',
            'TicketId',
            'TicketNumber',
            'Type',
            'LeadId',
            'LeadName',
            'StartDate'
        ],

        init: function() {
            this.inherited(arguments);

            this.connect(this.fields['Lead'], 'onChange', this.onLeadChange);
            this.connect(this.fields['IsLead'], 'onChange', this.onIsLeadChange);

            this.connect(this.fields['Account'], 'onChange', this.onAccountChange);
            this.connect(this.fields['Contact'], 'onChange', this.onAccountDependentChange);
            this.connect(this.fields['Opportunity'], 'onChange', this.onAccountDependentChange);
            this.connect(this.fields['Ticket'], 'onChange', this.onAccountDependentChange);
        },
        isHistoryForLead: function(entry) {
            return entry && /^[\w]{12}$/.test(entry['LeadId']);
        },
        isInLeadContext: function() {
            var insert = this.options && this.options.insert,
                entry = this.options && this.options.entry,
                lead = (insert && App.isNavigationFromResourceKind('leads', function(o, c) { return c.resourceKind === 'leads'; })) || this.isHistoryForLead(entry);
            return !!lead;
        },
        beforeTransitionTo: function() {
            this.inherited(arguments);

            // we hide the lead or standard fields here, as the view is currently hidden, in order to prevent flashing.
            // the value for the 'IsLead' field will be set later, based on the value derived here.

            // todo: there is an issue when refreshing the edit view as options.isLead is persisted in the navigation state.
            if (this.options.isForLead != undefined) return;

            this.options.isForLead = this.isInLeadContext();

            if (this.options.isForLead)
                this.showFieldsForLead();
            else
                this.showFieldsForStandard();
        },
        onIsLeadChange: function(value, field) {
            this.options.isForLead = value;

            if (this.options.isForLead)
                this.showFieldsForLead();
            else
                this.showFieldsForStandard();
        },
        onLeadChange: function(value, field) {
            var selection = field.getSelection();

            if (selection && this.insert)
            {
                this.fields['AccountName'].setValue(utility.getValue(selection, 'Company'));
            }
        },
        onAccountChange: function(value, field) {
            var fields = this.fields;
            array.forEach(['Contact', 'Opportunity', 'Ticket'], function(f) {
                if (value)
                {
                    fields[f].dependsOn = 'Account';
                    fields[f].where = string.substitute('Account.Id eq "${0}"', [value['AccountId'] || value['key']]);

                    if (fields[f].currentSelection &&
                        fields[f].currentSelection.Account['$key'] != (value['AccountId'] || value['key'])) {

                        fields[f].setValue(false);
                    }

                }
                else
                {
                    fields[f].dependsOn = null;
                    fields[f].where = 'Account.AccountName ne null';
                }
            });
        },
        onAccountDependentChange: function(value, field) {
            if (value && !field.dependsOn && field.currentSelection && field.currentSelection.Account) {

                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': field.currentSelection.Account['$key'],
                    'AccountName': field.currentSelection.Account['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }
        },
        showFieldsForLead: function() {
            array.forEach(this.fieldsForStandard.concat(this.fieldsForLeads), function(item) {
                if (this.fields[item])
                    this.fields[item].hide();
            }, this);

            array.forEach(this.fieldsForLeads, function(item) {
                if (this.fields[item])
                    this.fields[item].show();
            }, this);
        },
        showFieldsForStandard: function() {
            array.forEach(this.fieldsForStandard.concat(this.fieldsForLeads), function(item) {
                if (this.fields[item])
                    this.fields[item].hide();
            }, this);

            array.forEach(this.fieldsForStandard, function(item) {
                    if (this.fields[item])
                        this.fields[item].show();
                }, this);
        },
        applyContext: function() {
            var found = App.queryNavigationContext(function(o) {
                var context = (o.options && o.options.source) || o;
                return /^(accounts|contacts|opportunities|leads|tickets)$/.test(context.resourceKind) && context.key;
            });

            found = found.options.source || found;

            var lookup = {
                'accounts': this.applyAccountContext,
                'contacts': this.applyContactContext,
                'opportunities': this.applyOpportunityContext,
                'leads': this.applyLeadContext,
                'tickets': this.applyTicketContext
            };

            if (found && lookup[found.resourceKind])
                lookup[found.resourceKind].call(this, found);

            var user = App.context && App.context.user;

            this.fields['Type'].setValue('atNote');
            this.fields['UserId'].setValue(user && user['$key']);
            this.fields['UserName'].setValue(user && user['$descriptor']);
            this.fields['StartDate'].setValue(new Date());
        },
        applyAccountContext: function(context) {
            var accountField = this.fields['Account'];
            accountField.setValue({
                'AccountId': context.key,
                'AccountName': context.descriptor
            });
            this.onAccountChange(accountField.getValue(), accountField);
        },
        applyLeadContext: function(context) {
            this.options.isForLead = this.isInLeadContext();

            var isLeadField = this.fields['IsLead'];
            isLeadField.setValue(this.options.isForLead);
            this.onIsLeadChange(this.options.isForLead, isLeadField);

            this.fields['Lead'].setValue({
                'LeadId': context.key,
                'LeadName': context.descriptor
            });

            var company;

            if (context.entry['Company'])
            {
                company = context.entry['Company'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                company = entry['Company'];
            }

            if (company)
                this.fields['AccountName'].setValue(company);
        },
        applyOpportunityContext: function(context) {

            var opportunityField = this.fields['Opportunity'];
            opportunityField.setValue({
                'OpportunityId': context.key,
                'OpportunityName': context.descriptor
            });
            this.onAccountDependentChange(opportunityField.getValue, opportunityField);

            var accountEntry;
            if (context.entry['Account'])
            {
                accountEntry = context.entry['Account'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                accountEntry = entry['Account'];
            }

            if (accountEntry)
            {
                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': accountEntry['$key'],
                    'AccountName': accountEntry['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }

            // todo: find a good way to get the primary contact and apply
        },
        applyContactContext: function(context) {
            var contactField = this.fields['Contact'];
            contactField.setValue({
                'ContactId': context.key,
                'ContactName': context.descriptor
            });
            this.onAccountDependentChange(contactField.getValue(), contactField);

            var accountEntry;
            if (context.entry['Account'])
            {
                accountEntry = context.entry['Account'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                accountEntry = entry['Account'];
            }

            if (accountEntry)
            {
                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': accountEntry['$key'],
                    'AccountName': accountEntry['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }
        },
        applyTicketContext: function(context) {
            var ticketField = this.fields['Ticket'];
            ticketField.setValue({
                'TicketId': context.key,
                'TicketNumber': context.descriptor
            });
            this.onAccountDependentChange(ticketField.getValue(), ticketField);

            var accountEntry, contactEntry;
            if (context.entry['Account'])
            {
                accountEntry = context.entry['Account'];
                contactEntry = context.entry['Contact'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                accountEntry = entry['Account'];
                contactEntry = entry['Contact'];
            }

            if (accountEntry)
            {
                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': accountEntry['$key'],
                    'AccountName': accountEntry['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }

            if (contactEntry)
            {
                var contactField = this.fields['Contact'];
                contactField.setValue({
                    'ContactId': contactEntry['$key'],
                    'ContactName': contactEntry['NameLF']
                });
                this.onAccountDependentChange(contactField.getValue(), contactField);
            }
        },
        setValues: function(values) {
            this.inherited(arguments);

            var isLeadField = this.fields['IsLead'];
            isLeadField.setValue(this.isInLeadContext());
            this.onIsLeadChange(isLeadField.getValue(), isLeadField);

            this.fields['Text'].setValue(values['LongNotes'] || values['Notes'] || '');
        },
        formatDependentQuery: function(dependentValue, format, property) {
            property = property || '$key';

            return string.substitute(format, [utility.getValue(dependentValue, property)]);
        },
        getValues: function() {
            var values = this.inherited(arguments);

            if (this.fields['Text'].isDirty())
            {
                var text = this.fields['Text'].getValue();

                values = values || {};
                values['LongNotes'] = text;
                values['Notes'] = text && text.length > 250
                    ? text.substr(0, 250)
                    : text;
            }

            return values;
        },
        createLayout: function() {
            return this.layout || (this.layout = [{
                title: this.detailsText,
                name: 'DetailsSection',
                children: [{
                    name: 'Type',
                    property: 'Type',
                    type: 'hidden'
                },{
                    name: 'UserId',
                    property: 'UserId',
                    type: 'hidden'
                },{
                    name: 'UserName',
                    property: 'UserName',
                    type: 'hidden'
                },{
                    label: this.startingText,
                    name: 'StartDate',
                    property: 'StartDate',
                    type: 'date',
                    showTimePicker: true,
                    dateFormatText: this.startingFormatText,
                    minValue: (new Date(1900, 0, 1)),
                    validator: [
                        validator.exists,
                        validator.isDateInRange
                    ]
                },{
                    dependsOn: 'Type',
                    label: this.regardingText,
                    name: 'Description',
                    property: 'Description',
                    picklist: 'Note Regarding',
                    orderBy: 'text asc',
                    title: this.noteDescriptionTitleText,
                    type: 'picklist'
                }]
            },{
                title: this.longNotesTitleText,
                name: 'NotesSection',
                children: [{
                    name: 'Text',
                    property: 'Text',
                    label: this.longNotesText,
                    cls: 'row-edit-text',
                    type: 'textarea'
                }]
            },{
                title: this.relatedItemsText,
                name: 'RelatedItemsSection',
                children: [{
                    label: this.isLeadText,
                    name: 'IsLead',
                    include: false,
                    type: 'boolean'
                },{
                    label: this.accountText,
                    name: 'Account',
                    property: 'Account',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'AccountId',
                    valueTextProperty: 'AccountName',
                    view: 'account_related',
                    validator: validator.exists
                },{
                    label: this.contactText,
                    name: 'Contact',
                    property: 'Contact',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'ContactId',
                    valueTextProperty: 'ContactName',
                    view: 'contact_related',
                    where: this.formatDependentQuery.bindDelegate(
                        this, 'Account.Id eq "${0}"', 'AccountId'
                    )
                },{
                    label: this.opportunityText,
                    name: 'Opportunity',
                    property: 'Opportunity',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'OpportunityId',
                    valueTextProperty: 'OpportunityName',
                    view: 'opportunity_related',
                    where: this.formatDependentQuery.bindDelegate(
                        this, 'Account.Id eq "${0}"', 'AccountId'
                    )
                },{
                    label: this.ticketNumberText,
                    name: 'Ticket',
                    property: 'Ticket',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'TicketId',
                    valueTextProperty: 'TicketNumber',
                    view: 'ticket_related',
                    where: this.formatDependentQuery.bindDelegate(
                        this, 'Account.Id eq "${0}"', 'AccountId'
                    )
                },{
                    label: this.leadText,
                    name: 'Lead',
                    property: 'Lead',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'LeadId',
                    valueTextProperty: 'LeadName',
                    view: 'lead_related',
                    validator: validator.exists
                },{
                    label: this.companyText,
                    name: 'AccountName',
                    property: 'AccountName',
                    type: 'text'
                }]
            }]);
        }
    });
});<commit_msg>fixed acquiring context of source<commit_after>define('Mobile/SalesLogix/Views/History/Edit', [
    'dojo/_base/declare',
    'dojo/_base/array',
    'dojo/string',
    'Mobile/SalesLogix/Validator',
    'Sage/Platform/Mobile/Utility',
    'Sage/Platform/Mobile/Edit'
], function(
    declare,
    array,
    string,
    validator,
    utility,
    Edit
) {

    return declare('Mobile.SalesLogix.Views.History.Edit', [Edit], {
        //Localization
        accountText: 'account',
        noteDescriptionTitleText: 'Note Description',
        contactText: 'contact',
        longNotesText: 'notes',
        longNotesTitleText: 'Notes',
        opportunityText: 'opportunity',
        ticketNumberText: 'ticket',
        regardingText: 'regarding',
        isLeadText: 'for lead',
        startingText: 'time',
		startingFormatText : 'M/d/yyyy h:mm tt',
        titleText: 'Note',
        companyText: 'company',
        leadText: 'lead',
        relatedItemsText: 'Related Items',

        //View Properties
        id: 'history_edit',
        fieldsForLeads: ['AccountName', 'Lead'],
        fieldsForStandard: ['Account', 'Contact', 'Opportunity', 'Ticket'],
        entityName: 'History',
        resourceKind: 'history',
        insertSecurity: null, //'Entities/History/Add',
        updateSecurity: null, //'Entities/History/Edit',
        querySelect: [
            'AccountId',
            'AccountName',
            'ContactId',
            'ContactName',
            'Description',
            'LongNotes',
            'Notes',
            'OpportunityId',
            'OpportunityName',
            'TicketId',
            'TicketNumber',
            'Type',
            'LeadId',
            'LeadName',
            'StartDate'
        ],

        init: function() {
            this.inherited(arguments);

            this.connect(this.fields['Lead'], 'onChange', this.onLeadChange);
            this.connect(this.fields['IsLead'], 'onChange', this.onIsLeadChange);

            this.connect(this.fields['Account'], 'onChange', this.onAccountChange);
            this.connect(this.fields['Contact'], 'onChange', this.onAccountDependentChange);
            this.connect(this.fields['Opportunity'], 'onChange', this.onAccountDependentChange);
            this.connect(this.fields['Ticket'], 'onChange', this.onAccountDependentChange);
        },
        isHistoryForLead: function(entry) {
            return entry && /^[\w]{12}$/.test(entry['LeadId']);
        },
        isInLeadContext: function() {
            var insert = this.options && this.options.insert,
                entry = this.options && this.options.entry,
                lead = (insert && App.isNavigationFromResourceKind('leads', function(o, c) { return c.resourceKind === 'leads'; })) || this.isHistoryForLead(entry);
            return !!lead;
        },
        beforeTransitionTo: function() {
            this.inherited(arguments);

            // we hide the lead or standard fields here, as the view is currently hidden, in order to prevent flashing.
            // the value for the 'IsLead' field will be set later, based on the value derived here.

            // todo: there is an issue when refreshing the edit view as options.isLead is persisted in the navigation state.
            if (this.options.isForLead != undefined) return;

            this.options.isForLead = this.isInLeadContext();

            if (this.options.isForLead)
                this.showFieldsForLead();
            else
                this.showFieldsForStandard();
        },
        onIsLeadChange: function(value, field) {
            this.options.isForLead = value;

            if (this.options.isForLead)
                this.showFieldsForLead();
            else
                this.showFieldsForStandard();
        },
        onLeadChange: function(value, field) {
            var selection = field.getSelection();

            if (selection && this.insert)
            {
                this.fields['AccountName'].setValue(utility.getValue(selection, 'Company'));
            }
        },
        onAccountChange: function(value, field) {
            var fields = this.fields;
            array.forEach(['Contact', 'Opportunity', 'Ticket'], function(f) {
                if (value)
                {
                    fields[f].dependsOn = 'Account';
                    fields[f].where = string.substitute('Account.Id eq "${0}"', [value['AccountId'] || value['key']]);

                    if (fields[f].currentSelection &&
                        fields[f].currentSelection.Account['$key'] != (value['AccountId'] || value['key'])) {

                        fields[f].setValue(false);
                    }

                }
                else
                {
                    fields[f].dependsOn = null;
                    fields[f].where = 'Account.AccountName ne null';
                }
            });
        },
        onAccountDependentChange: function(value, field) {
            if (value && !field.dependsOn && field.currentSelection && field.currentSelection.Account) {

                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': field.currentSelection.Account['$key'],
                    'AccountName': field.currentSelection.Account['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }
        },
        showFieldsForLead: function() {
            array.forEach(this.fieldsForStandard.concat(this.fieldsForLeads), function(item) {
                if (this.fields[item])
                    this.fields[item].hide();
            }, this);

            array.forEach(this.fieldsForLeads, function(item) {
                if (this.fields[item])
                    this.fields[item].show();
            }, this);
        },
        showFieldsForStandard: function() {
            array.forEach(this.fieldsForStandard.concat(this.fieldsForLeads), function(item) {
                if (this.fields[item])
                    this.fields[item].hide();
            }, this);

            array.forEach(this.fieldsForStandard, function(item) {
                    if (this.fields[item])
                        this.fields[item].show();
                }, this);
        },
        applyContext: function() {
            var found = App.queryNavigationContext(function(o) {
                var context = (o.options && o.options.source) || o;
                return /^(accounts|contacts|opportunities|leads|tickets)$/.test(context.resourceKind) && context.key;
            });

            found = (found && found.options && found.options.source) || found;

            var lookup = {
                'accounts': this.applyAccountContext,
                'contacts': this.applyContactContext,
                'opportunities': this.applyOpportunityContext,
                'leads': this.applyLeadContext,
                'tickets': this.applyTicketContext
            };

            if (found && lookup[found.resourceKind])
                lookup[found.resourceKind].call(this, found);

            var user = App.context && App.context.user;

            this.fields['Type'].setValue('atNote');
            this.fields['UserId'].setValue(user && user['$key']);
            this.fields['UserName'].setValue(user && user['$descriptor']);
            this.fields['StartDate'].setValue(new Date());
        },
        applyAccountContext: function(context) {
            var accountField = this.fields['Account'];
            accountField.setValue({
                'AccountId': context.key,
                'AccountName': context.descriptor
            });
            this.onAccountChange(accountField.getValue(), accountField);
        },
        applyLeadContext: function(context) {
            this.options.isForLead = this.isInLeadContext();

            var isLeadField = this.fields['IsLead'];
            isLeadField.setValue(this.options.isForLead);
            this.onIsLeadChange(this.options.isForLead, isLeadField);

            this.fields['Lead'].setValue({
                'LeadId': context.key,
                'LeadName': context.descriptor
            });

            var company;

            if (context.entry['Company'])
            {
                company = context.entry['Company'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                company = entry['Company'];
            }

            if (company)
                this.fields['AccountName'].setValue(company);
        },
        applyOpportunityContext: function(context) {

            var opportunityField = this.fields['Opportunity'];
            opportunityField.setValue({
                'OpportunityId': context.key,
                'OpportunityName': context.descriptor
            });
            this.onAccountDependentChange(opportunityField.getValue, opportunityField);

            var accountEntry;
            if (context.entry['Account'])
            {
                accountEntry = context.entry['Account'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                accountEntry = entry['Account'];
            }

            if (accountEntry)
            {
                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': accountEntry['$key'],
                    'AccountName': accountEntry['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }

            // todo: find a good way to get the primary contact and apply
        },
        applyContactContext: function(context) {
            var contactField = this.fields['Contact'];
            contactField.setValue({
                'ContactId': context.key,
                'ContactName': context.descriptor
            });
            this.onAccountDependentChange(contactField.getValue(), contactField);

            var accountEntry;
            if (context.entry['Account'])
            {
                accountEntry = context.entry['Account'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                accountEntry = entry['Account'];
            }

            if (accountEntry)
            {
                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': accountEntry['$key'],
                    'AccountName': accountEntry['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }
        },
        applyTicketContext: function(context) {
            var ticketField = this.fields['Ticket'];
            ticketField.setValue({
                'TicketId': context.key,
                'TicketNumber': context.descriptor
            });
            this.onAccountDependentChange(ticketField.getValue(), ticketField);

            var accountEntry, contactEntry;
            if (context.entry['Account'])
            {
                accountEntry = context.entry['Account'];
                contactEntry = context.entry['Contact'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                accountEntry = entry['Account'];
                contactEntry = entry['Contact'];
            }

            if (accountEntry)
            {
                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': accountEntry['$key'],
                    'AccountName': accountEntry['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }

            if (contactEntry)
            {
                var contactField = this.fields['Contact'];
                contactField.setValue({
                    'ContactId': contactEntry['$key'],
                    'ContactName': contactEntry['NameLF']
                });
                this.onAccountDependentChange(contactField.getValue(), contactField);
            }
        },
        setValues: function(values) {
            this.inherited(arguments);

            var isLeadField = this.fields['IsLead'];
            isLeadField.setValue(this.isInLeadContext());
            this.onIsLeadChange(isLeadField.getValue(), isLeadField);

            this.fields['Text'].setValue(values['LongNotes'] || values['Notes'] || '');
        },
        formatDependentQuery: function(dependentValue, format, property) {
            property = property || '$key';

            return string.substitute(format, [utility.getValue(dependentValue, property)]);
        },
        getValues: function() {
            var values = this.inherited(arguments);

            if (this.fields['Text'].isDirty())
            {
                var text = this.fields['Text'].getValue();

                values = values || {};
                values['LongNotes'] = text;
                values['Notes'] = text && text.length > 250
                    ? text.substr(0, 250)
                    : text;
            }

            return values;
        },
        createLayout: function() {
            return this.layout || (this.layout = [{
                title: this.detailsText,
                name: 'DetailsSection',
                children: [{
                    name: 'Type',
                    property: 'Type',
                    type: 'hidden'
                },{
                    name: 'UserId',
                    property: 'UserId',
                    type: 'hidden'
                },{
                    name: 'UserName',
                    property: 'UserName',
                    type: 'hidden'
                },{
                    label: this.startingText,
                    name: 'StartDate',
                    property: 'StartDate',
                    type: 'date',
                    showTimePicker: true,
                    dateFormatText: this.startingFormatText,
                    minValue: (new Date(1900, 0, 1)),
                    validator: [
                        validator.exists,
                        validator.isDateInRange
                    ]
                },{
                    dependsOn: 'Type',
                    label: this.regardingText,
                    name: 'Description',
                    property: 'Description',
                    picklist: 'Note Regarding',
                    orderBy: 'text asc',
                    title: this.noteDescriptionTitleText,
                    type: 'picklist'
                }]
            },{
                title: this.longNotesTitleText,
                name: 'NotesSection',
                children: [{
                    name: 'Text',
                    property: 'Text',
                    label: this.longNotesText,
                    cls: 'row-edit-text',
                    type: 'textarea'
                }]
            },{
                title: this.relatedItemsText,
                name: 'RelatedItemsSection',
                children: [{
                    label: this.isLeadText,
                    name: 'IsLead',
                    include: false,
                    type: 'boolean'
                },{
                    label: this.accountText,
                    name: 'Account',
                    property: 'Account',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'AccountId',
                    valueTextProperty: 'AccountName',
                    view: 'account_related',
                    validator: validator.exists
                },{
                    label: this.contactText,
                    name: 'Contact',
                    property: 'Contact',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'ContactId',
                    valueTextProperty: 'ContactName',
                    view: 'contact_related',
                    where: this.formatDependentQuery.bindDelegate(
                        this, 'Account.Id eq "${0}"', 'AccountId'
                    )
                },{
                    label: this.opportunityText,
                    name: 'Opportunity',
                    property: 'Opportunity',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'OpportunityId',
                    valueTextProperty: 'OpportunityName',
                    view: 'opportunity_related',
                    where: this.formatDependentQuery.bindDelegate(
                        this, 'Account.Id eq "${0}"', 'AccountId'
                    )
                },{
                    label: this.ticketNumberText,
                    name: 'Ticket',
                    property: 'Ticket',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'TicketId',
                    valueTextProperty: 'TicketNumber',
                    view: 'ticket_related',
                    where: this.formatDependentQuery.bindDelegate(
                        this, 'Account.Id eq "${0}"', 'AccountId'
                    )
                },{
                    label: this.leadText,
                    name: 'Lead',
                    property: 'Lead',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'LeadId',
                    valueTextProperty: 'LeadName',
                    view: 'lead_related',
                    validator: validator.exists
                },{
                    label: this.companyText,
                    name: 'AccountName',
                    property: 'AccountName',
                    type: 'text'
                }]
            }]);
        }
    });
});<|endoftext|>


<commit_before>/* eslint no-console: ["error", { allow: ["log"] }] */
const gulp = require('gulp');
const connect = require('gulp-connect');
const gopen = require('gulp-open');
const modifyFile = require('gulp-modify-file');

const buildJs = require('./build-js.js');
const buildLess = require('./build-less.js');

// Tasks
gulp.task('playground', (cb) => {
  const env = process.env.NODE_ENV || 'development';
  gulp.src('./playground/index.html')
    .pipe(modifyFile((content) => {
      if (env === 'development') {
        return content
          .replace('../dist/css/swiper.min.css', '../build/css/swiper.css')
          .replace('../dist/js/swiper.min.js', '../build/js/swiper.js');
      }
      return content
        .replace('../build/css/swiper.css', '../dist/css/swiper.min.css')
        .replace('../build/js/swiper.js', '../dist/js/swiper.min.js');
    }))
    .pipe(gulp.dest('./playground/'))
    .on('end', () => {
      if (cb) cb();
    });
});
gulp.task('js', (cb) => {
  buildJs(cb);
});

gulp.task('less', (cb) => {
  buildLess(cb);
});

gulp.task('build', gulp.series(['js', 'less']));

gulp.task('watch', () => {
  gulp.watch('./src/**/**/*.js', gulp.series('js'));
  gulp.watch('./src/**/**/*.less', gulp.series('less'));
});

gulp.task('connect', () => {
  connect.server({
    root: ['./'],
    livereload: true,
    port: '3000',
  });
});

gulp.task('open', () => {
  gulp.src('./playground/index.html').pipe(gopen({ uri: 'http://localhost:3000/playground/' }));
});

gulp.task('server', gulp.series(['watch', 'connect', 'open']));

gulp.task('default', gulp.series('server'));
<commit_msg>Update gulpfile.js<commit_after>/* eslint no-console: ["error", { allow: ["log"] }] */
const gulp = require('gulp');
const connect = require('gulp-connect');
const gopen = require('gulp-open');
const modifyFile = require('gulp-modify-file');

const buildJs = require('./build-js.js');
const buildLess = require('./build-less.js');

// Tasks
gulp.task('playground', (cb) => {
  const env = process.env.NODE_ENV || 'development';
  gulp.src('./playground/index.html')
    .pipe(modifyFile((content) => {
      if (env === 'development') {
        return content
          .replace('../dist/css/swiper.min.css', '../build/css/swiper.css')
          .replace('../dist/js/swiper.min.js', '../build/js/swiper.js');
      }
      return content
        .replace('../build/css/swiper.css', '../dist/css/swiper.min.css')
        .replace('../build/js/swiper.js', '../dist/js/swiper.min.js');
    }))
    .pipe(gulp.dest('./playground/'))
    .on('end', () => {
      if (cb) cb();
    });
});
gulp.task('js', (cb) => {
  buildJs(cb);
});

gulp.task('less', (cb) => {
  buildLess(cb);
});

gulp.task('build', gulp.series(['js', 'less']));

gulp.task('watch', () => {
  gulp.watch('./src/**/**/*.js', gulp.series('js'));
  gulp.watch('./src/**/**/*.less', gulp.series('less'));
});

gulp.task('connect', () => {
  connect.server({
    root: ['./'],
    livereload: true,
    port: '3000',
  });
});

gulp.task('open', () => {
  gulp.src('./playground/index.html').pipe(gopen({ uri: 'http://localhost:3000/playground/' }));
});

gulp.task('server', gulp.parallel(['watch', 'connect', 'open']));

gulp.task('default', gulp.series('server'));
<|endoftext|>


<commit_before>if (typeof(module) !== 'undefined') {
  module.exports = {
    'processBytecode': processBytecode,
    'processFile': processFile
  };
}

/**
 * The registers.
 */
var reg = {};

/**
 * Define operators.
 */
var op = {
  'or':
    function(o1, o2) {
      return '(' + o1.toString() + ' || ' + o2.toString() + ')';
    },
  'and':
    function(o1, o2) {
      return '(' + o1.toString() + ' && ' + o2.toString() + ')';
    },
  'not':
    function(o1) {
      return '(!(' + o1.toString() + '))';
    }
};

function makeExample(input, output) {
  if (output === "Error") {
    return "function() {\n  var verdict = false;\n  try{\n    " + input + ";\n  } catch (e) {\n    verdict = true;\n  }\n" + "  return verdict;\n}"
  } else {
    return "function() {\n  var verdict = " + input + " === " + output + ";\n  return verdict;\n}"
  }
}

function handleFunc(btc, lines) {
  var preLines = [],
      postLines = [];
  var i;
  for (i = 0; i < btc.docs.length; i++) {
    var node = btc.docs[i];
    switch (node.type) {
      case 'adjective':
        reg[node.target] = '_______contract.' + node.name + '(_______arg)';
        break;
      case 'and':
        reg[node.target] = op.and(reg[node.operand1], reg[node.operand2]);
        break;
      case 'or':
        reg[node.target] = op.or(reg[node.operand1], reg[node.operand2]);
        break;
      case 'not':
        reg[node.target] = op.not(reg[node.operand1]);
        break;
      case 'null':
        reg[node.target] = '(_______arg === null)';
        break;
      case 'clause':
        var nouns = [];
        var j;
        for (j = 0; j < node.subjects.length; j++) {
          var q = node.subjects[j].qualifier;
          if (q === null) {
            q = 'single'
          }
          nouns.push({'qualifier': q, 'name': node.subjects[j].name});
        }
        var subjectArray = ['function() {'];
        for (j = 0; j < nouns.length; j++) {
          if (nouns[j].name !== '@output') {
            subjectArray.push('if (!(_______contract.' + nouns[j].qualifier +
                              '(' + nouns[j].name +
                              ').each(function(_______arg) {');
            subjectArray.push('  return ' + reg[node.descriptor] + ';');
            subjectArray.push('}))) {');
            subjectArray.push('  return false;');
            subjectArray.push('}');
          } else {
            subjectArray.push('if (!(_______contract.' + nouns[j].qualifier +
                              '(_______out).each(function(_______arg) {');
            subjectArray.push('  return ' + reg[node.descriptor] + ';');
            subjectArray.push('}))) {');
            subjectArray.push('  return false;');
            subjectArray.push('}');
          }
        }
        subjectArray.push('return true; }');
        reg[node.target] = subjectArray.join("\n");
        break;
      case 'doc':
        if (reg[node.directive] !== undefined &&
            reg[node.directive].type == 'contract') {
          var msg = 'Violation in function ' + btc.name + ' for ' +
                    lines[node.line-1].replace(new RegExp(' *\\* *#', 'g'),
                                               '#');
          msg = '"' + msg.replace(new RegExp('\\"', 'g'), '\\"') + '"';
          postLines.push('_______contract.enforce(' + reg[node.directive].clause +
                         ', ' + msg + ');');
        }
        break;
      case 'int-lit':
        reg[node.target] = '(_______arg === ' + node.value + ')';
        break;
      case 'float-lit':
        reg[node.target] = '(_______arg === ' + node.value + ')';
        break;
      case 'string-lit':
        reg[node.target] = '(_______arg === "' +
                           node.value.replace('"', '\\"') + '")';
        break;
      case 'pass-lit':
        reg[node.target] = 'function() { return true; }';
        break;
      case 'fail-lit':
        reg[node.target] = 'function() { return false; }';
        break;
      case 'ite':
        reg[node.target] = 'function() {\n  if (' + reg[node.cond] + '()) {\n' +
                           '    return ' + reg[node.true] + '();\n  } else {\n' +
                           '    return ' + reg[node.false] + '();\n  }\n}'
        break;
      case 'compound':
        reg[node.target] = 'function() {\n  if (!(' + reg[node.operand1] +
                           '())) {\n    return false;\n  } else {\n    return ' +
                           reg[node.operand2] + '()\n  }\n}';
        break;
      case 'setup':
        preLines.push('if (_______first_' + btc.name + ') {\n  ' + node.code +
                      '\n}');
        break;
      case 'example':
        var msg = 'Failure in function ' + btc.name + ' for input ' +
                  node.input + ' and output ' + node.output;
        msg = '"' + msg.replace(new RegExp('\\"', 'g'), '\\"') + '"';
        var newInput = node.input.replace(
                         new RegExp(' *' + btc.name + ' *\\(', 'g'),
                         ' _______' + btc.name + '(');
        var newOutput = node.output.replace(
                         new RegExp(' *' + btc.name + ' *\\('),
                         ' _______' + btc.name + '(', 'g');
        preLines.push('if (_______first_' + btc.name + ') {\n' +
                      '  _______contract.enforce(' + makeExample(newInput, newOutput) +
                      ', ' + msg + ');\n}');
        break;
      case 'contract':
        reg[node.target] = {'type': 'contract', 'clause': reg[node.clause]};
        break;
    }
  }
  var params = [];
  for (i = 0; i < btc.params.length; i++) {
    params.push(btc.params[i].name);
  }
  var paramString = params.join(', ');
  var outArray = ['function ' + btc.name + '(' + paramString + ') {'];
  for (i = 0; i < preLines.length; i++) {
    outArray.push('  ' + preLines[i]);
  }
  outArray.push('  _______first_' + btc.name + ' = false;')
  outArray.push('  var _______out = _______' + btc.name + '(' + paramString + ');')
  for (i = 0; i < postLines.length; i++) {
    outArray.push('  ' + postLines[i]);
  }
  outArray.push('}');
  if (outArray.length > 0) {
    outArray.push('');
  }
  return outArray.join("\n");
}

function processBytecode(btc, text) {
  var results = [];
  var names = [];
  var i;
  for (i = 0; i < btc.length; i++) {
    if (btc[i].type == 'function') {
      results.push(handleFunc(btc[i], text.split("\n")));
      names.push(btc[i].name);
    }
  }
  return {'result': results.join("\n"),
          'names': names};
}

function processFile(btc, text, depth) {
  var outJS = processBytecode(btc, text);
  var outString = "var _______contract = require('" +
                  new Array(depth + 1).join('../') +
                  ".contract.js');\n" +
                  "var _______enforce = _______contract.enforce;\n" +
                  "var _______example = _______contract.example;\n\n";
  var cleanedText = text;
  var i;
  var declarations = [];
  for (i = 0; i < outJS.names.length; i++) {
    cleanedText = cleanedText.replace(new RegExp('function ' +
                                      outJS.names[i] + ' *\\('),
                                      'function _______' + outJS.names[i] +
                                      '(', 'g');
    declarations.push('var _______first_' + outJS.names[i] + ' = true;');
  }
  outString += declarations.join("\n") + "\n\n" + cleanedText +
               "\n\n" + outJS.result;
  return outString;
}
<commit_msg>resolved merge<commit_after>if (typeof(module) !== 'undefined') {
  module.exports = {
    'processBytecode': processBytecode,
    'processFile': processFile
  };
}

/**
 * The registers.
 */
var reg = {};

/**
 * Define operators.
 */
var op = {
  'or':
    function(o1, o2) {
      return '(' + o1.toString() + ' || ' + o2.toString() + ')';
    },
  'and':
    function(o1, o2) {
      return '(' + o1.toString() + ' && ' + o2.toString() + ')';
    },
  'not':
    function(o1) {
      return '(!(' + o1.toString() + '))';
    }
};

function makeExample(input, output) {
  if (output === "Error") {
    return "function() {\n      var verdict = false;\n      try{\n        " +
      input + ";\n      } catch (e) {\n        verdict = true;\n      }\n" +
      "      return verdict;\n    }";
  } else {
    return "function() {\n      var verdict = " +
      input + " === " + output +
      ";\n      return verdict;\n    }";
  }
}

function handleFunc(btc, lines) {
  var preLines = [],
      postLines = [];
  var i;
  for (i = 0; i < btc.docs.length; i++) {
    var node = btc.docs[i];
    switch (node.type) {
      case 'adjective':
        reg[node.target] = '_______contract.' + node.name + '(_______arg)';
        break;
      case 'and':
        reg[node.target] = op.and(reg[node.operand1], reg[node.operand2]);
        break;
      case 'or':
        reg[node.target] = op.or(reg[node.operand1], reg[node.operand2]);
        break;
      case 'not':
        reg[node.target] = op.not(reg[node.operand1]);
        break;
      case 'null':
        reg[node.target] = '(_______arg === null)';
        break;
      case 'clause':
        var nouns = [];
        var j;
        for (j = 0; j < node.subjects.length; j++) {
          var q = node.subjects[j].qualifier;
          if (q === null) {
            q = 'single'
          }
          nouns.push({'qualifier': q, 'name': node.subjects[j].name});
        }
        var subjectArray = ['function() {'];
        for (j = 0; j < nouns.length; j++) {
          if (nouns[j].name !== '@output') {
            subjectArray.push('    if (!(_______contract.' + nouns[j].qualifier +
                              '(' + nouns[j].name +
                              ').each(function(_______arg) {');
            subjectArray.push('      return ' + reg[node.descriptor] + ';');
            subjectArray.push('    }))) {');
            subjectArray.push('      return false;');
            subjectArray.push('    }');
          } else {
            subjectArray.push('    if (!(_______contract.' + nouns[j].qualifier +
                              '(_______out).each(function(_______arg) {');
            subjectArray.push('      return ' + reg[node.descriptor] + ';');
            subjectArray.push('    }))) {');
            subjectArray.push('      return false;');
            subjectArray.push('    }');
          }
        }
        subjectArray.push('    return true;');
        subjectArray.push('  }');
        reg[node.target] = subjectArray.join("\n");
        break;
      case 'doc':
        if (reg[node.directive] !== undefined &&
            reg[node.directive].type == 'contract') {
          var msg = 'Violation in function ' + btc.name + ' for ' +
                    lines[node.line-1].replace(new RegExp(' *\\* *#', 'g'),
                                               '#');
          msg = '"' + msg.replace(new RegExp('\\"', 'g'), '\\"') + '"';
          postLines.push('_______contract.enforce(' + reg[node.directive].clause +
                         ', ' + msg + ');');
        }
        break;
      case 'int-lit':
        reg[node.target] = '(_______arg === ' + node.value + ')';
        break;
      case 'float-lit':
        reg[node.target] = '(_______arg === ' + node.value + ')';
        break;
      case 'string-lit':
        reg[node.target] = '(_______arg === "' +
                           node.value.replace('"', '\\"') + '")';
        break;
      case 'pass-lit':
        reg[node.target] = 'function() { return true; }';
        break;
      case 'fail-lit':
        reg[node.target] = 'function() { return false; }';
        break;
      case 'ite':
        reg[node.target] = 'function() {\n  if (' + reg[node.cond] + '()) {\n' +
                           '    return ' + reg[node.true] + '();\n  } else {\n' +
                           '    return ' + reg[node.false] + '();\n  }\n}'
        break;
      case 'compound':
        reg[node.target] = 'function() {\n  if (!(' + reg[node.operand1] +
                           '())) {\n    return false;\n  } else {\n    return ' +
                           reg[node.operand2] + '()\n  }\n}';
        break;
      case 'setup':
        preLines.push('if (_______first_' + btc.name + ') {\n    ' + node.code +
                      '\n  }');
        break;
      case 'example':
        var msg = 'Failure in function ' + btc.name + ' for input ' +
                  node.input + ' and output ' + node.output;
        msg = '"' + msg.replace(new RegExp('\\"', 'g'), '\\"') + '"';
        var newInput = node.input.replace(
                         new RegExp(' *' + btc.name + ' *\\(', 'g'),
                         ' _______' + btc.name + '(');
        var newOutput = node.output.replace(
                         new RegExp(' *' + btc.name + ' *\\('),
                         ' _______' + btc.name + '(', 'g');
        preLines.push('if (_______first_' + btc.name + ') {\n' +
                      '  _______contract.enforce(' + makeExample(newInput, newOutput) +
                      ', ' + msg + ');\n}');
        break;
      case 'contract':
        reg[node.target] = {'type': 'contract', 'clause': reg[node.clause]};
        break;
    }
  }
  var params = [];
  for (i = 0; i < btc.params.length; i++) {
    params.push(btc.params[i].name);
  }
  var paramString = params.join(', ');
  var outArray = ['function ' + btc.name + '(' + paramString + ') {'];
  for (i = 0; i < preLines.length; i++) {
    outArray.push('  ' + preLines[i]);
  }
  outArray.push('  _______first_' + btc.name + ' = false;')
  outArray.push('  var _______out = _______' + btc.name + '(' + paramString + ');')
  for (i = 0; i < postLines.length; i++) {
    outArray.push('  ' + postLines[i]);
  }
  outArray.push('}');
  if (outArray.length > 0) {
    outArray.push('');
  }
  return outArray.join("\n");
}

function processBytecode(btc, text) {
  var results = [];
  var names = [];
  var i;
  for (i = 0; i < btc.length; i++) {
    if (btc[i].type == 'function') {
      results.push(handleFunc(btc[i], text.split("\n")));
      names.push(btc[i].name);
    }
  }
  return {'result': results.join("\n"),
          'names': names};
}

function processFile(btc, text, depth) {
  var outJS = processBytecode(btc, text);
  var outString = "var _______contract = require('" +
                  new Array(depth + 1).join('../') +
                  ".contract.js');\n" +
                  "var _______enforce = _______contract.enforce;\n\n";
  var cleanedText = text;
  var i;
  var declarations = [];
  for (i = 0; i < outJS.names.length; i++) {
    cleanedText = cleanedText.replace(new RegExp('function ' +
                                      outJS.names[i] + ' *\\('),
                                      'function _______' + outJS.names[i] +
                                      '(', 'g');
    declarations.push('var _______first_' + outJS.names[i] + ' = true;');
  }
  outString += declarations.join("\n") + "\n\n" + cleanedText +
               "\n\n" + outJS.result;
  return outString;
}
<|endoftext|>