<commit_before>define(['./util', './Rarity', './Level', './Card'], function define__cardcollection(util, Rarity, Level, Card) {

    var COMBO_STAT_COEFFICIENT = 77;

    function categorize_card(card) {
        var standard = card.set < 5000;
        var deck = standard && !card.commander && !card.is_combo && !card.is_defense && !card.hidden;
        var combo = 1 === card.levels.length && !!card.attack_multiplier;

        return {
            "standard": standard,
            "deck": deck,
            "combo": combo,
            "precombo": !!card.combo_card_id,
            "hidden": card.hidden,
            "card": card
        }
    }

    function flatten_card_category(cardCategory) {
        return cardCategory.card;
    }

    function upgrade_card(card, level) {
        card = util.clone(card);

        level = new Level(level, new Rarity(card.rarity));

        var upgrade = card.levels[level.getAbsoluteValue() - 1];
        if (!upgrade) {
            throw new Error('„' + card.name + '” doesn’t have this level: ' + level.getAbsoluteValue());
        }

        card.attack = upgrade.attack;
        card.health = upgrade.health;
        card.skills = upgrade.skills;

        card.level = level.getValue();
        card.fuse = level.getFuse();

        return card;
    }

    function combo_value(alpha, bravo, multiplier) {
        return Math.max(alpha, bravo, Math.ceil(1.1 * (alpha + bravo) * multiplier));
    }

    function hydrate_combo(level, combo) {
        var character = upgrade_card(this.get(combo.character), level || "1");
        var item = upgrade_card(this.get(combo.item), level || "1");
        var result = util.clone(this.get(combo.card_id));

        result.rarity = Math.ceil(character.rarity /2 + item.rarity /2);
        result.health = combo_value(item.health, character.health, result.health_multiplier);
        result.attack = combo_value(item.attack, character.attack, result.attack_multiplier);

        var power = 1.1 * (3 * character.attack + 3 * item.attack + character.health + item.health);

        result.skills = Object.keys(result.skills).reduce(function (skills, key) {
            skills[key] = {
                x: Math.round((power - result.skills[key].p) / COMBO_STAT_COEFFICIENT * result.skills[key].v),
                y: result.skills[key].y
            };

            return skills;
        }, {});

        return {
            "character": character,
            "item": item,
            "result": addLevels(result, []) // recalculate first level
        }
    }

    var COMBO_ROLE_CHARACTER = 'character';
    var COMBO_ROLE_ITEM = 'item';

    var COMBO_ROLE_PRECOMBO = 'precombo';

    function __comboId(alpha, bravo) {
        return [alpha, bravo].sort().join("~");
    }

    function parseCombo(combo) {
        var character = parseInt(combo.querySelector('cards').getAttribute('card1'));
        var item = parseInt(combo.querySelector('cards').getAttribute('card2'));

        return {
            "id": __comboId(character, item),
            "card_id": parseInt(combo.querySelector('card_id').textContent),
            "character": character,
            "item": item
        }
    }

    function addLevels(unit, upgrades) {
        unit.levels = [{
            "health": unit.health,
            "attack": unit.attack,
            "skills": unit.skills
        }];

        upgrades.reduce(function(values, upgrade) {
            values = addSkills(util.clone(values), [].slice.apply(upgrade.querySelectorAll('skill')));

            values.attack = parseInt((upgrade.querySelector('attack') || { 'textContent': values.attack }).textContent);
            values.health = parseInt((upgrade.querySelector('health') || { 'textContent': values.health }).textContent);

            unit.levels.push(values);

            return values;
        }, unit.levels[0]);

        return unit;
    }

    function addSkills(unit, skills) {
        unit.skills = unit.skills || {};

        skills.forEach(function (e) {
            unit.skills[e.getAttribute('id')] = {
                "p": parseInt(e.getAttribute('p')) || null,
                "x": parseInt(e.getAttribute('x')) || null,
                "v": parseInt(e.getAttribute('v')) || null,
                "y": e.getAttribute('y') || null
            };
        });

        return unit;
    }

    function normalizePicture(picture, type) {
        return ['FG', 'AD', 'BB', 'KH', 'FT', 'generic'][parseInt(type)-1]
            + "_" + picture.replace(/^(fg|koth|ad|bb|ft|kh|fr|generic)_/i, '');
    }

    function parseUnit(unit) {
        function v(name) {
            return (unit.querySelector(name) || {}).textContent;
        }

        return addLevels(addSkills({
            id: parseInt(v('id')),
            name: v('name'),
            slug: util.slugify(v('name')),
            desc: v('desc'),
            picture: normalizePicture(v('picture'), v('type')),
            commander: !!v('commander'),
            is_combo: !!parseFloat(v("attack_multiplier")),
            is_defense: !!v('defense_card_id'),
            rarity: parseInt(v('rarity')),
            trait: v('trait'),
            set: parseInt(v('set')),
            type: parseInt(v('type')),
            hidden: !!v('hidden'),
            combo_card_id: parseInt(v("combo_card_id")) || null,
            health: parseInt(v('health')) || 0,
            attack: parseInt(v('attack')) || 0,
            health_multiplier: parseFloat(v('health_multiplier')) || 0,
            attack_multiplier: parseFloat(v('attack_multiplier')) || 0
        }, [].slice.apply(unit.querySelectorAll('unit > skill'))), [].slice.apply(unit.querySelectorAll('upgrade')));
    }

    function CardCollection(listResponseXML) {
        this.defaultInclude = ['deck'];

        listResponseXML = listResponseXML.map(function (responseXML) {
            return (new DOMParser).parseFromString(responseXML, 'application/xml');
        });

        this.items = listResponseXML.reduce(function (collection, xml) {
            return collection.concat([].slice.apply(xml.querySelectorAll('unit')).map(parseUnit));
        }, []);

        this.combos = listResponseXML.reduce(function (collection, xml) {
            return collection.concat([].slice.apply(xml.querySelectorAll('combo')).map(parseCombo));
        }, []);

        this.types = {
            "characters": this.combos.map(function (combo) { return combo.character; }),
            "items": this.combos.map(function (combo) { return combo.item; })
        }
    }

    CardCollection.prototype.getCards = function cardcollection__getCards(include) {
        include = include || this.defaultInclude;
        return this.items.map(categorize_card)
            .filter(function (item) {
                return include.reduce(function (result, key) {
                    var exclude = "-" === key[0];
                    key = key.replace(/^[+-]/, '');

                    return exclude ? (result && ! item[key]) : (result || item[key]);
                }, false);
            }).map(flatten_card_category);
    };

    CardCollection.prototype.getComboRole = function cardcollection__getComboRole(card) {
        return -1 !== this.types.characters.indexOf(card.id) ? COMBO_ROLE_CHARACTER
            : -1 !== this.types.items.indexOf(card.id) ? COMBO_ROLE_ITEM
            : COMBO_ROLE_PRECOMBO;
    };

    CardCollection.prototype.isPrecombo = function cardcollection__isPrecombo(card) {
        return COMBO_ROLE_PRECOMBO === this.getComboRole(card);
    };

    CardCollection.prototype.find = function cardcollection__find(options) {
        if ("string" === typeof options) {
            options = { "name": options }
        }

        var name = util.slugify(options.name);
        var include = options.include || this.defaultInclude;

        return this.items.filter(function (card) {
            return name === card.slug;
        }).map(categorize_card).sort(function (alpha, bravo) {
            return include.reduce(function (result, key) {
                var dir = "-" === key[0] ? -1 : 1;
                key = key.replace(/^[+-]/, '');

                return result || (bravo[key] - alpha[key]) * dir;
            }, 0);
        }).map(flatten_card_category)[0];
    };

    CardCollection.prototype.get = function cardcollection_(id) {
        for (var i = 0, card; card = this.items[i]; i++) {
            if (id === card.id) {
                return card;
            }
        }
    };

    CardCollection.forLevel = CardCollection.prototype.forLevel = function cardcollection__forLevel(card, level) {
        card = upgrade_card(card, level);

        return new Card({
            id: card.id,
            name: card.name,
            image: card.picture,
            rarity: card.rarity,
            attack: card.attack,
            health: card.health,
            level: card.level,
            trait: card.trait,
            fuse: card.fuse,
            skills: Object.keys(card.skills).map(function (skill) {
                return {
                    type: skill,
                    value: Math.abs(card.skills[skill].x),
                    target: !!card.skills[skill].y
                };
            })
        });
    };

    CardCollection.prototype.getCombo = function cardcollection__getCombo(alpha, bravo, level) {
        var search = __comboId(alpha.id, bravo.id);

        for (var i = 0, combo; combo = this.combos[i]; i++) {
            if (combo.id === search) {
                return hydrate_combo.call(this, level, combo);
            }
        }

        return null;
    };

    CardCollection.prototype.getRecipesIncluding = function(card, level) {
        return this.combos.filter(function (combo) {
            return !!~[combo.card_id, combo.character, combo.item].indexOf(card.id);
        }).map(hydrate_combo.bind(this, level));
    };

    return CardCollection;

});<commit_msg>show combos for given character and item levels<commit_after>define(['./util', './Rarity', './Level', './Card'], function define__cardcollection(util, Rarity, Level, Card) {

    var COMBO_STAT_COEFFICIENT = 77;

    function categorize_card(card) {
        var standard = card.set < 5000;
        var deck = standard && !card.commander && !card.is_combo && !card.is_defense && !card.hidden;
        var combo = 1 === card.levels.length && !!card.attack_multiplier;

        return {
            "standard": standard,
            "deck": deck,
            "combo": combo,
            "precombo": !!card.combo_card_id,
            "hidden": card.hidden,
            "card": card
        }
    }

    function flatten_card_category(cardCategory) {
        return cardCategory.card;
    }

    function upgrade_card(card, level) {
        card = util.clone(card);

        level = new Level(level, new Rarity(card.rarity));

        var upgrade = card.levels[level.getAbsoluteValue() - 1];
        if (!upgrade) {
            throw new Error('„' + card.name + '” doesn’t have this level: ' + level.getAbsoluteValue());
        }

        card.attack = upgrade.attack;
        card.health = upgrade.health;
        card.skills = upgrade.skills;

        card.level = level.getValue();
        card.fuse = level.getFuse();

        return card;
    }

    function combo_value(alpha, bravo, multiplier) {
        return Math.max(alpha, bravo, Math.ceil(1.1 * (alpha + bravo) * multiplier));
    }

    function hydrate_combo(characterLevel, itemLevel, combo) {
        var character = upgrade_card(this.get(combo.character), characterLevel || "1");
        var item = upgrade_card(this.get(combo.item), itemLevel || "1");
        var result = util.clone(this.get(combo.card_id));

        result.rarity = Math.ceil(character.rarity /2 + item.rarity /2);
        result.health = combo_value(item.health, character.health, result.health_multiplier);
        result.attack = combo_value(item.attack, character.attack, result.attack_multiplier);

        var power = 1.1 * (3 * character.attack + 3 * item.attack + character.health + item.health);

        result.skills = Object.keys(result.skills).reduce(function (skills, key) {
            skills[key] = {
                x: Math.round((power - result.skills[key].p) / COMBO_STAT_COEFFICIENT * result.skills[key].v),
                y: result.skills[key].y
            };

            return skills;
        }, {});

        return {
            "character": character,
            "item": item,
            "result": addLevels(result, []) // recalculate first level
        }
    }

    var COMBO_ROLE_CHARACTER = 'character';
    var COMBO_ROLE_ITEM = 'item';

    var COMBO_ROLE_PRECOMBO = 'precombo';

    function parseCombo(combo) {
        var character = parseInt(combo.querySelector('cards').getAttribute('card1'));
        var item = parseInt(combo.querySelector('cards').getAttribute('card2'));

        return {
            "id": [character, item].sort().join("~"),
            "card_id": parseInt(combo.querySelector('card_id').textContent),
            "character": character,
            "item": item
        }
    }

    function addLevels(unit, upgrades) {
        unit.levels = [{
            "health": unit.health,
            "attack": unit.attack,
            "skills": unit.skills
        }];

        upgrades.reduce(function(values, upgrade) {
            values = addSkills(util.clone(values), [].slice.apply(upgrade.querySelectorAll('skill')));

            values.attack = parseInt((upgrade.querySelector('attack') || { 'textContent': values.attack }).textContent);
            values.health = parseInt((upgrade.querySelector('health') || { 'textContent': values.health }).textContent);

            unit.levels.push(values);

            return values;
        }, unit.levels[0]);

        return unit;
    }

    function addSkills(unit, skills) {
        unit.skills = unit.skills || {};

        skills.forEach(function (e) {
            unit.skills[e.getAttribute('id')] = {
                "p": parseInt(e.getAttribute('p')) || null,
                "x": parseInt(e.getAttribute('x')) || null,
                "v": parseInt(e.getAttribute('v')) || null,
                "y": e.getAttribute('y') || null
            };
        });

        return unit;
    }

    function normalizePicture(picture, type) {
        return ['FG', 'AD', 'BB', 'KH', 'FT', 'generic'][parseInt(type)-1]
            + "_" + picture.replace(/^(fg|koth|ad|bb|ft|kh|fr|generic)_/i, '');
    }

    function parseUnit(unit) {
        function v(name) {
            return (unit.querySelector(name) || {}).textContent;
        }

        return addLevels(addSkills({
            id: parseInt(v('id')),
            name: v('name'),
            slug: util.slugify(v('name')),
            desc: v('desc'),
            picture: normalizePicture(v('picture'), v('type')),
            commander: !!v('commander'),
            is_combo: !!parseFloat(v("attack_multiplier")),
            is_defense: !!v('defense_card_id'),
            rarity: parseInt(v('rarity')),
            trait: v('trait'),
            set: parseInt(v('set')),
            type: parseInt(v('type')),
            hidden: !!v('hidden'),
            combo_card_id: parseInt(v("combo_card_id")) || null,
            health: parseInt(v('health')) || 0,
            attack: parseInt(v('attack')) || 0,
            health_multiplier: parseFloat(v('health_multiplier')) || 0,
            attack_multiplier: parseFloat(v('attack_multiplier')) || 0
        }, [].slice.apply(unit.querySelectorAll('unit > skill'))), [].slice.apply(unit.querySelectorAll('upgrade')));
    }

    function CardCollection(listResponseXML) {
        this.defaultInclude = ['deck'];

        listResponseXML = listResponseXML.map(function (responseXML) {
            return (new DOMParser).parseFromString(responseXML, 'application/xml');
        });

        this.items = listResponseXML.reduce(function (collection, xml) {
            return collection.concat([].slice.apply(xml.querySelectorAll('unit')).map(parseUnit));
        }, []);

        this.combos = listResponseXML.reduce(function (collection, xml) {
            return collection.concat([].slice.apply(xml.querySelectorAll('combo')).map(parseCombo));
        }, []);

        this.types = {
            "characters": this.combos.map(function (combo) { return combo.character; }),
            "items": this.combos.map(function (combo) { return combo.item; })
        }
    }

    CardCollection.prototype.getCards = function cardcollection__getCards(include) {
        include = include || this.defaultInclude;
        return this.items.map(categorize_card)
            .filter(function (item) {
                return include.reduce(function (result, key) {
                    var exclude = "-" === key[0];
                    key = key.replace(/^[+-]/, '');

                    return exclude ? (result && ! item[key]) : (result || item[key]);
                }, false);
            }).map(flatten_card_category);
    };

    CardCollection.prototype.getComboRole = function cardcollection__getComboRole(card) {
        return -1 !== this.types.characters.indexOf(card.id) ? COMBO_ROLE_CHARACTER
            : -1 !== this.types.items.indexOf(card.id) ? COMBO_ROLE_ITEM
            : COMBO_ROLE_PRECOMBO;
    };

    CardCollection.prototype.isPrecombo = function cardcollection__isPrecombo(card) {
        return COMBO_ROLE_PRECOMBO === this.getComboRole(card);
    };

    CardCollection.prototype.find = function cardcollection__find(options) {
        if ("string" === typeof options) {
            options = { "name": options }
        }

        var name = util.slugify(options.name);
        var include = options.include || this.defaultInclude;

        return this.items.filter(function (card) {
            return name === card.slug;
        }).map(categorize_card).sort(function (alpha, bravo) {
            return include.reduce(function (result, key) {
                var dir = "-" === key[0] ? -1 : 1;
                key = key.replace(/^[+-]/, '');

                return result || (bravo[key] - alpha[key]) * dir;
            }, 0);
        }).map(flatten_card_category)[0];
    };

    CardCollection.prototype.get = function cardcollection_(id) {
        for (var i = 0, card; card = this.items[i]; i++) {
            if (id === card.id) {
                return card;
            }
        }
    };

    CardCollection.forLevel = CardCollection.prototype.forLevel = function cardcollection__forLevel(card, level) {
        card = upgrade_card(card, level);

        return new Card({
            id: card.id,
            name: card.name,
            image: card.picture,
            rarity: card.rarity,
            attack: card.attack,
            health: card.health,
            level: card.level,
            trait: card.trait,
            fuse: card.fuse,
            skills: Object.keys(card.skills).map(function (skill) {
                return {
                    type: skill,
                    value: Math.abs(card.skills[skill].x),
                    target: !!card.skills[skill].y
                };
            })
        });
    };

    CardCollection.prototype.getCombo = function cardcollection__getCombo(alpha, bravo) {
        for (var i = 0, combo; combo = this.combos[i]; i++) {
            if (combo.character === alpha.id && combo.item === bravo.id) {
                return hydrate_combo.call(this, alpha.getLevelString(), bravo.getLevelString(), combo);
            } else if (combo.character === bravo.id && combo.item === alpha.id) {
                return hydrate_combo.call(this, bravo.getLevelString(), alpha.getLevelString(), combo);
            }
        }

        return null;
    };

    CardCollection.prototype.getRecipesIncluding = function(card, level) {
        return this.combos.filter(function (combo) {
            return !!~[combo.card_id, combo.character, combo.item].indexOf(card.id);
        }).map(hydrate_combo.bind(this, level, level));
    };

    return CardCollection;

});<|endoftext|>


<commit_before>/* globals UI */

var C = UI.Views.Connector;

class EditForm extends C.View {
  constructor(props) {
    super(props);
    this.state = {
      events: []
    };
    if (!props.connector) {
      this.state.mode = 'connect';
    }
  }
  connect() {
    this.props.onConnect();
  }
  render() {
    return (
      <C.Page default="setup" {...this.props}>
        <C.Panel name="Setup" slug="setup">
          <UI.FormElements.Button text={this.props.connectorInstance ? 'Reauthorize' : 'Connect'} type="large" onClick={()=>{
              return this.connect();
            }} />
        </C.Panel>
        {this.props.connectorInstance ? <C.Panel name="Events" slug="events">
        <C.PageHeader
          title="Check the boxes of the events you want to subscribe to."
          subTitle="Checking a box will automatically subscribe you to that event." />
          <C.CheckboxGrid
            items={this.getAvailableEvents()}
            checked={this.getSubscribedEvents()}
            onChange={this.props.onSubscribe} />
        </C.Panel> : <C.Panel name="Events" slug="events">
          <C.EventsGrid.Header
            title="Events are available once you've connected." />
        </C.Panel>}
      </C.Page>
    );
  }
}

export default EditForm;
global.EditForm = EditForm;
<commit_msg>events<commit_after>/* globals UI */

var C = UI.Views.Connector;

class EditForm extends C.View {
  constructor(props) {
    super(props);
    this.state = {
      events: []
    };
    if (!props.connector) {
      this.state.mode = 'connect';
    }
  }
  connect() {
    this.props.onConnect();
  }
  render() {
    return (
      <C.Page default="setup" {...this.props}>
        <C.Panel name="Setup" slug="setup">
          <UI.FormElements.Button text={this.props.connectorInstance ? 'Reauthorize' : 'Connect'} type="large" onClick={()=>{
              return this.connect();
            }} />
        </C.Panel>
        {this.props.connectorInstance ? <C.Panel name="Events" slug="events">
        <C.PageHeader
          title="Check the boxes of the events you want to subscribe to."
          subTitle="Checking a box will automatically subscribe you to that event." />
          <C.CheckboxGrid
            items={this.props.connectorInstance.events}
            checked={this.props.connectorInstance.subscribedEvents}
            onChange={this.props.onSubscribe} />
        </C.Panel> : <C.Panel name="Events" slug="events">
          <C.EventsGrid.Header
            title="Events are available once you've connected." />
        </C.Panel>}
      </C.Page>
    );
  }
}

export default EditForm;
global.EditForm = EditForm;
<|endoftext|>


<commit_before>import * as ACTIONS from 'constants/action_types';
import Lbryio from 'lbryio';
import { Lbry, doNotify, MODALS, doHideNotification } from 'lbry-redux';
import { doClaimRewardType, doRewardList } from 'redux/actions/rewards';
import {
  selectEmailToVerify,
  selectPhoneToVerify,
  selectUserCountryCode,
} from 'redux/selectors/user';
import rewards from 'rewards';
import analytics from 'analytics';
import pjson from 'package.json';

export function doFetchInviteStatus() {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_INVITE_STATUS_FETCH_STARTED,
    });

    Lbryio.call('user', 'invite_status')
      .then(status => {
        dispatch({
          type: ACTIONS.USER_INVITE_STATUS_FETCH_SUCCESS,
          data: {
            invitesRemaining: status.invites_remaining ? status.invites_remaining : 0,
            invitees: status.invitees,
          },
        });
      })
      .catch(error => {
        dispatch({
          type: ACTIONS.USER_INVITE_STATUS_FETCH_FAILURE,
          data: { error },
        });
      });
  };
}

export function doInstallNew() {
  const payload = { app_version: pjson.version };
  Lbry.status().then(status => {
    payload.app_id = status.installation_id;
    Lbry.version().then(version => {
      payload.daemon_version = version.lbrynet_version;
      payload.operating_system = version.os_system;
      payload.platform = version.platform;
      Lbryio.call('install', 'new', payload);
    });
  });
}

export function doAuthenticate() {
  return dispatch => {
    dispatch({
      type: ACTIONS.AUTHENTICATION_STARTED,
    });
    Lbryio.authenticate()
      .then(user => {
        analytics.setUser(user);
        dispatch({
          type: ACTIONS.AUTHENTICATION_SUCCESS,
          data: { user },
        });
        dispatch(doRewardList());
        dispatch(doFetchInviteStatus());
        doInstallNew();
      })
      .catch(error => {
        dispatch(doNotify({ id: MODALS.AUTHENTICATION_FAILURE }));
        dispatch({
          type: ACTIONS.AUTHENTICATION_FAILURE,
          data: { error },
        });
      });
  };
}

export function doUserFetch() {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_FETCH_STARTED,
    });
    Lbryio.getCurrentUser()
      .then(user => {
        analytics.setUser(user);
        dispatch(doRewardList());

        dispatch({
          type: ACTIONS.USER_FETCH_SUCCESS,
          data: { user },
        });
      })
      .catch(error => {
        dispatch({
          type: ACTIONS.USER_FETCH_FAILURE,
          data: { error },
        });
      });
  };
}

export function doUserPhoneReset() {
  return {
    type: ACTIONS.USER_PHONE_RESET,
  };
}

export function doUserPhoneNew(phone, countryCode) {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_PHONE_NEW_STARTED,
      data: { phone, country_code: countryCode },
    });

    const success = () => {
      dispatch({
        type: ACTIONS.USER_PHONE_NEW_SUCCESS,
        data: { phone },
      });
    };

    const failure = error => {
      dispatch({
        type: ACTIONS.USER_PHONE_NEW_FAILURE,
        data: { error },
      });
    };

    Lbryio.call(
      'user',
      'phone_number_new',
      { phone_number: phone, country_code: countryCode },
      'post'
    ).then(success, failure);
  };
}

export function doUserPhoneVerifyFailure(error) {
  return {
    type: ACTIONS.USER_PHONE_VERIFY_FAILURE,
    data: { error },
  };
}

export function doUserPhoneVerify(verificationCode) {
  return (dispatch, getState) => {
    const phoneNumber = selectPhoneToVerify(getState());
    const countryCode = selectUserCountryCode(getState());

    dispatch({
      type: ACTIONS.USER_PHONE_VERIFY_STARTED,
      code: verificationCode,
    });

    Lbryio.call(
      'user',
      'phone_number_confirm',
      {
        verification_code: verificationCode,
        phone_number: phoneNumber,
        country_code: countryCode,
      },
      'post'
    )
      .then(user => {
        if (user.is_identity_verified) {
          dispatch({
            type: ACTIONS.USER_PHONE_VERIFY_SUCCESS,
            data: { user },
          });
          dispatch(doHideNotification());
          dispatch(doClaimRewardType(rewards.TYPE_NEW_USER));
        }
      })
      .catch(error => dispatch(doUserPhoneVerifyFailure(error)));
  };
}

export function doUserEmailNew(email) {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_EMAIL_NEW_STARTED,
      email,
    });

    const success = () => {
      dispatch({
        type: ACTIONS.USER_EMAIL_NEW_SUCCESS,
        data: { email },
      });
      dispatch(doUserFetch());
    };

    const failure = error => {
      dispatch({
        type: ACTIONS.USER_EMAIL_NEW_FAILURE,
        data: { error },
      });
    };

    Lbryio.call('user_email', 'new', { email, send_verification_email: true }, 'post')
      .catch(error => {
        if (error.response && error.response.status === 409) {
          return Lbryio.call(
            'user_email',
            'resend_token',
            { email, only_if_expired: true },
            'post'
          ).then(success, failure);
        }
        throw error;
      })
      .then(success, failure);
  };
}

export function doUserResendVerificationEmail(email) {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_EMAIL_VERIFY_RETRY,
      email,
    });

    const success = () => {
      dispatch({
        type: ACTIONS.USER_EMAIL_NEW_SUCCESS,
        data: { email },
      });
      dispatch(doUserFetch());
    };

    const failure = error => {
      dispatch({
        type: ACTIONS.USER_EMAIL_NEW_FAILURE,
        data: { error },
      });
    };

    Lbryio.call('user_email', 'resend_token', { email }, 'post')
      .catch(error => {
        if (error.response && error.response.status === 409) {
          throw error;
        }
      })
      .then(success, failure);
  };
}

export function doUserEmailVerifyFailure(error) {
  return {
    type: ACTIONS.USER_EMAIL_VERIFY_FAILURE,
    data: { error },
  };
}

export function doUserEmailVerify(verificationToken, recaptcha) {
  return (dispatch, getState) => {
    const email = selectEmailToVerify(getState());

    dispatch({
      type: ACTIONS.USER_EMAIL_VERIFY_STARTED,
      code: verificationToken,
      recaptcha,
    });

    Lbryio.call(
      'user_email',
      'confirm',
      {
        verification_token: verificationToken,
        email,
        recaptcha,
      },
      'post'
    )
      .then(userEmail => {
        if (userEmail.is_verified) {
          dispatch({
            type: ACTIONS.USER_EMAIL_VERIFY_SUCCESS,
            data: { email },
          });
          dispatch(doUserFetch());
        } else {
          throw new Error('Your email is still not verified.'); // shouldn't happen
        }
      })
      .catch(error => dispatch(doUserEmailVerifyFailure(error)));
  };
}

export function doUserIdentityVerify(stripeToken) {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_IDENTITY_VERIFY_STARTED,
      token: stripeToken,
    });

    Lbryio.call('user', 'verify_identity', { stripe_token: stripeToken }, 'post')
      .then(user => {
        if (user.is_identity_verified) {
          dispatch({
            type: ACTIONS.USER_IDENTITY_VERIFY_SUCCESS,
            data: { user },
          });
          dispatch(doClaimRewardType(rewards.TYPE_NEW_USER));
        } else {
          throw new Error('Your identity is still not verified. This should not happen.'); // shouldn't happen
        }
      })
      .catch(error => {
        dispatch({
          type: ACTIONS.USER_IDENTITY_VERIFY_FAILURE,
          data: { error: error.toString() },
        });
      });
  };
}

export function doFetchAccessToken() {
  return dispatch => {
    const success = token =>
      dispatch({
        type: ACTIONS.FETCH_ACCESS_TOKEN_SUCCESS,
        data: { token },
      });
    Lbryio.getAuthToken().then(success);
  };
}

export function doUserInviteNew(email) {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_INVITE_NEW_STARTED,
    });

    Lbryio.call('user', 'invite', { email }, 'post')
      .then(() => {
        dispatch({
          type: ACTIONS.USER_INVITE_NEW_SUCCESS,
          data: { email },
        });

        dispatch(
          doNotify({
            displayType: ['snackbar'],
            message: __('Invite sent to %s', email),
          })
        );

        dispatch(doFetchInviteStatus());
      })
      .catch(error => {
        dispatch({
          type: ACTIONS.USER_INVITE_NEW_FAILURE,
          data: { error },
        });
      });
  };
}
<commit_msg>nevermind, adding node_id back<commit_after>import * as ACTIONS from 'constants/action_types';
import Lbryio from 'lbryio';
import { Lbry, doNotify, MODALS, doHideNotification } from 'lbry-redux';
import { doClaimRewardType, doRewardList } from 'redux/actions/rewards';
import {
  selectEmailToVerify,
  selectPhoneToVerify,
  selectUserCountryCode,
} from 'redux/selectors/user';
import rewards from 'rewards';
import analytics from 'analytics';
import pjson from 'package.json';

export function doFetchInviteStatus() {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_INVITE_STATUS_FETCH_STARTED,
    });

    Lbryio.call('user', 'invite_status')
      .then(status => {
        dispatch({
          type: ACTIONS.USER_INVITE_STATUS_FETCH_SUCCESS,
          data: {
            invitesRemaining: status.invites_remaining ? status.invites_remaining : 0,
            invitees: status.invitees,
          },
        });
      })
      .catch(error => {
        dispatch({
          type: ACTIONS.USER_INVITE_STATUS_FETCH_FAILURE,
          data: { error },
        });
      });
  };
}

export function doInstallNew() {
  const payload = { app_version: pjson.version };
  Lbry.status().then(status => {
    payload.app_id = status.installation_id;
    payload.node_id = status.dht.node_id;
    Lbry.version().then(version => {
      payload.daemon_version = version.lbrynet_version;
      payload.operating_system = version.os_system;
      payload.platform = version.platform;
      Lbryio.call('install', 'new', payload);
    });
  });
}

export function doAuthenticate() {
  return dispatch => {
    dispatch({
      type: ACTIONS.AUTHENTICATION_STARTED,
    });
    Lbryio.authenticate()
      .then(user => {
        analytics.setUser(user);
        dispatch({
          type: ACTIONS.AUTHENTICATION_SUCCESS,
          data: { user },
        });
        dispatch(doRewardList());
        dispatch(doFetchInviteStatus());
        doInstallNew();
      })
      .catch(error => {
        dispatch(doNotify({ id: MODALS.AUTHENTICATION_FAILURE }));
        dispatch({
          type: ACTIONS.AUTHENTICATION_FAILURE,
          data: { error },
        });
      });
  };
}

export function doUserFetch() {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_FETCH_STARTED,
    });
    Lbryio.getCurrentUser()
      .then(user => {
        analytics.setUser(user);
        dispatch(doRewardList());

        dispatch({
          type: ACTIONS.USER_FETCH_SUCCESS,
          data: { user },
        });
      })
      .catch(error => {
        dispatch({
          type: ACTIONS.USER_FETCH_FAILURE,
          data: { error },
        });
      });
  };
}

export function doUserPhoneReset() {
  return {
    type: ACTIONS.USER_PHONE_RESET,
  };
}

export function doUserPhoneNew(phone, countryCode) {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_PHONE_NEW_STARTED,
      data: { phone, country_code: countryCode },
    });

    const success = () => {
      dispatch({
        type: ACTIONS.USER_PHONE_NEW_SUCCESS,
        data: { phone },
      });
    };

    const failure = error => {
      dispatch({
        type: ACTIONS.USER_PHONE_NEW_FAILURE,
        data: { error },
      });
    };

    Lbryio.call(
      'user',
      'phone_number_new',
      { phone_number: phone, country_code: countryCode },
      'post'
    ).then(success, failure);
  };
}

export function doUserPhoneVerifyFailure(error) {
  return {
    type: ACTIONS.USER_PHONE_VERIFY_FAILURE,
    data: { error },
  };
}

export function doUserPhoneVerify(verificationCode) {
  return (dispatch, getState) => {
    const phoneNumber = selectPhoneToVerify(getState());
    const countryCode = selectUserCountryCode(getState());

    dispatch({
      type: ACTIONS.USER_PHONE_VERIFY_STARTED,
      code: verificationCode,
    });

    Lbryio.call(
      'user',
      'phone_number_confirm',
      {
        verification_code: verificationCode,
        phone_number: phoneNumber,
        country_code: countryCode,
      },
      'post'
    )
      .then(user => {
        if (user.is_identity_verified) {
          dispatch({
            type: ACTIONS.USER_PHONE_VERIFY_SUCCESS,
            data: { user },
          });
          dispatch(doHideNotification());
          dispatch(doClaimRewardType(rewards.TYPE_NEW_USER));
        }
      })
      .catch(error => dispatch(doUserPhoneVerifyFailure(error)));
  };
}

export function doUserEmailNew(email) {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_EMAIL_NEW_STARTED,
      email,
    });

    const success = () => {
      dispatch({
        type: ACTIONS.USER_EMAIL_NEW_SUCCESS,
        data: { email },
      });
      dispatch(doUserFetch());
    };

    const failure = error => {
      dispatch({
        type: ACTIONS.USER_EMAIL_NEW_FAILURE,
        data: { error },
      });
    };

    Lbryio.call('user_email', 'new', { email, send_verification_email: true }, 'post')
      .catch(error => {
        if (error.response && error.response.status === 409) {
          return Lbryio.call(
            'user_email',
            'resend_token',
            { email, only_if_expired: true },
            'post'
          ).then(success, failure);
        }
        throw error;
      })
      .then(success, failure);
  };
}

export function doUserResendVerificationEmail(email) {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_EMAIL_VERIFY_RETRY,
      email,
    });

    const success = () => {
      dispatch({
        type: ACTIONS.USER_EMAIL_NEW_SUCCESS,
        data: { email },
      });
      dispatch(doUserFetch());
    };

    const failure = error => {
      dispatch({
        type: ACTIONS.USER_EMAIL_NEW_FAILURE,
        data: { error },
      });
    };

    Lbryio.call('user_email', 'resend_token', { email }, 'post')
      .catch(error => {
        if (error.response && error.response.status === 409) {
          throw error;
        }
      })
      .then(success, failure);
  };
}

export function doUserEmailVerifyFailure(error) {
  return {
    type: ACTIONS.USER_EMAIL_VERIFY_FAILURE,
    data: { error },
  };
}

export function doUserEmailVerify(verificationToken, recaptcha) {
  return (dispatch, getState) => {
    const email = selectEmailToVerify(getState());

    dispatch({
      type: ACTIONS.USER_EMAIL_VERIFY_STARTED,
      code: verificationToken,
      recaptcha,
    });

    Lbryio.call(
      'user_email',
      'confirm',
      {
        verification_token: verificationToken,
        email,
        recaptcha,
      },
      'post'
    )
      .then(userEmail => {
        if (userEmail.is_verified) {
          dispatch({
            type: ACTIONS.USER_EMAIL_VERIFY_SUCCESS,
            data: { email },
          });
          dispatch(doUserFetch());
        } else {
          throw new Error('Your email is still not verified.'); // shouldn't happen
        }
      })
      .catch(error => dispatch(doUserEmailVerifyFailure(error)));
  };
}

export function doUserIdentityVerify(stripeToken) {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_IDENTITY_VERIFY_STARTED,
      token: stripeToken,
    });

    Lbryio.call('user', 'verify_identity', { stripe_token: stripeToken }, 'post')
      .then(user => {
        if (user.is_identity_verified) {
          dispatch({
            type: ACTIONS.USER_IDENTITY_VERIFY_SUCCESS,
            data: { user },
          });
          dispatch(doClaimRewardType(rewards.TYPE_NEW_USER));
        } else {
          throw new Error('Your identity is still not verified. This should not happen.'); // shouldn't happen
        }
      })
      .catch(error => {
        dispatch({
          type: ACTIONS.USER_IDENTITY_VERIFY_FAILURE,
          data: { error: error.toString() },
        });
      });
  };
}

export function doFetchAccessToken() {
  return dispatch => {
    const success = token =>
      dispatch({
        type: ACTIONS.FETCH_ACCESS_TOKEN_SUCCESS,
        data: { token },
      });
    Lbryio.getAuthToken().then(success);
  };
}

export function doUserInviteNew(email) {
  return dispatch => {
    dispatch({
      type: ACTIONS.USER_INVITE_NEW_STARTED,
    });

    Lbryio.call('user', 'invite', { email }, 'post')
      .then(() => {
        dispatch({
          type: ACTIONS.USER_INVITE_NEW_SUCCESS,
          data: { email },
        });

        dispatch(
          doNotify({
            displayType: ['snackbar'],
            message: __('Invite sent to %s', email),
          })
        );

        dispatch(doFetchInviteStatus());
      })
      .catch(error => {
        dispatch({
          type: ACTIONS.USER_INVITE_NEW_FAILURE,
          data: { error },
        });
      });
  };
}
<|endoftext|>


<commit_before>const express = require('express');
const morganLogger = require('morgan');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const RateLimit = require('express-rate-limit');

const log = require('./config/logger');
const { blogPostRoute, healthCheckRoute } = require('./routes');

const { NODE_ENV, PORT = 3000 } = process.env;

mongoose.Promise = Promise;
mongoose
  .connect('mongodb://localhost:27017/blogapp')
  .catch(err => log('error', err));

const app = express();

if (NODE_ENV === 'dev') app.use(morganLogger('dev'));

app.use(new RateLimit({
  windowMs: 900000,
  max: 100,
  delayMs: 0,
}));

app.use(bodyParser.json());

app.use('/api', blogPostRoute);
app.use('/private', healthCheckRoute);

app.listen(PORT, () => {
  log('info', `App listening on port: ${PORT}`);
});

module.exports = app;
<commit_msg>Add config for mongodb<commit_after>const express = require('express');
const morganLogger = require('morgan');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const RateLimit = require('express-rate-limit');

const log = require('./config/logger');
const { blogPostRoute, healthCheckRoute } = require('./routes');

const { NODE_ENV, PORT = 3000, MONGODB_URI } = process.env;

mongoose.Promise = Promise;
mongoose
  .connect(MONGODB_URI || 'mongodb://localhost:27017/blogapp')
  .catch(err => log('error', err));

const app = express();

if (NODE_ENV === 'dev') app.use(morganLogger('dev'));

app.use(new RateLimit({
  windowMs: 900000,
  max: 100,
  delayMs: 0,
}));

app.use(bodyParser.json());

app.use('/api', blogPostRoute);
app.use('/private', healthCheckRoute);

app.listen(PORT, () => {
  log('info', `App listening on port: ${PORT}`);
});

module.exports = app;
<|endoftext|>


<commit_before>// Layout fixes
NGApp.factory( 'PhoneGapService', function( $route, $rootScope ){

	if( !App.isPhoneGap ){
		return {};
	}

	service = {
		isPhoneGap : App.isPhoneGap,
		isAndroid : App.isAndroid()
	};

	$rootScope.$on('$routeChangeSuccess', function ( $currentRoute, $previousRoute ) {
		service.routeChanged( $route.current.action );
	} );

	service.routeChanged = function( route ){

		if( App.isPhoneGap && !App.splashHidden && ( !route || route == 'home' ) ){
			//navigator.splashscreen.show();
		} else {
			setTimeout( function(){
				navigator.splashscreen.hide();
				App.splashHidden = true;
			}, 1000 );
		}

		switch( route ){
			case 'location':
				if( service.isAndroid ){
					// Fix the location background
					setTimeout( function(){
						$( '.home-top' ).css( 'background-position','top right' );
					}, 100 );

				}
				break;
		}
	}

	return service;
} );
<commit_msg>fixes #2671<commit_after>// Layout fixes
NGApp.factory( 'PhoneGapService', function( $route, $rootScope ){

	if( !App.isPhoneGap ){
		return {};
	}

	service = {
		isPhoneGap : App.isPhoneGap,
		isAndroid : App.isAndroid()
	};

	$rootScope.$on('$routeChangeSuccess', function ( $currentRoute, $previousRoute ) {
		service.routeChanged( $route.current.action );
	} );

	service.routeChanged = function( route ){
		// hiden the keyboard accessory on the location page.
		if (App.isPhoneGap && App.iOS() && navigator && navigator.keyboard) {
			if (route == 'location') {
				navigator.keyboard.hide();
			} else {
				navigator.keyboard.show();
			}
		}

		if( App.isPhoneGap && !App.splashHidden && ( !route || route == 'home' ) ){
			//navigator.splashscreen.show();
		} else {
			setTimeout( function(){
				navigator.splashscreen.hide();
				App.splashHidden = true;
			}, 1000 );
		}

		switch( route ){
			case 'location':
				if( service.isAndroid ){
					// Fix the location background
					setTimeout( function(){
						$( '.home-top' ).css( 'background-position','top right' );
					}, 100 );

				}
				break;
		}
	}

	return service;
} );
<|endoftext|>


<commit_before>$(document).ready(function(){

    //jquery selector for dom element we're going to render to
    var screen = "#screen";
    if (!Detector.webgl){
        $(screen).append(Detector.getWebGLErrorMessage());
    }

    //size of display
    var w = $(screen).width();
    var h = $(screen).height();
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(w,h);
    $(screen).append( renderer.domElement );
    //start with center of mass focus selected
    $("#com").button('toggle');

    var scene = new THREE.Scene();
    //do I want perspective?
    var camera = new THREE.PerspectiveCamera( 60, w/h, 0.1, 30 );
    camera.position.z = 2;
    camera.lookAt(new THREE.Vector3(0,0,0));

    //Allows you to look around whilst focusing on a point
    var controls = new THREE.OrbitControls( camera , $(screen)[0]);
    controls.addEventListener('change', render);

    //light at the center of mass
    var light = new THREE.PointLight( 0xffffff, 1, 10 );
    light.position.set( 0, 0, 0 );
    scene.add( light );
    var light2 = new THREE.PointLight( 0xffffff, 0.6, 10 );
    light2.position.set( 0, 0, 1 );
    scene.add( light2 );

    //solutions/starting positions available to simulate
    //[0:14]
    var solution = 3;

    //array of spheres, carries other information like
    //time-step size, trail length
    var bodies = [];
    reset(bodies, scene, solution);

    //simulation parameters
    var step = 0;

    //bind function to dropdown menu for solution selection
    $("#simulationSelection").click(function(x){
        solution = x.target.id;
        reset(bodies, scene, solution);
        camera.position.set(0,0,3);
    });
    var currentFocus = -1;
    //focus point function
    $("#focusRadio").click(function(x){
        var newFocus = x.target.value;
        if (currentFocus != newFocus){
            currentFocus = newFocus;
            reset(bodies, scene, solution);
            camera.position.set(0,0,3);
        }
    });

    function move(){
        for (var i = 0; i < bodies.speed; i++){
            rk4(bodies);
        }
        step++;
        //recenter on the focussed body
        if (currentFocus != -1){
            var adjustment = bodies[currentFocus].position.clone();
            for (var i = 0; i < bodies.length; i++){
                bodies[i].position.sub(adjustment);
            }
        }

        for (var i = 0; i < bodies.length; i++){
            //Lines seem to be fixed length,
            //but we can push and shift to get a trail.
            bodies[i].trail.geometry.vertices.shift();
            bodies[i].trail.geometry.vertices.push(bodies[i].position.clone());
            bodies[i].trail.geometry.verticesNeedUpdate = true;
        }

        if (step % 1000 == 0){
            for (var i = 0; i < bodies.length; i++){
                var v = bodies[i].velocity;
                var p = bodies[i].position;
                if (v.length() > 10 || p.length() > 10){
                    console.log(step);
                    return false
                }
            }
            console.log(step);
        }
        return true;
    }

    function animate(){
        if (!move()){
            reset(bodies, scene, solution);
        }
        requestAnimationFrame( animate );
        controls.update();
        renderer.render( scene, camera );
    }

    function render(){
        renderer.render( scene, camera );
    }

    animate();
});

//https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods#Common_fourth-order_Runge.E2.80.93Kutta_method
//http://home.deds.nl/~infokees/useful/OrbitRungeKutta4.pdf
//Could we improve accuracy by considering all particles at once?
function rk4(bodies){
    var h = bodies.dt;
    var movements= [];
    for (var i = 0; i < bodies.length; i++){
        var r = bodies[i].position;
        var v = bodies[i].velocity;

        //running totals remove need to clone vectors
        //Equations 11 & 12
        var dr = new THREE.Vector3(0,0,0);
        var dv = new THREE.Vector3(0,0,0);

        //Equation 10 is missing a "+"
        var k1v = a(i, r, bodies);
        dv.add(k1v);

        var k1r = v.clone();
        dr.add(k1r);

        var k2v = a(i, k1r.multiplyScalar(h/2).add(r), bodies);
        dv.add(k2v).add(k2v);

        var k2r = k1v.multiplyScalar(h/2).add(v);
        dr.add(k2r).add(k2r);

        var k3v = a(i, k2r.multiplyScalar(h/2).add(r), bodies);
        dv.add(k3v).add(k3v);

        var k3r = k2v.multiplyScalar(h/2).add(v);
        dr.add(k3r).add(k3r);

        var k4v = a(i, k3r.multiplyScalar(h).add(r), bodies);
        dv.add(k4v);

        var k4r = k3v.multiplyScalar(h).add(v);
        dr.add(k4r);

        bodies[i].velocity.add(dv.multiplyScalar(h/6));
        bodies[i].position.add(dr.multiplyScalar(h/6));
    }
}

//calculates the acceleration of body i if it were at position p
function a(i, p, bodies){
    //F = G*m1*m2/r^2
    //G,m = 1
    //F points in the direction of the attractor
    var sum = new THREE.Vector3(0,0,0);
    for (var j = 0; j < bodies.length; j++){
        if (j == i){
            continue;
        }
        var d2 = p.distanceToSquared(bodies[j].position);
        var r = new THREE.Vector3(0,0,0);
        r.subVectors(bodies[j].position, p) //vector to attractor
        .normalize() //unit vector
        .divideScalar(d2);
        sum.add(r);
    }
    return sum;
}

//resets the bodies to the starting positions and velocities given in
//the paper http://arxiv.org/pdf/1303.0181v1.pdf
//solution in [0:14]
function reset(bodies, scene, solution){
    bodies.dt = 0.001;
    bodies.speed = 5;
    //numerical stability is governed by how close the bodies come to each other during an orbit
    //these are derived empically
    var instability = [10,20,10,1,2,10,20,20,50,20,100,10,10,2000,2000];
    bodies.dt /= instability[solution];
    bodies.speed *= instability[solution];

    //period of orbit from paper
    var ts =     [6.2356,  7.0039, 63.5345, 14.8939, 28.6703, 13.8658, 25.8406, 10.4668, 79.4759,  21.2710, 55.5018, 17.3284, 10.9626, 55.7898, 54.2076 ];
    var period = ts[solution];
    //make the trails as long as the orbit
    bodies.segments = period / bodies.dt/bodies.speed ;

    for (var i = 0; i < bodies.length; i++){
        scene.remove(bodies[i].trail);
        scene.remove(bodies[i]);
    }

    //n = 3...
    for (var i = 0; i < 3; i++){
        //size and detail of spheres
        var geometry = new THREE.SphereGeometry(0.1,16,16);
        var material = new THREE.MeshPhongMaterial( { color: 0xff << (i*8)} );
        var body = new THREE.Mesh( geometry, material );
        body.velocity = new THREE.Vector3(0,0,0);

        //trailing lines
        var lineMaterial = new THREE.LineBasicMaterial({ color: body.material.color });
        var lineGeometry = new THREE.Geometry();
        for (var j = 0; j < bodies.segments; j++){
            //lines start at the initial positions of the spheres
            lineGeometry.vertices.push(new THREE.Vector3([-1,1,0][i],0,0));
        }
        body.trail = new THREE.Line(lineGeometry, lineMaterial);
        bodies[i] = body;
    }

    for (var i = 0; i < bodies.length; i++){
        scene.add(bodies[i]);
        scene.add(bodies[i].trail);
    }

    //The paper refers to the particles as 1,2,3
    //I use 0,1,2
    var x1dots = [0.30689, 0.39295, 0.18428, 0.46444, 0.43917, 0.40592, 0.38344, 0.08330, 0.350112, 0.08058, 0.55906, 0.51394, 0.28270, 0.41682, 0.41734];
    var y1dots = [0.12551, 0.09758, 0.58719, 0.39606, 0.45297, 0.23016, 0.37736, 0.12789, 0.079340, 0.58884, 0.34919, 0.30474, 0.32721, 0.33033, 0.31310];

    var x1dot = x1dots[solution];
    var y1dot = y1dots[solution];

    bodies[0].velocity.x = x1dot;
    bodies[1].velocity.x = x1dot;
    bodies[2].velocity.x = -2*x1dot;

    bodies[0].velocity.y = y1dot;
    bodies[1].velocity.y = y1dot;
    bodies[2].velocity.y = -2*y1dot;

    bodies[0].position.x = -1;
    bodies[1].position.x = 1;
    bodies[2].position.x = 0;

    bodies[0].position.y = 0;
    bodies[1].position.y = 0;
    bodies[2].position.y = 0;
}

<commit_msg>extract move()<commit_after>$(document).ready(function(){

    //jquery selector for dom element we're going to render to
    var screen = "#screen";
    if (!Detector.webgl){
        $(screen).append(Detector.getWebGLErrorMessage());
    }

    //size of display
    var w = $(screen).width();
    var h = $(screen).height();
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(w,h);
    $(screen).append( renderer.domElement );
    //start with center of mass focus selected
    $("#com").button('toggle');

    var scene = new THREE.Scene();
    //do I want perspective?
    var camera = new THREE.PerspectiveCamera( 60, w/h, 0.1, 30 );
    camera.position.z = 3;
    camera.lookAt(new THREE.Vector3(0,0,0));

    //Allows you to look around whilst focusing on a point
    var controls = new THREE.OrbitControls( camera , $(screen)[0]);
    controls.addEventListener('change', render);

    //light at the center of mass
    var light = new THREE.PointLight( 0xffffff, 1, 10 );
    light.position.set( 0, 0, 0 );
    scene.add( light );
    var light2 = new THREE.PointLight( 0xffffff, 0.6, 10 );
    light2.position.set( 0, 0, 1 );
    scene.add( light2 );

    //solutions/starting positions available to simulate
    //[0:14]
    var solution = 3;

    //array of spheres, carries other information like
    //time-step size, trail length
    var bodies = [];
    reset(bodies, scene, solution);

    //simulation parameters
    var step = 0;

    //bind function to dropdown menu for solution selection
    $("#simulationSelection").click(function(x){
        solution = x.target.id;
        reset(bodies, scene, solution);
    });

    bodies.currentFocus = -1;
    //focus point function
    $("#focusRadio").click(function(x){
        var newFocus = x.target.value;
        if (bodies.currentFocus != newFocus){
            bodies.currentFocus = newFocus;
            reset(bodies, scene, solution);
        }
    });

    function animate(){
        move(bodies)
        step++
        if (step % 1000 == 0){
            for (var i = 0; i < bodies.length; i++){
                var v = bodies[i].velocity;
                var p = bodies[i].position;
                if (v.length() > 10 || p.length() > 10){
                    console.log(step);
                    reset(bodies, scene, solution);
                }
            }
            console.log(step);
        }
        requestAnimationFrame( animate );
        controls.update();
        renderer.render( scene, camera );
    }

    function render(){
        renderer.render( scene, camera );
    }

    animate();
});

function move(bodies){
    for (var i = 0; i < bodies.speed; i++){
        rk4(bodies);
    }
    //recenter on the focussed body
    if (bodies.currentFocus != -1){
        var adjustment = bodies[bodies.currentFocus].position.clone();
        for (var i = 0; i < bodies.length; i++){
            bodies[i].position.sub(adjustment);
        }
    }

    for (var i = 0; i < bodies.length; i++){
        //Lines seem to be fixed length,
        //but we can push and shift to get a trail.
        bodies[i].trail.geometry.vertices.shift();
        bodies[i].trail.geometry.vertices.push(bodies[i].position.clone());
        bodies[i].trail.geometry.verticesNeedUpdate = true;
    }
}

//https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods#Common_fourth-order_Runge.E2.80.93Kutta_method
//http://home.deds.nl/~infokees/useful/OrbitRungeKutta4.pdf
//Could we improve accuracy by considering all particles at once?
function rk4(bodies){
    var h = bodies.dt;
    var movements= [];
    for (var i = 0; i < bodies.length; i++){
        var r = bodies[i].position;
        var v = bodies[i].velocity;

        //running totals remove need to clone vectors
        //Equations 11 & 12
        var dr = new THREE.Vector3(0,0,0);
        var dv = new THREE.Vector3(0,0,0);

        //Equation 10 is missing a "+"
        var k1v = a(i, r, bodies);
        dv.add(k1v);

        var k1r = v.clone();
        dr.add(k1r);

        var k2v = a(i, k1r.multiplyScalar(h/2).add(r), bodies);
        dv.add(k2v).add(k2v);

        var k2r = k1v.multiplyScalar(h/2).add(v);
        dr.add(k2r).add(k2r);

        var k3v = a(i, k2r.multiplyScalar(h/2).add(r), bodies);
        dv.add(k3v).add(k3v);

        var k3r = k2v.multiplyScalar(h/2).add(v);
        dr.add(k3r).add(k3r);

        var k4v = a(i, k3r.multiplyScalar(h).add(r), bodies);
        dv.add(k4v);

        var k4r = k3v.multiplyScalar(h).add(v);
        dr.add(k4r);

        bodies[i].velocity.add(dv.multiplyScalar(h/6));
        bodies[i].position.add(dr.multiplyScalar(h/6));
    }
}

//calculates the acceleration of body i if it were at position p
function a(i, p, bodies){
    //F = G*m1*m2/r^2
    //G,m = 1
    //F points in the direction of the attractor
    var sum = new THREE.Vector3(0,0,0);
    for (var j = 0; j < bodies.length; j++){
        if (j == i){
            continue;
        }
        var d2 = p.distanceToSquared(bodies[j].position);
        var r = new THREE.Vector3(0,0,0);
        r.subVectors(bodies[j].position, p) //vector to attractor
        .normalize() //unit vector
        .divideScalar(d2);
        sum.add(r);
    }
    return sum;
}

//resets the bodies to the starting positions and velocities given in
//the paper http://arxiv.org/pdf/1303.0181v1.pdf
//solution in [0:14]
function reset(bodies, scene, solution){
    bodies.dt = 0.001;
    bodies.speed = 5;
    //numerical stability is governed by how close the bodies come to each other during an orbit
    //these are derived empically
    var instability = [10,20,10,1,2,10,20,20,50,20,100,10,10,2000,2000];
    bodies.dt /= instability[solution];
    bodies.speed *= instability[solution];

    //period of orbit from paper
    var ts =     [6.2356,  7.0039, 63.5345, 14.8939, 28.6703, 13.8658, 25.8406, 10.4668, 79.4759,  21.2710, 55.5018, 17.3284, 10.9626, 55.7898, 54.2076 ];
    var period = ts[solution];
    //make the trails as long as the orbit
    bodies.segments = period / bodies.dt/bodies.speed ;

    for (var i = 0; i < bodies.length; i++){
        scene.remove(bodies[i].trail);
        scene.remove(bodies[i]);
    }

    //n = 3...
    for (var i = 0; i < 3; i++){
        //size and detail of spheres
        var geometry = new THREE.SphereGeometry(0.1,16,16);
        var material = new THREE.MeshPhongMaterial( { color: 0xff << (i*8)} );
        var body = new THREE.Mesh( geometry, material );
        body.velocity = new THREE.Vector3(0,0,0);

        //trailing lines
        var lineMaterial = new THREE.LineBasicMaterial({ color: body.material.color });
        var lineGeometry = new THREE.Geometry();
        for (var j = 0; j < bodies.segments; j++){
            //lines start at the initial positions of the spheres
            lineGeometry.vertices.push(new THREE.Vector3([-1,1,0][i],0,0));
        }
        body.trail = new THREE.Line(lineGeometry, lineMaterial);
        bodies[i] = body;
    }

    for (var i = 0; i < bodies.length; i++){
        scene.add(bodies[i]);
        scene.add(bodies[i].trail);
    }

    //The paper refers to the particles as 1,2,3
    //I use 0,1,2
    var x1dots = [0.30689, 0.39295, 0.18428, 0.46444, 0.43917, 0.40592, 0.38344, 0.08330, 0.350112, 0.08058, 0.55906, 0.51394, 0.28270, 0.41682, 0.41734];
    var y1dots = [0.12551, 0.09758, 0.58719, 0.39606, 0.45297, 0.23016, 0.37736, 0.12789, 0.079340, 0.58884, 0.34919, 0.30474, 0.32721, 0.33033, 0.31310];

    var x1dot = x1dots[solution];
    var y1dot = y1dots[solution];

    bodies[0].velocity.x = x1dot;
    bodies[1].velocity.x = x1dot;
    bodies[2].velocity.x = -2*x1dot;

    bodies[0].velocity.y = y1dot;
    bodies[1].velocity.y = y1dot;
    bodies[2].velocity.y = -2*y1dot;

    bodies[0].position.x = -1;
    bodies[1].position.x = 1;
    bodies[2].position.x = 0;

    bodies[0].position.y = 0;
    bodies[1].position.y = 0;
    bodies[2].position.y = 0;
}

<|endoftext|>


<commit_before>// Copyright 2011 WebDriver committers
// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Ready to inject atoms for manipulating the DOM.
 */

goog.provide('webdriver.atoms.inject.action');

goog.require('bot.action');
goog.require('bot.inject');
goog.require('goog.dom.selection');

/**
 * Submits the form containing the given element.
 *
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to submit.
 */
webdriver.atoms.inject.action.submit = function(element) {
  bot.inject.executeScript(bot.action.submit, [element], true);
};

/**
 * Clear an element.
 *
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to clear.
 * @see bot.action.clear
 */
webdriver.atoms.inject.action.clear = function(element) {
  bot.inject.executeScript(bot.action.clear, [element], true);
};

/**
 * Click an element.
 *
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to click.
 * @see bot.action.click
 */
webdriver.atoms.inject.action.click = function(element) {
  bot.inject.executeScript(bot.action.click, [element], true);
};<commit_msg>DanielWagnerHall: Adding trailing newline<commit_after>// Copyright 2011 WebDriver committers
// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Ready to inject atoms for manipulating the DOM.
 */

goog.provide('webdriver.atoms.inject.action');

goog.require('bot.action');
goog.require('bot.inject');
goog.require('goog.dom.selection');

/**
 * Submits the form containing the given element.
 *
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to submit.
 */
webdriver.atoms.inject.action.submit = function(element) {
  bot.inject.executeScript(bot.action.submit, [element], true);
};

/**
 * Clear an element.
 *
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to clear.
 * @see bot.action.clear
 */
webdriver.atoms.inject.action.clear = function(element) {
  bot.inject.executeScript(bot.action.clear, [element], true);
};

/**
 * Click an element.
 *
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to click.
 * @see bot.action.click
 */
webdriver.atoms.inject.action.click = function(element) {
  bot.inject.executeScript(bot.action.click, [element], true);
};

<|endoftext|>


<commit_before>const http = require('http');
const reporter = require('mocha/lib/reporters').min;
const bridgeTests = require('mocha-selenium-bridge');
const { Builder } = require('selenium-webdriver');
const handler = require('serve-handler');

const PORT = 3000;
const URL = `http://localhost:${PORT}/test/browser/selenium.html`;

const bsConfig = {
  project: 'messageformat',
  'browserstack.local': 'true',
  'browserstack.user': process.env.BROWSERSTACK_USER,
  'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY,
  'browserstack.localIdentifier': process.env.BROWSERSTACK_LOCAL_IDENTIFIER
};

const browsers = [
  { browserName: 'Chrome', browser_version: '49.0' },
  { browserName: 'Firefox', browser_version: '66.0' },
  { browserName: 'IE', browser_version: '11.0' },
  { browserName: 'Edge', browser_version: '17.0' }
  // { browserName: 'Safari', browser_version: '12.0' }
  // {
  //   browserName: 'android',
  //   device: 'Samsung Galaxy S6',
  //   realMobile: 'true',
  //   os_version: '5.0'
  // },
  // {
  //   browserName: 'iPhone',
  //   device: 'iPhone 6S',
  //   realMobile: 'true',
  //   os_version: '11.4'
  // }
];

function buildDriver(browser) {
  const cap = Object.assign({}, browser, bsConfig);
  return new Builder()
    .usingServer('http://hub-cloud.browserstack.com/wd/hub')
    .withCapabilities(cap)
    .build();
}

describe('Browser tests', function() {
  this.timeout(120 * 1000);

  let server;
  before(() => {
    server = http.createServer((req, res) => handler(req, res));
    server.listen(PORT);
  });
  after(() => {
    server.close();
  });

  for (const browser of browsers) {
    const version = browser.browser_version || browser.os_version;
    const title = `${browser.browserName} ${version}`;
    it(title, async () => {
      console.log(`
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
Testing ${title}...`);
      const driver = buildDriver(browser);
      const code = await bridgeTests(driver, reporter, URL);
      if (code > 0) throw new Error(`Failed ${code} tests`);
      if (code < 0) throw new Error(`MSB error ${code}`);
    });
  }
});
<commit_msg>fix(browserstack-tests): Remember to call driver.quit()<commit_after>const http = require('http');
const reporter = require('mocha/lib/reporters').min;
const bridgeTests = require('mocha-selenium-bridge');
const { Builder } = require('selenium-webdriver');
const handler = require('serve-handler');

const PORT = 3000;
const URL = `http://localhost:${PORT}/test/browser/selenium.html`;

const bsConfig = {
  project: 'messageformat',
  'browserstack.local': 'true',
  'browserstack.user': process.env.BROWSERSTACK_USER,
  'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY,
  'browserstack.localIdentifier': process.env.BROWSERSTACK_LOCAL_IDENTIFIER
};

const browsers = [
  { browserName: 'Chrome', browser_version: '49.0' },
  { browserName: 'Firefox', browser_version: '66.0' },
  { browserName: 'IE', browser_version: '11.0' },
  { browserName: 'Edge', browser_version: '17.0' }
  // { browserName: 'Safari', browser_version: '12.0' }
  // {
  //   browserName: 'android',
  //   device: 'Samsung Galaxy S6',
  //   realMobile: 'true',
  //   os_version: '5.0'
  // },
  // {
  //   browserName: 'iPhone',
  //   device: 'iPhone 6S',
  //   realMobile: 'true',
  //   os_version: '11.4'
  // }
];

function buildDriver(browser) {
  const cap = Object.assign({}, browser, bsConfig);
  return new Builder()
    .usingServer('http://hub-cloud.browserstack.com/wd/hub')
    .withCapabilities(cap)
    .build();
}

describe('Browser tests', function() {
  this.timeout(120 * 1000);

  let server;
  before(() => {
    server = http.createServer((req, res) => handler(req, res));
    server.listen(PORT);
  });
  after(() => {
    server.close();
  });

  for (const browser of browsers) {
    const version = browser.browser_version || browser.os_version;
    const title = `${browser.browserName} ${version}`;
    it(title, async () => {
      console.log(`
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
Testing ${title}...`);
      const driver = buildDriver(browser);
      const code = await bridgeTests(driver, reporter, URL);
      driver.quit();
      if (code > 0) throw new Error(`Failed ${code} tests`);
      if (code < 0) throw new Error(`MSB error ${code}`);
    });
  }
});
<|endoftext|>


<commit_before>var express =  require('express');
var app = express();
var mongoose = require('mongoose');
var config = require('./config');
var songs = require('./songs');

console.log('Database: ' + config.db[app.settings.env]);

mongoose.connect(config.db[app.settings.env], function(err) {
  if(err) {
    return console.log('Mongo connect error... ' + err);
  }
  var db = mongoose.connection;

  app.use(function(req, res, next){
    req.db = db;
    next();
  });

  app.use('/songs', songs);

  app.listen(8888, function() {
    console.log('Listening on port 8888');
  });
});

<commit_msg>Update index.js<commit_after>var express =  require('express');
var app = express();
var mongoose = require('mongoose');
var config = require('./config');
var songs = require('./songs');

console.log('Database: ' + config.db[app.settings.env]);

mongoose.Promise = global.Promise;
mongoose.connect(config.db[app.settings.env], function(err) {
  if(err) {
    return console.log('Mongo connect error... ' + err);
  }
  var db = mongoose.connection;

  app.use(function(req, res, next){
    req.db = db;
    next();
  });

  app.use('/songs', songs);

  app.listen(8888, function() {
    console.log('Listening on port 8888');
  });
});

<|endoftext|>


<commit_before>/*! pix2rem 2015-12-31 Author:Nelson Kuang license:MIT */
!function(){function a(){var a={UCBrowser:function(){return navigator.userAgent.match(/UCBrowser/i)},MicroMessenger:function(){return navigator.userAgent.match(/MicroMessenger/i)},Android:function(){return navigator.userAgent.match(/Android/i)},BlackBerry:function(){return navigator.userAgent.match(/BlackBerry/i)},iPad:function(){return navigator.userAgent.match(/iPad/i)},iPhone:function(){return navigator.userAgent.match(/iPhone/i)},iOS:function(){return navigator.userAgent.match(/iPhone|iPod|iPad/i)},Opera:function(){return navigator.userAgent.match(/Opera Mini/i)},Windows:function(){return navigator.userAgent.match(/IEMobile/i)},any:function(){return a.Android()||a.BlackBerry()||a.iOS()||a.Opera()||a.Windows()}},b=window.screen.width,c=window.devicePixelRatio,d=750;a.UCBrowser()||a.MicroMessenger()&&!a.iPhone()?(b>d?document.querySelector("html").style.fontSize=b/c/10+"px":document.querySelector("html").style.fontSize=b/10+"px",a.any()||(document.querySelector("html").style.fontSize=d/10+"px")):a.iPhone()?document.querySelector("html").style.fontSize=b/10+"px":a.iPad()?document.querySelector("html").style.fontSize=d/10+"px":a.any()?document.querySelector("html").style.fontSize=b/10+"px":window.innerWidth<=d?document.querySelector("html").style.fontSize=window.innerWidth/10+"px":document.querySelector("html").style.fontSize=d/10+"px"}a(),window.onresize=function(){a()}}();
<commit_msg>Update pix2rem.min.js<commit_after>/*! pix2rem 2016-01-20 Author:Nelson Kuang license:MIT */
!function(){function a(){var a={UCBrowser:function(){return navigator.userAgent.match(/UCBrowser/i)},MicroMessenger:function(){return navigator.userAgent.match(/MicroMessenger/i)},Android:function(){return navigator.userAgent.match(/Android/i)},BlackBerry:function(){return navigator.userAgent.match(/BlackBerry/i)},iPad:function(){return navigator.userAgent.match(/iPad/i)},iPhone:function(){return navigator.userAgent.match(/iPhone/i)},iOS:function(){return navigator.userAgent.match(/iPhone|iPod|iPad/i)},Opera:function(){return navigator.userAgent.match(/Opera Mini/i)},Windows:function(){return navigator.userAgent.match(/IEMobile/i)},any:function(){return a.Android()||a.BlackBerry()||a.iOS()||a.Opera()||a.Windows()}},b=window.screen.width,c=window.devicePixelRatio,d=750;a.UCBrowser()||a.MicroMessenger()&&!a.iPhone()?(b>d?document.querySelector("html").style.fontSize=b/c/10+"px":document.querySelector("html").style.fontSize=b/10+"px",a.any()||(document.querySelector("html").style.fontSize=d/10+"px")):a.iPhone()?document.querySelector("html").style.fontSize=b/10+"px":a.iPad()?document.querySelector("html").style.fontSize=d/10+"px":a.any()?b/10>70?document.querySelector("html").style.fontSize=b/c/10+"px":document.querySelector("html").style.fontSize=b/10+"px":window.innerWidth<=d?document.querySelector("html").style.fontSize=window.innerWidth/10+"px":document.querySelector("html").style.fontSize=d/10+"px"}a(),window.onresize=function(){a()}}();
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'underscore',
    'find/app/page/search/service-view',
    'find/hod/app/page/search/results/hod-results-view-augmentation',
    'find/hod/app/page/search/results/hod-results-view',
    'find/app/util/model-any-changed-attribute-listener'
], function (_, ServiceView, ResultsViewAugmentation, ResultsView, addChangeListener) {

    'use strict';

    //noinspection JSUnusedGlobalSymbols
    return ServiceView.extend({
        ResultsView: ResultsView,
        ResultsViewAugmentation: ResultsViewAugmentation,

        // TODO: Enable sunburst in HOD when IOD-9173 is complete
        // TODO: When sunburst is enabled make this.fetchParametricFields also fetch the restrictedParametricCollection
        displayDependentParametricViews: false,
        mapViewResultsStep: 2500,
        mapViewAllowIncrement: false,

        initialize: function(options) {
            ServiceView.prototype.initialize.call(this, options);
            addChangeListener(this, this.queryModel, ['queryText', 'fieldText', 'minDate', 'maxDate', 'minScore', 'stateMatchIds'], this.fetchData);
            addChangeListener(this, this.queryModel, ['indexes'], function () {
                this.fetchEntities();
                this.parametricFieldsCollection.reset();
                this.numericParametricFieldsCollection.reset();
                this.dateParametricFieldsCollection.reset();
                if (this.queryModel.get('indexes').length !== 0) {
                    this.fetchParametricFields(this.parametricFieldsCollection, _.bind(this.fetchParametricValueCollections, this));
                    this.fetchParametricFields(this.numericParametricFieldsCollection);
                    this.fetchParametricFields(this.dateParametricFieldsCollection);
                }
            });
        },

        fetchParametricFields: function (fieldsCollection, callback) {
            if (this.queryModel.get('indexes').length > 0) {
                fieldsCollection.fetch({
                    data: {
                        databases: this.queryModel.get('indexes')
                    },
                    success: _.bind(function () {
                        if (callback) {
                            callback();
                        }
                    }, this)
                });
            }
        },

        fetchParametricValues: function () {
            this.parametricCollection.reset();

            if (this.queryModel.get('indexes').length !== 0) {
                var fieldNames = this.parametricFieldsCollection.pluck('id');
                if (fieldNames.length > 0) {
                    this.parametricCollection.fetch({data: {
                        databases: this.queryModel.get('indexes'),
                        fieldNames: fieldNames
                    }});
                }
            }
        }
    });
});
<commit_msg>[FIND-687] Fixed HOD BIFHI initialisation error.<commit_after>/*
 * Copyright 2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'underscore',
    'find/app/page/search/service-view',
    'find/hod/app/page/search/results/hod-results-view-augmentation',
    'find/hod/app/page/search/results/hod-results-view',
    'find/app/util/model-any-changed-attribute-listener'
], function (_, ServiceView, ResultsViewAugmentation, ResultsView, addChangeListener) {

    'use strict';

    //noinspection JSUnusedGlobalSymbols
    return ServiceView.extend({
        ResultsView: ResultsView,
        ResultsViewAugmentation: ResultsViewAugmentation,

        // TODO: Enable sunburst in HOD when IOD-9173 is complete
        // TODO: When sunburst is enabled make this.fetchParametricFields also fetch the restrictedParametricCollection
        displayDependentParametricViews: false,
        mapViewResultsStep: 2500,
        mapViewAllowIncrement: false,

        initialize: function(options) {
            ServiceView.prototype.initialize.call(this, options);
            addChangeListener(this, this.queryModel, ['queryText', 'fieldText', 'minDate', 'maxDate', 'minScore', 'stateMatchIds'], this.fetchData);

            addChangeListener(this, this.queryModel, ['indexes'], function () {
                if (this.entityCollection) {
                    this.fetchEntities();
                }

                this.parametricFieldsCollection.reset();
                this.numericParametricFieldsCollection.reset();
                this.dateParametricFieldsCollection.reset();

                if (this.queryModel.get('indexes').length !== 0) {
                    this.fetchParametricFields(this.parametricFieldsCollection, _.bind(this.fetchParametricValueCollections, this));
                    this.fetchParametricFields(this.numericParametricFieldsCollection);
                    this.fetchParametricFields(this.dateParametricFieldsCollection);
                }
            });
        },

        fetchParametricFields: function (fieldsCollection, callback) {
            if (this.queryModel.get('indexes').length > 0) {
                fieldsCollection.fetch({
                    data: {
                        databases: this.queryModel.get('indexes')
                    },
                    success: _.bind(function () {
                        if (callback) {
                            callback();
                        }
                    }, this)
                });
            }
        },

        fetchParametricValues: function () {
            this.parametricCollection.reset();

            if (this.queryModel.get('indexes').length !== 0) {
                var fieldNames = this.parametricFieldsCollection.pluck('id');
                if (fieldNames.length > 0) {
                    this.parametricCollection.fetch({data: {
                        databases: this.queryModel.get('indexes'),
                        fieldNames: fieldNames
                    }});
                }
            }
        }
    });
});
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

/* eslint-disable no-console */
/* global console */

var allocCluster = require('../lib/test-cluster.js');
var collectParallel = require('collect-parallel/array');

var DUMP_LOGS = false;

allocCluster.test('dead exit peers get reaped', {
    size: 10,
    namedRemotes: ['alice', 'alice', 'alice', 'alice', 'alice', 'alice', 'alice'],
    whitelist: [
        ['info', 'implementing affinity change'],
        ['info', 'pruning ex-affinity peers'],
        ['info', 'draining ex-affinity peer'],
        ['info', 'draining peer'],
        ['info', 'Refreshing service peer affinity'],
        ['info', 'reaping dead peers'],
        ['info', 'reaping dead peer'],
        ['info', 'pruning peers'],
        ['info', 'draining pruned peer'],
        ['info', 'refreshed peer partially']
    ]
}, function t(cluster, assert) {
    var activeNum = 3;

    // for more determinism
    cluster.namedRemotes.sort(function byHostPort(a, b) {
        if (a.hostPort < b.hostPort) {
            return -1;
        } else if (a.hostPort > b.hostPort) {
            return 1;
        }
        return 0;
    });

    pruneClusterPears(cluster, assert, initialPruneDone);

    function initialPruneDone() {
        takeLogs();
        assert.comment('- initialPruneDone');

        // Verify that hyperban is connected to all the alices
        checkAllExitPeers(cluster, assert, null);

        // Reap peers that have not registered (nobody)
        reapClusterPears(cluster, assert, initialReapDone);
    }

    function initialReapDone() {
        takeLogs();
        assert.comment('- initialReapDone');

        // Verify that all alices are still connected
        checkAllExitPeers(cluster, assert, null);

        // Some of the peers re-register
        collectParallel(
            cluster.namedRemotes.slice(0, activeNum),
            function reregEach(alice, i, done) {
                cluster.sendRegister(alice.channel, {
                    serviceName: alice.serviceName
                }, done);
            },
            afterReRegister
        );
    }

    function afterReRegister(_, results) {
        takeLogs();
        assert.comment('- afterReRegister');

        var done = false;
        for (var i = 0; i < results.length; i++) {
            var res = results[i];
            done = done || !!res.err;
            assert.ifError(res.err, 'no unexpected error from rereg ' + i);
        }
        if (done) {
            assert.end();
            return;
        }

        reapClusterPears(cluster, assert, afterReapPeers);
    }

    function afterReapPeers() {
        takeLogs();
        assert.comment('- afterReapPeers');

        pruneClusterPears(cluster, assert, afterReapPrunePeers);
    }

    function afterReapPrunePeers() {
        takeLogs();
        assert.comment('- afterReapPrunePeers');

        checkAllExitPeers(cluster, assert, [
            // Some of the peers remain
            false,
            false,
            false,
            // Others not so much
            true,
            true,
            true,
            true
        ]);

        // But then everybody registers again!
        collectParallel(
            cluster.namedRemotes,
            function reregEach(alice, i, done) {
                cluster.sendRegister(alice.channel, {
                    serviceName: alice.serviceName
                }, done);
            },
            afterResurrection
        );
    }

    function afterResurrection(_, results) {
        takeLogs();
        assert.comment('- afterResurrection');

        var done = false;
        for (var i = 0; i < results.length; i++) {
            var res = results[i];
            done = done || !!res.err;
            assert.ifError(res.err, 'no unexpected error from resurrection ' + i);
        }
        if (done) {
            assert.end();
            return;
        }

        pruneClusterPears(cluster, assert, afterResPruneDone);
    }

    function afterResPruneDone() {
        takeLogs();
        assert.comment('- afterResPruneDone');

        // Verify that all the peers have rejoined the fray.
        checkAllExitPeers(cluster, assert, null);

        // And they all lived happily ever after.
        // The end.
        assert.end();

    }

    function takeLogs() {
        var logs = cluster.logger._backend.records.slice(0);
        cluster.logger._backend.records.length = 0;
        if (DUMP_LOGS) {
            logs2console(logs);
        }
        return logs;
    }
});

function logs2console(logs) {
    console.log(
        logs.map(function each(log) {
            var data = log._logData;
            return data.time + ' ' +
                data.level.toUpperCase() + ' ' +
                data.msg + ' ' +
                JSON.stringify(data.fields);
        }).join('\n')
    );
}

function reapClusterPears(cluster, assert, callback) {
    collectParallel(
        cluster.apps,
        function reapEach(app, i, done) {
            var serviceProxy = app.clients.serviceProxy;
            serviceProxy.peerReaper.run(done);
        },
        function finish(_, results) {
            for (var i = 0; i < results.length; i++) {
                var res = results[i];
                assert.ifError(res.err, 'no error from reaping app ' + i);
            }
            callback();
        }
    );
}

function pruneClusterPears(cluster, assert, callback) {
    collectParallel(
        cluster.apps,
        function pruneEach(app, i, done) {
            var serviceProxy = app.clients.serviceProxy;
            serviceProxy.peerPruner.run(done);
        },
        function finish(_, results) {
            for (var i = 0; i < results.length; i++) {
                var res = results[i];
                assert.ifError(res.err, 'no error from pruning app ' + i);
            }
            callback();
        }
    );
}

var getPeerInfo = require('../../peer-info.js');

function checkAllExitPeers(cluster, assert, isDead) {
    cluster.namedRemotes.forEach(function eachRemote(alice, i) {
        assert.comment('-- checkExitPeers for ' + i);

        var app = cluster.apps[0];
        var exitShard = app.clients.egressNodes.exitsFor(alice.serviceName);
        var exitApps = cluster.apps.filter(function isExit(someApp) {
            return !!exitShard[someApp.tchannel.hostPort];
        });

        var peersInfo = {
            seenServiceName: {},
            numExistantPeers: 0,
            connected: {
                out: false,
                in: false
            }
        };

        exitApps.forEach(function anyAppPeerInfo(exitApp) {
            var peer = exitApp.tchannel.peers.get(alice.hostPort);
            if (!peer) {
                return;
            }
            peersInfo.numExistantPeers++;
            var peerInfo = getPeerInfo(peer);
            peerInfo.serviceNames.forEach(function eachServiceName(serviceName) {
                peersInfo.seenServiceName[serviceName] = true;
            });
            peersInfo.connected.out = peersInfo.connected.out || peerInfo.connected.out;
            peersInfo.connected.in = peersInfo.connected.in || peerInfo.connected.in;
        });
        peersInfo.serviceNames = Object.keys(peersInfo.seenServiceName);

        if (isDead && isDead[i]) {
            assert.equal(
                peersInfo.serviceNames.length, 0,
                'peer has no services');
        } else {
            assert.ok(peersInfo.numExistantPeers > 0,
                      'should have a peer on every exitApp');
            assert.ok(
                peersInfo.connected.out ||
                peersInfo.connected.in,
                'exitApp is connected to peer');
        }
    });
}
<commit_msg>test/forward/dead-remote-reaped.js: expect peer affinity audit fail warn<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

/* eslint-disable no-console */
/* global console */

var allocCluster = require('../lib/test-cluster.js');
var collectParallel = require('collect-parallel/array');

var DUMP_LOGS = false;

allocCluster.test('dead exit peers get reaped', {
    size: 10,
    namedRemotes: ['alice', 'alice', 'alice', 'alice', 'alice', 'alice', 'alice'],
    whitelist: [
        // TODO: this is debt, this should not be an expected log; we should
        // understand and fix the cause of and need for this audit
        ['warn', 'partial affinity audit fail'],

        ['info', 'implementing affinity change'],
        ['info', 'pruning ex-affinity peers'],
        ['info', 'draining ex-affinity peer'],
        ['info', 'draining peer'],
        ['info', 'Refreshing service peer affinity'],
        ['info', 'reaping dead peers'],
        ['info', 'reaping dead peer'],
        ['info', 'pruning peers'],
        ['info', 'draining pruned peer'],
        ['info', 'refreshed peer partially']
    ]
}, function t(cluster, assert) {
    var activeNum = 3;

    // for more determinism
    cluster.namedRemotes.sort(function byHostPort(a, b) {
        if (a.hostPort < b.hostPort) {
            return -1;
        } else if (a.hostPort > b.hostPort) {
            return 1;
        }
        return 0;
    });

    pruneClusterPears(cluster, assert, initialPruneDone);

    function initialPruneDone() {
        takeLogs();
        assert.comment('- initialPruneDone');

        // Verify that hyperban is connected to all the alices
        checkAllExitPeers(cluster, assert, null);

        // Reap peers that have not registered (nobody)
        reapClusterPears(cluster, assert, initialReapDone);
    }

    function initialReapDone() {
        takeLogs();
        assert.comment('- initialReapDone');

        // Verify that all alices are still connected
        checkAllExitPeers(cluster, assert, null);

        // Some of the peers re-register
        collectParallel(
            cluster.namedRemotes.slice(0, activeNum),
            function reregEach(alice, i, done) {
                cluster.sendRegister(alice.channel, {
                    serviceName: alice.serviceName
                }, done);
            },
            afterReRegister
        );
    }

    function afterReRegister(_, results) {
        takeLogs();
        assert.comment('- afterReRegister');

        var done = false;
        for (var i = 0; i < results.length; i++) {
            var res = results[i];
            done = done || !!res.err;
            assert.ifError(res.err, 'no unexpected error from rereg ' + i);
        }
        if (done) {
            assert.end();
            return;
        }

        reapClusterPears(cluster, assert, afterReapPeers);
    }

    function afterReapPeers() {
        takeLogs();
        assert.comment('- afterReapPeers');

        pruneClusterPears(cluster, assert, afterReapPrunePeers);
    }

    function afterReapPrunePeers() {
        takeLogs();
        assert.comment('- afterReapPrunePeers');

        checkAllExitPeers(cluster, assert, [
            // Some of the peers remain
            false,
            false,
            false,
            // Others not so much
            true,
            true,
            true,
            true
        ]);

        // But then everybody registers again!
        collectParallel(
            cluster.namedRemotes,
            function reregEach(alice, i, done) {
                cluster.sendRegister(alice.channel, {
                    serviceName: alice.serviceName
                }, done);
            },
            afterResurrection
        );
    }

    function afterResurrection(_, results) {
        takeLogs();
        assert.comment('- afterResurrection');

        var done = false;
        for (var i = 0; i < results.length; i++) {
            var res = results[i];
            done = done || !!res.err;
            assert.ifError(res.err, 'no unexpected error from resurrection ' + i);
        }
        if (done) {
            assert.end();
            return;
        }

        pruneClusterPears(cluster, assert, afterResPruneDone);
    }

    function afterResPruneDone() {
        takeLogs();
        assert.comment('- afterResPruneDone');

        // Verify that all the peers have rejoined the fray.
        checkAllExitPeers(cluster, assert, null);

        // And they all lived happily ever after.
        // The end.
        assert.end();

    }

    function takeLogs() {
        var logs = cluster.logger._backend.records.slice(0);
        cluster.logger._backend.records.length = 0;
        if (DUMP_LOGS) {
            logs2console(logs);
        }
        return logs;
    }
});

function logs2console(logs) {
    console.log(
        logs.map(function each(log) {
            var data = log._logData;
            return data.time + ' ' +
                data.level.toUpperCase() + ' ' +
                data.msg + ' ' +
                JSON.stringify(data.fields);
        }).join('\n')
    );
}

function reapClusterPears(cluster, assert, callback) {
    collectParallel(
        cluster.apps,
        function reapEach(app, i, done) {
            var serviceProxy = app.clients.serviceProxy;
            serviceProxy.peerReaper.run(done);
        },
        function finish(_, results) {
            for (var i = 0; i < results.length; i++) {
                var res = results[i];
                assert.ifError(res.err, 'no error from reaping app ' + i);
            }
            callback();
        }
    );
}

function pruneClusterPears(cluster, assert, callback) {
    collectParallel(
        cluster.apps,
        function pruneEach(app, i, done) {
            var serviceProxy = app.clients.serviceProxy;
            serviceProxy.peerPruner.run(done);
        },
        function finish(_, results) {
            for (var i = 0; i < results.length; i++) {
                var res = results[i];
                assert.ifError(res.err, 'no error from pruning app ' + i);
            }
            callback();
        }
    );
}

var getPeerInfo = require('../../peer-info.js');

function checkAllExitPeers(cluster, assert, isDead) {
    cluster.namedRemotes.forEach(function eachRemote(alice, i) {
        assert.comment('-- checkExitPeers for ' + i);

        var app = cluster.apps[0];
        var exitShard = app.clients.egressNodes.exitsFor(alice.serviceName);
        var exitApps = cluster.apps.filter(function isExit(someApp) {
            return !!exitShard[someApp.tchannel.hostPort];
        });

        var peersInfo = {
            seenServiceName: {},
            numExistantPeers: 0,
            connected: {
                out: false,
                in: false
            }
        };

        exitApps.forEach(function anyAppPeerInfo(exitApp) {
            var peer = exitApp.tchannel.peers.get(alice.hostPort);
            if (!peer) {
                return;
            }
            peersInfo.numExistantPeers++;
            var peerInfo = getPeerInfo(peer);
            peerInfo.serviceNames.forEach(function eachServiceName(serviceName) {
                peersInfo.seenServiceName[serviceName] = true;
            });
            peersInfo.connected.out = peersInfo.connected.out || peerInfo.connected.out;
            peersInfo.connected.in = peersInfo.connected.in || peerInfo.connected.in;
        });
        peersInfo.serviceNames = Object.keys(peersInfo.seenServiceName);

        if (isDead && isDead[i]) {
            assert.equal(
                peersInfo.serviceNames.length, 0,
                'peer has no services');
        } else {
            assert.ok(peersInfo.numExistantPeers > 0,
                      'should have a peer on every exitApp');
            assert.ok(
                peersInfo.connected.out ||
                peersInfo.connected.in,
                'exitApp is connected to peer');
        }
    });
}
<|endoftext|>