<commit_before>(function () {
    'use strict';

    var crypto = require('crypto');
    var bodyParser = require('body-parser');
    var r = require('rethinkdb');
    var config = require('../config');
    var router = require('express').Router();

    var lastUpdate = 0;

    router.get('/photo', function (req, res) {
        config.logger.info('GET request for /photo. query["hub.challenge"] = ' + req.query['hub.challenge']);

        if (req.query['hub.verify_token'] == config.instagram.verify) {
            res.send(req.query['hub.challenge']);
        } else {
            config.logger.error('token verification incorrect');
            res.status(500).json({err: 'Verify token incorrect'});
        }
    });

    router.use(bodyParser.json({
        verify: function (req, res, buf) {
            var hmac = crypto.createHmac('sha1', config.instagram.secret);
            var hash = hmac.update(buf).digest('hex');

            if (req.header('X-Hub-Signature') == hash) {
                req.validOrigin = true;
            }
        }
    }));

    router.post('/photo', function (req, res) {
        if (!req.validOrigin) {
            config.logger.error('Invalid signature in POST /api/instagram/photo');
            return res.status(500).json({err: 'Invalid signature'});
        }

        var update = req.body[0];
        res.json({success: true, kind: update.object});

        if (update.time - lastUpdate < 1) return;
        lastUpdate = update.time;

        config.logger.info('POST request for /photo. object updated: ' + update.object_id);

        var path = 'https://api.instagram.com/v1/tags/' + update.object_id + '/media/recent?client_id=' + config.instagram.client;

        var conn;
        r.connect(config.database)
            .then(function (c) {
                conn = c;

                var recent = r.http(path)('data');
                config.logger.info('Recent instagram pictures: ' + JSON.stringify(recent));

                var merged = recent.merge(function (item) {
                    return {
                        created_time: r.epochTime(item('created_time').coerceTo('number')),
                        time: r.now(),
                        place: r.point(
                            item('location')('longitude'),
                            item('location')('latitude')).default(null)
                    }
                });

                config.logger.info('Merged instagram pictures: ' + JSON.stringify(merged));

                return r.table('pictures').insert(merged).run(conn);
            })
            .then(function(result) {
                config.logger.info('Inserted new pictures into db. Inserted: ' + result.inserted + '.');
            })
            .error(function (err) {
                config.logger.error(err);
            })
            .finally(function () {
                if (conn)
                    conn.close();
            });
    });

    module.exports = router;
})();
<commit_msg>adding logging statements.<commit_after>(function () {
    'use strict';

    var crypto = require('crypto');
    var bodyParser = require('body-parser');
    var r = require('rethinkdb');
    var config = require('../config');
    var router = require('express').Router();

    var lastUpdate = 0;

    router.get('/photo', function (req, res) {
        config.logger.info('GET request for /photo. query["hub.challenge"] = ' + req.query['hub.challenge']);

        if (req.query['hub.verify_token'] == config.instagram.verify) {
            res.send(req.query['hub.challenge']);
        } else {
            config.logger.error('token verification incorrect');
            res.status(500).json({err: 'Verify token incorrect'});
        }
    });

    router.use(bodyParser.json({
        verify: function (req, res, buf) {
            var hmac = crypto.createHmac('sha1', config.instagram.secret);
            var hash = hmac.update(buf).digest('hex');

            if (req.header('X-Hub-Signature') == hash) {
                req.validOrigin = true;
            }
        }
    }));

    router.post('/photo', function (req, res) {
        if (!req.validOrigin) {
            config.logger.error('Invalid signature in POST /api/instagram/photo');
            return res.status(500).json({err: 'Invalid signature'});
        }

        var update = req.body[0];
        res.json({success: true, kind: update.object});

        if (update.time - lastUpdate < 1) return;
        lastUpdate = update.time;

        config.logger.info('POST request for /photo. object updated: ' + update.object_id);

        var path = 'https://api.instagram.com/v1/tags/' + update.object_id + '/media/recent?client_id=' + config.instagram.client;

        var conn;
        r.connect(config.database)
            .then(function (c) {
                conn = c;

                var recent = r.http(path)('data');
                //config.logger.info('Recent instagram pictures: ' + JSON.stringify(recent));
                //
                //var merged = recent.merge(function (item) {
                //    return {
                //        created_time: r.epochTime(item('created_time').coerceTo('number')),
                //        time: r.now(),
                //        place: r.point(
                //            item('location')('longitude'),
                //            item('location')('latitude')).default(null)
                //    }
                //});
                //
                //config.logger.info('Merged instagram pictures: ' + JSON.stringify(merged));

                return r.table('pictures').insert(recent).run(conn);
            })
            .then(function(result) {
                config.logger.info('Inserted records.');
                config.logger.info('Num Inserted: ' + result.inserted + '.');
            })
            .error(function (err) {
                config.logger.error(err);
            })
            .finally(function () {
                if (conn)
                    conn.close();
            });
    });

    module.exports = router;
})();
<|endoftext|>


<commit_before>import { PropTypes }  from 'react';

import UserAvatar     from '../application/user_avatar.component';

const ProposalInfoComponent = ({
  created_at,
  author,
  children
}) => {
  const authorUrl = author ? `/users/${author.id}` : '#';

  return (

            <UserAvatar user={author} />

            { author ? author.name : 'no user' }

          { ' ' + created_at }

      {children}

  );
};

ProposalInfoComponent.propTypes = {
  created_at: PropTypes.string.isRequired,
  author: PropTypes.object,
  children: PropTypes.any
};

export default ProposalInfoComponent;
<commit_msg>Hide author name and avatar if not present (#681)<commit_after>import { PropTypes }  from 'react';

import UserAvatar     from '../application/user_avatar.component';

const ProposalInfoComponent = ({
  created_at,
  author,
  children
}) => {
  const authorUrl = author ? `/users/${author.id}` : '#';

  return (

      {
        (() => {
          if (author) {
            return (

                    <UserAvatar user={author} />

                    {author.name}

                  { ' ' + created_at }

            );
          }
          return null;
        })()
      }
      {children}

  );
};

ProposalInfoComponent.propTypes = {
  created_at: PropTypes.string.isRequired,
  author: PropTypes.object,
  children: PropTypes.any
};

export default ProposalInfoComponent;
<|endoftext|>


<commit_before>import Ember from 'ember';

import { addAltitudeUnit } from '../utils/units';
import safeComputed from '../utils/safe-computed';

export default Ember.Component.extend(Ember.Evented, {
  layoutName: 'components/base-barogram',

  height: 133,

  flot: null,

  active: [],
  passive: [],
  enls: [],

  contests: null,
  elevations: [],

  flotStyle: safeComputed('height', height => Ember.String.htmlSafe(`width: 100%; height: ${height}px;`)),

  draw() {
    this.update();

    let flot = this.get('flot');
    flot.setupGrid();
    flot.draw();
  },

  didInsertElement() {
    let opts = {
      grid: {
        borderWidth: 0,
        hoverable: true,
        clickable: true,
        autoHighlight: false,
        margin: 5,
      },
      xaxis: {
        mode: 'time',
        timeformat: '%H:%M',
      },
      yaxes: [
        {
          min: 0,
          tickFormatter: addAltitudeUnit,
        },
        {
          show: false,
          min: 0,
          max: 1000,
        },
      ],
      crosshair: {
        mode: 'x',
      },
    };

    if (this.get('uploadMode')) {
      opts.selection = {
        mode: 'x',
      };

      opts.crosshair = {
        mode: null,
      };
    }

    let placeholder = this.$('div');

    this.set('placeholder', placeholder);
    this.set('flot', Ember.$.plot(placeholder, [], opts));

    placeholder.on('plotclick', (event, pos) => {
      this.trigger('baroclick', pos.x / 1000);
    });

    placeholder.on('plotselecting', (event, range, marker) => {
      this.trigger('baroselecting', range, marker);
    });
  },

  update() {
    let data = [];
    this.addElevations(data);
    this.addActiveTraces(data);
    this.addPassiveTraces(data);
    this.addENLData(data);
    this.addContests(data);

    this.get('flot').setData(data);
  },

  addActiveTraces(data) {
    this.get('active').forEach(trace => {
      data.push({
        data: trace.data,
        color: trace.color,
      });
    });
  },

  addPassiveTraces(data) {
    this.get('passive').forEach(trace => {
      let color = Ember.$.color.parse(trace.color).add('a', -0.6).toString();

      data.push({
        data: trace.data,
        color,
        shadowSize: 0,
        lines: {
          lineWidth: 1,
        },
      });
    });
  },

  addENLData(data) {
    this.get('enls').forEach(enl => {
      data.push({
        data: enl.data,
        color: enl.color,
        lines: {
          lineWidth: 0,
          fill: 0.2,
        },
        yaxis: 2,
      });
    });
  },

  addContests(data) {
    // Skip the function if there are no contest markers
    let contests = this.get('contests');
    if (!contests) {
      return;
    }

    // Iterate through the contests
    contests.forEach(contest => {
      let times = contest.get('times');
      if (times.length < 1) {
        return;
      }

      let color = contest.get('color');

      // Add the turnpoint markers to the markings array
      let markings = times.map(time => ({
        position: time * 1000,
      }));

      // Add the chart series for this contest to the data array
      data.push({
        marks: {
          show: true,
          lineWidth: 1,
          toothSize: 6,
          color,
          fillColor: color,
        },
        data: [],
        markdata: markings,
      });
    });
  },

  addElevations(data) {
    data.push({
      data: this.get('elevations'),
      color: 'rgb(235, 155, 98)',
      lines: {
        lineWidth: 0,
        fill: 0.8,
      },
    });
  },
});
<commit_msg>components/base-barogram: Simplify data assembly methods<commit_after>import Ember from 'ember';

import { addAltitudeUnit } from '../utils/units';
import safeComputed from '../utils/safe-computed';

export default Ember.Component.extend(Ember.Evented, {
  layoutName: 'components/base-barogram',

  height: 133,

  flot: null,

  active: [],
  passive: [],
  enls: [],

  contests: null,
  elevations: [],

  flotStyle: safeComputed('height', height => Ember.String.htmlSafe(`width: 100%; height: ${height}px;`)),

  draw() {
    this.update();

    let flot = this.get('flot');
    flot.setupGrid();
    flot.draw();
  },

  didInsertElement() {
    let opts = {
      grid: {
        borderWidth: 0,
        hoverable: true,
        clickable: true,
        autoHighlight: false,
        margin: 5,
      },
      xaxis: {
        mode: 'time',
        timeformat: '%H:%M',
      },
      yaxes: [
        {
          min: 0,
          tickFormatter: addAltitudeUnit,
        },
        {
          show: false,
          min: 0,
          max: 1000,
        },
      ],
      crosshair: {
        mode: 'x',
      },
    };

    if (this.get('uploadMode')) {
      opts.selection = {
        mode: 'x',
      };

      opts.crosshair = {
        mode: null,
      };
    }

    let placeholder = this.$('div');

    this.set('placeholder', placeholder);
    this.set('flot', Ember.$.plot(placeholder, [], opts));

    placeholder.on('plotclick', (event, pos) => {
      this.trigger('baroclick', pos.x / 1000);
    });

    placeholder.on('plotselecting', (event, range, marker) => {
      this.trigger('baroselecting', range, marker);
    });
  },

  update() {
    let data = [];
    this.addElevations(data);
    data = data.concat(this.activeTraces());
    data = data.concat(this.passiveTraces());
    data = data.concat(this.enlData());
    this.addContests(data);

    this.get('flot').setData(data);
  },

  activeTraces() {
    return this.get('active').map(trace => ({
      data: trace.data,
      color: trace.color,
    }));
  },

  passiveTraces() {
    return this.get('passive').map(trace => ({
      data: trace.data,
      color: Ember.$.color.parse(trace.color).add('a', -0.6).toString(),
      shadowSize: 0,
      lines: {
        lineWidth: 1,
      },
    }));
  },

  enlData() {
    return this.get('enls').map(enl => ({
      data: enl.data,
      color: enl.color,
      lines: {
        lineWidth: 0,
        fill: 0.2,
      },
      yaxis: 2,
    }));
  },

  addContests(data) {
    // Skip the function if there are no contest markers
    let contests = this.get('contests');
    if (!contests) {
      return;
    }

    // Iterate through the contests
    contests.forEach(contest => {
      let times = contest.get('times');
      if (times.length < 1) {
        return;
      }

      let color = contest.get('color');

      // Add the turnpoint markers to the markings array
      let markings = times.map(time => ({
        position: time * 1000,
      }));

      // Add the chart series for this contest to the data array
      data.push({
        marks: {
          show: true,
          lineWidth: 1,
          toothSize: 6,
          color,
          fillColor: color,
        },
        data: [],
        markdata: markings,
      });
    });
  },

  addElevations(data) {
    data.push({
      data: this.get('elevations'),
      color: 'rgb(235, 155, 98)',
      lines: {
        lineWidth: 0,
        fill: 0.8,
      },
    });
  },
});
<|endoftext|>


<commit_before>/* eslint-disable no-unused-vars */
module.exports = {
  name: 'Await Reaction Call Action',
  displayName: 'Await Reaction',
  section: 'Messaging',

  subtitle ({ max, time }) {
    const getPlural = (n) => (n !== '1' ? 's' : '')
    return `Await ${max} reaction${getPlural(max)} for ${time} millisecond${getPlural(time)}`
  },

  variableStorage (data, varType) {
    if (parseInt(data.storage2) !== varType) return
    return [data.varName2, `Reaction${parseInt(data.max) === 1 ? '' : ' List'}`]
  },

  fields: ['storage', 'varName', 'filter', 'max', 'time', 'maxEmojis', 'maxUsers', 'iftrue', 'iftrueVal', 'iffalse', 'iffalseVal', 'storage2', 'varName2'],

  html (isEvent, data) {
    return `

      Filter Examples:

          Available variables:

author // The command author

server // Guild where the command was used

          Message variables (Message that is being awaited):

author // The message author

msg // The message object

reaction // The reaction that was added

user // The user that reacted

          Reaction Examples:

reaction.emoji.name === '👌'

['👍', '👎'].includes(reaction.emoji.name)

reaction.emoji.id === '514136831793823756'

reaction.emoji.id // Take any response

          Author Examples:

author.id === '123467823521843898'

author.username === 'Clyde'

author.tag === 'Clyde#0000'

author.id === user.id

          Reaction + Author examples:

reaction.emoji.name === '👍' && author.id === user.id // Take a 👍 reaction from the command message author

reaction.emoji.name === '👍' && author.id === tempVars('some variable') // Take a 👍 reaction from a member with an ID stored in a temp variable

          JavaScript Comparison and Logical Operators

      Source Message:

      <select id="storage" class="round" onchange="glob.messageChange(this, 'varNameContainer')">
        ${data.messages[isEvent ? 1 : 0]}
      </select>

      Variable Name:

      <input id="varName" class="round" type="text" list="variableList">

    JavaScript Filter Eval: (JavaScript Strings)

    <input id="filter" class="round" type="text" value="reaction.emoji.name === '👌' && author.id === user.id">

    Max Reactions:

    <input id="max" class="round" type="text" value="1" placeholder="Optional">

    Max Time (miliseconds):

    <input id="time" class="round" type="text" value="60000" placeholder="Optional">

    Max Emojis:

    <input id="maxEmojis" class="round" type="text" placeholder="Optional">

    Max Users:

    <input id="maxUsers" class="round" type="text" placeholder="Optional">

      On Respond:

      <select id="iftrue" class="round" onchange="glob.onChangeTrue(this)">
        <option value="0" selected>Continue Actions</option>
        <option value="1">Stop Action Sequence</option>
        <option value="2">Jump To Action</option>
        <option value="3">Skip Next Actions</option>
        <option value="4">Jump to Anchor</option>
      </select>

      Action Number:
<input id="iftrueVal" class="round" type="text">

      On Timeout:

      <select id="iffalse" class="round" onchange="glob.onChangeFalse(this)">
        <option value="0">Continue Actions</option>
        <option value="1" selected>Stop Action Sequence</option>
        <option value="2">Jump To Action</option>
        <option value="3">Skip Next Actions</option>
        <option value="4">Jump to Anchor</option>
      </select>

      Action Number:
<input id="iffalseVal" class="round" type="text">

        Store Reaction List To:

        <select id="storage2" class="round" onchange="glob.variableChange(this, 'varNameContainer2')">
          ${data.variables[0]}
        </select>

        Variable Name:

        <input id="varName2" class="round" type="text">

`
  },

  init () {
    const { glob, document } = this

    glob.messageChange(document.getElementById('storage'), 'varNameContainer')

    glob.variableChange(document.getElementById('storage2'), 'varNameContainer2')
    glob.onChangeTrue = function (event) {
      switch (parseInt(event.value)) {
        case 0:
        case 1:
          document.getElementById('iftrueContainer').style.display = 'none'
          break
        case 2:
          document.getElementById('iftrueName').innerHTML = 'Action Number'
          document.getElementById('iftrueContainer').style.display = null
          break
        case 3:
          document.getElementById('iftrueName').innerHTML = 'Number of Actions to Skip'
          document.getElementById('iftrueContainer').style.display = null
          break
        case 4:
          document.getElementById('iftrueName').innerHTML = 'Anchor ID'
          document.getElementById('iftrueContainer').style.display = null
          break
      }
    }
    glob.onChangeFalse = function (event) {
      switch (parseInt(event.value)) {
        case 0:
        case 1:
          document.getElementById('iffalseContainer').style.display = 'none'
          break
        case 2:
          document.getElementById('iffalseName').innerHTML = 'Action Number'
          document.getElementById('iffalseContainer').style.display = null
          break
        case 3:
          document.getElementById('iffalseName').innerHTML = 'Number of Actions to Skip'
          document.getElementById('iffalseContainer').style.display = null
          break
        case 4:
          document.getElementById('iffalseName').innerHTML = 'Anchor ID'
          document.getElementById('iffalseContainer').style.display = null
          break
      }
    }
    glob.onChangeTrue(document.getElementById('iftrue'))
    glob.onChangeFalse(document.getElementById('iffalse'))
  },

  action (cache) {
    const data = cache.actions[cache.index]
    const { Actions } = this.getDBM()

    const message = parseInt(data.storage)
    const varName = this.evalMessage(data.varName, cache)
    const msg = this.getMessage(message, varName, cache)

    const storage = parseInt(data.storage2)
    const varName2 = this.evalMessage(data.varName2, cache)

    if (msg) {
      const js = String(this.evalMessage(data.filter, cache))

      const max = parseInt(this.evalMessage(data.max, cache))
      const maxEmojis = parseInt(this.evalMessage(data.maxEmojis, cache))
      const maxUsers = parseInt(this.evalMessage(data.maxUsers, cache))
      const time = parseInt(this.evalMessage(data.time, cache))

      msg.awaitReactions((reaction, user) => {
        const { msg: message, server } = cache
        const { author } = message
        let member
        const tempVars = Actions.getActionVariable.bind(cache.temp)
        const globalVars = Actions.getActionVariable.bind(Actions.global)
        let serverVars = null

        if (message) member = message.member
        if (cache.server) serverVars = Actions.getActionVariable.bind(Actions.server[server.id])

        try {
          return !!eval(js)
        } catch {
          return false
        }
      }, {
        max,
        maxEmojis,
        maxUsers,
        time,
        errors: ['time']
      })
        .then((c) => {
          this.storeValue(c.size === 1 ? c.first() : c.array(), storage, varName2, cache)
          this.executeResults(true, data, cache)
        })
        .catch(() => this.executeResults(false, data, cache))
    }
  },

  mod () {}
}
<commit_msg>Fix Await Reaction not working in events (#730)<commit_after>/* eslint-disable no-unused-vars */
module.exports = {
  name: 'Await Reaction Call Action',
  displayName: 'Await Reaction',
  section: 'Messaging',

  subtitle ({ max, time }) {
    const getPlural = (n) => (n !== '1' ? 's' : '')
    return `Await ${max} reaction${getPlural(max)} for ${time} millisecond${getPlural(time)}`
  },

  variableStorage (data, varType) {
    if (parseInt(data.storage2) !== varType) return
    return [data.varName2, `Reaction${parseInt(data.max) === 1 ? '' : ' List'}`]
  },

  fields: ['storage', 'varName', 'filter', 'max', 'time', 'maxEmojis', 'maxUsers', 'iftrue', 'iftrueVal', 'iffalse', 'iffalseVal', 'storage2', 'varName2'],

  html (isEvent, data) {
    return `

      Filter Examples:

          Available variables:

author // The command author

server // Guild where the command was used

          Message variables (Message that is being awaited):

author // The message author

msg // The message object

reaction // The reaction that was added

user // The user that reacted

          Reaction Examples:

reaction.emoji.name === '👌'

['👍', '👎'].includes(reaction.emoji.name)

reaction.emoji.id === '514136831793823756'

reaction.emoji.id // Take any response

          Author Examples:

author.id === '123467823521843898'

author.username === 'Clyde'

author.tag === 'Clyde#0000'

author.id === user.id

          Reaction + Author examples:

reaction.emoji.name === '👍' && author.id === user.id // Take a 👍 reaction from the command message author

reaction.emoji.name === '👍' && author.id === tempVars('some variable') // Take a 👍 reaction from a member with an ID stored in a temp variable

          JavaScript Comparison and Logical Operators

      Source Message:

      <select id="storage" class="round" onchange="glob.messageChange(this, 'varNameContainer')">
        ${data.messages[isEvent ? 1 : 0]}
      </select>

      Variable Name:

      <input id="varName" class="round" type="text" list="variableList">

    JavaScript Filter Eval: (JavaScript Strings)

    <input id="filter" class="round" type="text" value="reaction.emoji.name === '👌' && author.id === user.id">

    Max Reactions:

    <input id="max" class="round" type="text" value="1" placeholder="Optional">

    Max Time (milliseconds):

    <input id="time" class="round" type="text" value="60000" placeholder="Optional">

    Max Emojis:

    <input id="maxEmojis" class="round" type="text" placeholder="Optional">

    Max Users:

    <input id="maxUsers" class="round" type="text" placeholder="Optional">

      On Respond:

      <select id="iftrue" class="round" onchange="glob.onChangeTrue(this)">
        <option value="0" selected>Continue Actions</option>
        <option value="1">Stop Action Sequence</option>
        <option value="2">Jump To Action</option>
        <option value="3">Skip Next Actions</option>
        <option value="4">Jump to Anchor</option>
      </select>

      Action Number:
<input id="iftrueVal" class="round" type="text">

      On Timeout:

      <select id="iffalse" class="round" onchange="glob.onChangeFalse(this)">
        <option value="0">Continue Actions</option>
        <option value="1" selected>Stop Action Sequence</option>
        <option value="2">Jump To Action</option>
        <option value="3">Skip Next Actions</option>
        <option value="4">Jump to Anchor</option>
      </select>

      Action Number:
<input id="iffalseVal" class="round" type="text">

        Store Reaction List To:

        <select id="storage2" class="round" onchange="glob.variableChange(this, 'varNameContainer2')">
          ${data.variables[0]}
        </select>

        Variable Name:

        <input id="varName2" class="round" type="text">

`
  },

  init () {
    const { glob, document } = this

    glob.messageChange(document.getElementById('storage'), 'varNameContainer')

    glob.variableChange(document.getElementById('storage2'), 'varNameContainer2')
    glob.onChangeTrue = function (event) {
      switch (parseInt(event.value)) {
        case 0:
        case 1:
          document.getElementById('iftrueContainer').style.display = 'none'
          break
        case 2:
          document.getElementById('iftrueName').innerHTML = 'Action Number'
          document.getElementById('iftrueContainer').style.display = null
          break
        case 3:
          document.getElementById('iftrueName').innerHTML = 'Number of Actions to Skip'
          document.getElementById('iftrueContainer').style.display = null
          break
        case 4:
          document.getElementById('iftrueName').innerHTML = 'Anchor ID'
          document.getElementById('iftrueContainer').style.display = null
          break
      }
    }
    glob.onChangeFalse = function (event) {
      switch (parseInt(event.value)) {
        case 0:
        case 1:
          document.getElementById('iffalseContainer').style.display = 'none'
          break
        case 2:
          document.getElementById('iffalseName').innerHTML = 'Action Number'
          document.getElementById('iffalseContainer').style.display = null
          break
        case 3:
          document.getElementById('iffalseName').innerHTML = 'Number of Actions to Skip'
          document.getElementById('iffalseContainer').style.display = null
          break
        case 4:
          document.getElementById('iffalseName').innerHTML = 'Anchor ID'
          document.getElementById('iffalseContainer').style.display = null
          break
      }
    }
    glob.onChangeTrue(document.getElementById('iftrue'))
    glob.onChangeFalse(document.getElementById('iffalse'))
  },

  action (cache) {
    const data = cache.actions[cache.index]
    const { Actions } = this.getDBM()

    const message = parseInt(data.storage)
    const varName = this.evalMessage(data.varName, cache)
    const msg = this.getMessage(message, varName, cache)

    const storage = parseInt(data.storage2)
    const varName2 = this.evalMessage(data.varName2, cache)

    if (msg) {
      const js = String(this.evalMessage(data.filter, cache))

      const max = parseInt(this.evalMessage(data.max, cache))
      const maxEmojis = parseInt(this.evalMessage(data.maxEmojis, cache))
      const maxUsers = parseInt(this.evalMessage(data.maxUsers, cache))
      const time = parseInt(this.evalMessage(data.time, cache))

      msg.awaitReactions((reaction, user) => {
        const { msg: message, server } = cache
        let member
        let author
        const tempVars = Actions.getActionVariable.bind(cache.temp)
        const globalVars = Actions.getActionVariable.bind(Actions.global)
        let serverVars = null

        if (message) {
          member = message.member
          author = message.author
        }
        if (server) serverVars = Actions.getActionVariable.bind(Actions.server[server.id])

        try {
          return !!eval(js)
        } catch {
          return false
        }
      }, {
        max,
        maxEmojis,
        maxUsers,
        time,
        errors: ['time']
      })
        .then((c) => {
          this.storeValue(c.size === 1 ? c.first() : c.array(), storage, varName2, cache)
          this.executeResults(true, data, cache)
        })
        .catch(() => this.executeResults(false, data, cache))
    }
  },

  mod () {}
}
<|endoftext|>


<commit_before>const React = require('react');

const CompLibrary = require('../../core/CompLibrary.js');
const MarkdownBlock = CompLibrary.MarkdownBlock; /* Used to read markdown */
const Container = CompLibrary.Container;
const GridBlock = CompLibrary.GridBlock;

const siteConfig = require(process.cwd() + '/siteConfig.js');

function imgUrl(img) {
  return siteConfig.baseUrl + 'img/' + img;
}

function docUrl(doc) {
  return siteConfig.baseUrl + 'docs/' + doc;
}

function pageUrl(page) {
  return siteConfig.baseUrl + page;
}

const FeatureCallout = props => (

Features:

Fast, smooth scrolling and zooming. Explore your genome with unparalleled speed.

Scales easily to multi-gigabase genomes and deep-coverage sequencing.

Quickly open and view data files on your computer without uploading them to any server.

Supports GFF3, BED, FASTA, Wiggle, BigWig, BAM, CRAM, VCF (with either .tbi or .idx index), REST, and more.  BAM, BigBed, BigWig, and VCF data are displayed directly from chunks of the compressed binary files, no conversion needed.

Includes an optional “faceted” track selector (see demo) suitable for large installations with thousands of tracks.

Very light server resource requirements. In fact, JBrowse has no back-end server code, it just reads chunks of files directly over HTTP using byte-range requests. You can serve huge datasets from a single low-cost cloud instance.

JBrowse Desktop runs as a stand-alone app on Windows, Mac OS, and Linux.

Highly extensible plugin architecture, with a large registry of plugins.

);

const BrowserCompat = props => (

Browser Compatibility

The latest release of JBrowse is tested to work with the following web browsers:

Mozilla Firefox (10 and later)

Google Chrome (17 and later)

Apple Safari (9 and later)

Microsoft Internet Explorer (11 and later)

Server-side code, which is used only to pre-generate static data files (no CGI), requires only BioPerl and a few other CPAN modules. The result is a cross-platform AJAX genome browser that is easy to install, embed and customize.

JBrowse is a GMOD project.

);

const ExtraInfo = props => (

Funding

JBrowse development is funded by the NHGRI.

Citing JBrowse

If you use JBrowse in a project that you publish, please cite the most recent JBrowse paper listed on the References page

License

JBrowse is released under the GNU LGPL or the Artistic License, see the JBrowse LICENSE file.

)

const HeaderInfo = props => (

The JBrowse Genome Browser

JBrowse is a fast, scalable genome browser built completely with JavaScript and HTML5. It can run on your desktop, or be embedded in your website.

    Download latest release – JBrowse {siteConfig.latestVersion}

)

class Index extends React.Component {
  render() {
    let language = this.props.language || '';
    return (
      <Container className="mainContainer documentContainer postContainer">

            <HeaderInfo />

              <FeatureCallout />
              <BrowserCompat />
              <ExtraInfo />

              Tweets by JBrowseGossip

      </Container>
    );
  }
}

module.exports = Index;
<commit_msg>[update docs] Fix the demo instance<commit_after>const React = require('react');

const CompLibrary = require('../../core/CompLibrary.js');
const MarkdownBlock = CompLibrary.MarkdownBlock; /* Used to read markdown */
const Container = CompLibrary.Container;
const GridBlock = CompLibrary.GridBlock;

const siteConfig = require(process.cwd() + '/siteConfig.js');

function imgUrl(img) {
  return siteConfig.baseUrl + 'img/' + img;
}

function docUrl(doc) {
  return siteConfig.baseUrl + 'docs/' + doc;
}

function pageUrl(page) {
  return siteConfig.baseUrl + page;
}

const FeatureCallout = props => (

Features:

Fast, smooth scrolling and zooming. Explore your genome with unparalleled speed.

Scales easily to multi-gigabase genomes and deep-coverage sequencing.

Quickly open and view data files on your computer without uploading them to any server.

Supports GFF3, BED, FASTA, Wiggle, BigWig, BAM, CRAM, VCF (with either .tbi or .idx index), REST, and more.  BAM, BigBed, BigWig, and VCF data are displayed directly from chunks of the compressed binary files, no conversion needed.

Includes an optional “faceted” track selector (see demo) suitable for large installations with thousands of tracks.

Very light server resource requirements. In fact, JBrowse has no back-end server code, it just reads chunks of files directly over HTTP using byte-range requests. You can serve huge datasets from a single low-cost cloud instance.

JBrowse Desktop runs as a stand-alone app on Windows, Mac OS, and Linux.

Highly extensible plugin architecture, with a large registry of plugins.

);

const BrowserCompat = props => (

Browser Compatibility

The latest release of JBrowse is tested to work with the following web browsers:

Mozilla Firefox (10 and later)

Google Chrome (17 and later)

Apple Safari (9 and later)

Microsoft Internet Explorer (11 and later)

Server-side code, which is used only to pre-generate static data files (no CGI), requires only BioPerl and a few other CPAN modules. The result is a cross-platform AJAX genome browser that is easy to install, embed and customize.

JBrowse is a GMOD project.

);

const ExtraInfo = props => (

Funding

JBrowse development is funded by the NHGRI.

Citing JBrowse

If you use JBrowse in a project that you publish, please cite the most recent JBrowse paper listed on the References page

License

JBrowse is released under the GNU LGPL or the Artistic License, see the JBrowse LICENSE file.

)

const HeaderInfo = props => (

The JBrowse Genome Browser

JBrowse is a fast, scalable genome browser built completely with JavaScript and HTML5. It can run on your desktop, or be embedded in your website.

    Download latest release – JBrowse {siteConfig.latestVersion}

)

class Index extends React.Component {
  render() {
    let language = this.props.language || '';
    return (
      <Container className="mainContainer documentContainer postContainer">

            <HeaderInfo />

              <FeatureCallout />
              <BrowserCompat />
              <ExtraInfo />

              Tweets by JBrowseGossip

      </Container>
    );
  }
}

module.exports = Index;
<|endoftext|>


<commit_before>'use strict';

let $ = require('jQuery');

const {
  NSAppCrawlingTreeNodeAction,
  NSAppCrawlingTreeNode
} = require('./models');

function NSCrawler(config, sessionId) {
  this.config = config;                     // Config in format of NSCrawlerConfig
  this.sessionId = sessionId;                  // Session Id
  this.crawlingBuffer = [];                         // The set of notes
  this.currentNode = null;                       // Current node which is in crawling
  this.repeatingCrawlingCount = 0;                  // When exceed 3, whole program exists
  this.crawlingExpires = false;                     // Flag to indicate whether a crawling expires
}

NSCrawler.prototype.initialize = function() {

  setTimeout(() => {
    this.crawlingExpires = true;
  }, this.config.testingPeriod * 1000);
  return this;
};

NSCrawler.prototype.explore = function(source) {
  let node = new NSAppCrawlingTreeNode();
  node.checkDigest().then(() => {
    // 1. Check if there is an existing node
    for (let index in this.crawlingBuffer) {
      if(this.crawlingBuffer[index] && this.crawlingBuffer[index].digest === node.digest) {
        this.currentNode = this.crawlingBuffer[index];
        // Check about current node related
        if (this.currentNode.isFinishedBrowseing()) {
          // Perform 'back' and craw again
          this.repeatingCrawlingCount++;
          window.wdclient.send(`/wd/hub/session/${this.sessionId}/back`, 'post', {}, null).then(() => {
            this.crawl();
          });
        } else {
          this.performAction();
          setTimeout(this.crawl.bind(this), this.config.newCommandTimeout * 1000);
        }
        return;
      }
    }

    this.repeatingCrawlingCount = 0;

    // 2. Initialize an new node
    node.parent = this.currentNode;
    this.currentNode = node;

    let matches = this.recursiveFilter(source.value, this.config.targetElements, this.config.exclusivePattern);
    if (matches.length) {
      this.currentNode.actions = produceNodeActions(matches);
    } else {
      let elements = this.recursiveFilter(source.value, null, this.config.exclusivePattern);
      this.currentNode.actions = produceNodeActions(elements);
    }

    if (this.currentNode.actions.length > this.config.maxActionPerPage) {
      this.currentNode.actions = this.currentNode.actions.slice(0,this.config.maxActionPerPage+1);
    }

    this.currentNode.sortActionPriority();
    this.crawlingBuffer.push(node);
    this.performAction();
    setTimeout(this.crawl.bind(this), this.config.newCommandTimeout * 1000);
  });
};

// Perform Node Actions
NSCrawler.prototype.performAction = function() {
  let that = this;
  window.wdclient
    .send(`/wd/hub/session/${this.sessionId}/source`, `get`, null, null)
    .then(() => {
      for (let i = 0; i < that.currentNode.actions.length; i++) {
        let action = that.currentNode.actions[i];
        if (!action.isTriggered) {
          action.isTriggered = true;
          console.log(JSON.stringify(action.source));

          window.wdclient
            .send(`/wd/hub/session/${this.sessionId}/element`, `post`, {
              using: 'xpath',
              value: action.location
            }, null)
            .then(data => {
              if (data.status === 0) {
                switch (action.source.type) {
                  case 'Button':
                  case 'Cell':
                    window.wdclient
                      .send(`/wd/hub/session/${this.sessionId}/actions`, `post`, {
                        actions: [{
                          type: 'tap',
                          x: action.source.rect.x,
                          y: action.source.rect.y
                        }]
                      }, null)
                      .then(() => {
                        this.refreshScreen();
                      });
                    break;
                  case 'PageIndicator':
                    window.wdclient
                      .send(`/wd/hub/session/${this.sessionId}/dragfromtoforduration`,`post`, {
                        fromX: 10,
                        fromY: 200,
                        toX: 300,
                        toY: 200,
                        duration: 2.00
                      }, null)
                      .then(() => {
                        this.refreshScreen();
                      });
                    break;
                  case 'TextField':
                  case 'SecureTextField':
                    window.wdclient
                      .send(`/wd/hub/session/${this.sessionId}/element/${data.value.ELEMENT}/value`,`post`, {
                        'value': [action.input]
                      }, null)
                      .then(() => {
                        this.refreshScreen();
                      });
                    break;
                  default:
                    break;
                }
              }
            });
          return;
        }
      }
    });
};

NSCrawler.prototype.crawl = function () {

  // Terminate under the following cases:
  // 1. the previous node has been finished for continuously count of 5, assume crawling finish
  // 2. the crawling process takes too long and hence expire
  if (this.repeatingCrawlingCount >= 5 || this.crawlingExpires) {
    console.log('-----> Crawling Finished <-----');
    return;
  }

  window.wdclient.send(`/wd/hub/session/${this.sessionId}/dismiss_alert`, 'post', {}, null).then(() => {
    window.wdclient
      .send(`/wd/hub/session/${this.sessionId}/source`, `get`, null, null)
      .then((data)  => {
        this.explore(data);
      });
  });
};

// If match is null or empty, put all elements which belongs to button, label,
NSCrawler.prototype.recursiveFilter = function (source, matches, exclusive) {
  let sourceArray = [];

  for (let key in source) {
    // filter out nav-bar element, avoid miss back operation
    if (source.type === 'NavigationBar') {
      continue;
    }

    if (source.hasOwnProperty(key)) {
      if (key === 'children') {
        for (let i = 0; i < source[key].length; i++) {
          this.insertXPath(source, source[key][i]);
          let result = this.recursiveFilter(source[key][i], matches, exclusive);
          sourceArray = sourceArray.concat(result);
        }
      } else if (source[key] !== null) {
        if (matches) {
          // Explicit mode
          for (let match in matches) {
            if ((source.value && source.value === match) ||
              (source.name && source.name === match)     ||
              (source.label && source.label === match)) {
              source.input = matches[match].actionValue;
              return [source];
            }
          }
        } else {
          // If the source value/name/label matches the exclusive pattern, avoid recording
          if ((exclusive) && ((source.value && exclusive.includes(source.value)) ||
            (source.name && exclusive.includes(source.name))   ||
            (source.label && exclusive.includes(source.label)))) {
            return [];
          }

          if (source.type) {
            switch (source.type) {
              case 'StaticText':
              case 'Button':
              case 'Cell':
              case 'PageIndicator':
                sourceArray.push(source);
                return sourceArray;
              case 'TextField':
              case 'SecureTextField':
                source.input = 'random+123';
                sourceArray.push(source);
                return sourceArray;
              default:
            }
          }
        }
      }
    }
  }
  return sourceArray;
}

NSCrawler.prototype.checkPathIndex = function (parent, child) {
  let currentTypeCount = child.type + '_count';

  if (!parent[currentTypeCount]) {
    for (let i = 0; i < parent.children.length; i++) {
      currentTypeCount = parent.children[i].type + '_count';
      if (!parent[currentTypeCount]) {
        parent[currentTypeCount] = 1;
      } else {
        parent[currentTypeCount]++;
      }
      parent.children[i].pathInParent = parent[currentTypeCount];
    }
  }
}

// Parent must be an array of child elements
NSCrawler.prototype.insertXPath = function (parent, child) {
  let prefix = this.config.platform === 'iOS' ? 'XCUIElementType' : '';
  this.checkPathIndex(parent, child);
  let currentIndex = child.pathInParent;
  child.xpath = (parent.xpath ? parent.xpath : '//' + prefix + 'Application[1]')+ '/' + prefix + child.type + '[' + currentIndex + ']';
}

function produceNodeActions(rawElements) {
  let actions = [];
  for (let index in rawElements) {
    let rawElement = rawElements[index];
    let action;

    switch (rawElement.type) {
      case 'StaticText':
      case 'Button':
      case 'Cell':
      case 'PageIndicator':
        action = new NSAppCrawlingTreeNodeAction();
        action.source = rawElement;
        action.location = rawElement.xpath;
        actions.push(action);
        break;
      case 'TextField':
      case 'SecureTextField':
        action = new NSAppCrawlingTreeNodeAction();
        action.source = rawElement;
        action.location = rawElement.xpath;
        action.input = rawElement.input;
        actions.push(action);
        break;
      default:
    }
  }
  return actions;
}

NSCrawler.prototype.refreshScreen = function () {
  window.wdclient.send(`/wd/hub/session/${this.sessionId}/screenshot`, 'get', null, function(data) {
    let base64 = `data:image/jpg;base64,${data.value}`;
    $('#screen').attr('src', base64);
  });
}

exports.NSCrawler = NSCrawler;
<commit_msg>bug fix and run through crawler<commit_after>'use strict';

let $ = require('jQuery');

const {
  NSAppCrawlingTreeNodeAction,
  NSAppCrawlingTreeNode
} = require('./models');

function NSCrawler(config, sessionId) {
  this.config = config;                     // Config in format of NSCrawlerConfig
  this.sessionId = sessionId;                  // Session Id
  this.crawlingBuffer = [];                         // The set of notes
  this.currentNode = null;                       // Current node which is in crawling
  this.repeatingCrawlingCount = 0;                  // When exceed 3, whole program exists
  this.crawlingExpires = false;                     // Flag to indicate whether a crawling expires
}

NSCrawler.prototype.initialize = function() {

  setTimeout(() => {
    this.crawlingExpires = true;
  }, this.config.testingPeriod * 1000);
  return this;
};

NSCrawler.prototype.explore = function(source) {
  let node = new NSAppCrawlingTreeNode();
  node.checkDigest().then(() => {
    // 1. Check if there is an existing node
    for (let index in this.crawlingBuffer) {
      if(this.crawlingBuffer[index] && this.crawlingBuffer[index].digest === node.digest) {
        this.currentNode = this.crawlingBuffer[index];
        // Check about current node related
        if (this.currentNode.isFinishedBrowseing()) {
          // Perform 'back' and craw again
          this.repeatingCrawlingCount++;
          window.wdclient.send(`/wd/hub/session/${this.sessionId}/back`, 'post', {}, null).then(() => {
            this.crawl();
          });
        } else {
          this.performAction();
          setTimeout(this.crawl.bind(this), this.config.newCommandTimeout * 1000);
        }
        return;
      }
    }

    this.repeatingCrawlingCount = 0;

    // 2. Initialize an new node
    node.parent = this.currentNode;
    this.currentNode = node;

    let matches = this.recursiveFilter(JSON.parse(source.value), this.config.targetElements, this.config.exclusivePattern);
    if (matches.length) {
      this.currentNode.actions = produceNodeActions(matches);
    } else {
      let elements = this.recursiveFilter(JSON.parse(source.value), null, this.config.exclusivePattern);
      this.currentNode.actions = produceNodeActions(elements);
    }

    if (this.currentNode.actions.length > this.config.maxActionPerPage) {
      this.currentNode.actions = this.currentNode.actions.slice(0,this.config.maxActionPerPage+1);
    }

    this.currentNode.sortActionPriority();
    this.crawlingBuffer.push(node);
    this.performAction();
    setTimeout(this.crawl.bind(this), this.config.newCommandTimeout * 1000);
  });
};

// Perform Node Actions
NSCrawler.prototype.performAction = function() {
  let that = this;
  window.wdclient
    .send(`/wd/hub/session/${this.sessionId}/source`, `get`, null, null)
    .then(() => {
      for (let i = 0; i < that.currentNode.actions.length; i++) {
        let action = that.currentNode.actions[i];
        if (!action.isTriggered) {
          action.isTriggered = true;
          console.log(JSON.stringify(action.source));

          window.wdclient
            .send(`/wd/hub/session/${this.sessionId}/element`, `post`, {
              using: 'xpath',
              value: action.location
            }, null)
            .then(data => {
              if (data.status === 0) {
                switch (action.source.type) {
                  case 'Button':
                  case 'Cell':
                    window.wdclient
                      .send(`/wd/hub/session/${this.sessionId}/actions`, `post`, {
                        actions: [{
                          type: 'tap',
                          x: action.source.rect.x,
                          y: action.source.rect.y
                        }]
                      }, null)
                      .then(() => {
                        this.refreshScreen();
                      });
                    break;
                  case 'PageIndicator':
                    window.wdclient
                      .send(`/wd/hub/session/${this.sessionId}/dragfromtoforduration`,`post`, {
                        fromX: 10,
                        fromY: 200,
                        toX: 300,
                        toY: 200,
                        duration: 2.00
                      }, null)
                      .then(() => {
                        this.refreshScreen();
                      });
                    break;
                  case 'TextField':
                  case 'SecureTextField':
                    window.wdclient
                      .send(`/wd/hub/session/${this.sessionId}/element/${data.value.ELEMENT}/value`,`post`, {
                        'value': [action.input]
                      }, null)
                      .then(() => {
                        this.refreshScreen();
                      });
                    break;
                  default:
                    break;
                }
              }
            });
          return;
        }
      }
    });
};

NSCrawler.prototype.crawl = function () {

  // Terminate under the following cases:
  // 1. the previous node has been finished for continuously count of 5, assume crawling finish
  // 2. the crawling process takes too long and hence expire
  if (this.repeatingCrawlingCount >= 5 || this.crawlingExpires) {
    console.log('-----> Crawling Finished <-----');
    return;
  }

  window.wdclient.send(`/wd/hub/session/${this.sessionId}/dismiss_alert`, 'post', {}, null).then(() => {
    window.wdclient
      .send(`/wd/hub/session/${this.sessionId}/source`, `get`, null, null)
      .then((data)  => {
        this.explore(data);
      });
  });
};

// If match is null or empty, put all elements which belongs to button, label,
NSCrawler.prototype.recursiveFilter = function (source, matches, exclusive) {
  let sourceArray = [];

  for (let key in source) {
    // filter out nav-bar element, avoid miss back operation
    if (source.type === 'NavigationBar') {
      continue;
    }

    if (source.hasOwnProperty(key)) {
      if (key === 'children') {
        for (let i = 0; i < source[key].length; i++) {
          this.insertXPath(source, source[key][i]);
          let result = this.recursiveFilter(source[key][i], matches, exclusive);
          sourceArray = sourceArray.concat(result);
        }
      } else if (source[key] !== null) {
        if (matches) {
          // Explicit mode
          for (let match in matches) {
            if ((source.value && source.value === match) ||
              (source.name && source.name === match)     ||
              (source.label && source.label === match)) {
              source.input = matches[match].actionValue;
              return [source];
            }
          }
        } else {
          // If the source value/name/label matches the exclusive pattern, avoid recording
          if ((exclusive) && ((source.value && exclusive.includes(source.value)) ||
            (source.name && exclusive.includes(source.name))   ||
            (source.label && exclusive.includes(source.label)))) {
            return [];
          }

          if (source.type) {
            switch (source.type) {
              case 'StaticText':
              case 'Button':
              case 'Cell':
              case 'PageIndicator':
                sourceArray.push(source);
                return sourceArray;
              case 'TextField':
              case 'SecureTextField':
                source.input = 'random+123';
                sourceArray.push(source);
                return sourceArray;
              default:
            }
          }
        }
      }
    }
  }
  return sourceArray;
}

NSCrawler.prototype.checkPathIndex = function (parent, child) {
  let currentTypeCount = child.type + '_count';

  if (!parent[currentTypeCount]) {
    for (let i = 0; i < parent.children.length; i++) {
      currentTypeCount = parent.children[i].type + '_count';
      if (!parent[currentTypeCount]) {
        parent[currentTypeCount] = 1;
      } else {
        parent[currentTypeCount]++;
      }
      parent.children[i].pathInParent = parent[currentTypeCount];
    }
  }
}

// Parent must be an array of child elements
NSCrawler.prototype.insertXPath = function (parent, child) {
  let prefix = this.config.platform === 'iOS' ? 'XCUIElementType' : '';
  this.checkPathIndex(parent, child);
  let currentIndex = child.pathInParent;
  child.xpath = (parent.xpath ? parent.xpath : '//' + prefix + 'Application[1]')+ '/' + prefix + child.type + '[' + currentIndex + ']';
}

function produceNodeActions(rawElements) {
  let actions = [];
  for (let index in rawElements) {
    let rawElement = rawElements[index];
    let action;

    switch (rawElement.type) {
      case 'StaticText':
      case 'Button':
      case 'Cell':
      case 'PageIndicator':
        action = new NSAppCrawlingTreeNodeAction();
        action.source = rawElement;
        action.location = rawElement.xpath;
        actions.push(action);
        break;
      case 'TextField':
      case 'SecureTextField':
        action = new NSAppCrawlingTreeNodeAction();
        action.source = rawElement;
        action.location = rawElement.xpath;
        action.input = rawElement.input;
        actions.push(action);
        break;
      default:
    }
  }
  return actions;
}

NSCrawler.prototype.refreshScreen = function () {
  window.wdclient.send(`/wd/hub/session/${this.sessionId}/screenshot`, 'get', null, function(data) {
    let base64 = `data:image/jpg;base64,${data.value}`;
    $('#screen').attr('src', base64);
  });
}

exports.NSCrawler = NSCrawler;
<|endoftext|>


<commit_before>import SPELLS from 'common/SPELLS';
import ITEMS from 'common/ITEMS';
import React from 'react';

import Analyzer from 'Parser/Core/Analyzer';
import Combatants from 'Parser/Core/Modules/Combatants';

class HighfathersMachination extends Analyzer {
  static dependencies = {
      combatants: Combatants,
  };
  healing = 0;
  procUsed = 0;
  totalProc = 0;

  on_initialized() {
    this.active = this.combatants.selected.hasTrinket(ITEMS.HIGHFATHERS_MACHINATION.id);
  }

  on_byPlayer_heal(event) {
    const spellId = event.ability.guid;

    if (spellId === SPELLS.AMANTHULS_PRESENCEHEAL.id) {
      this.procUsed++;
      this.healing += (event.amount || 0) + (event.absorbed || 0);
    }
  }

  on_byPlayer_applybuff(event) {
      const spellId = event.ability.guid;
      if (spellId === SPELLS.AMANTHULS_PRESENCEBUFF.id) {
          this.totalProc++;
      }
  }

  on_byPlayer_applybuffstack(event) {
      const spellId = event.ability.guid;
      if (spellId === SPELLS.AMANTHULS_PRESENCEBUFF.id) {
          this.totalProc++;
      }
  }

  item() {
    return {
      item: ITEMS.HIGHFATHERS_MACHINATION,
      result: (
        <dfn data-tip={`The trinket applied a total of ${this.totalProc} healing stacks. ${this.procUsed} stacks were used to heal a total amount of ${this.healing}. ${this.totalProc - this.procUsed} stacks wasted.`}>
        {this.owner.formatItemHealingDone(this.healing)}
        </dfn>),
    };
  }
}

export default HighfathersMachination;
<commit_msg>Update HighfathersMachination.js<commit_after>import SPELLS from 'common/SPELLS';
import ITEMS from 'common/ITEMS';
import React from 'react';
import { formatNumber } from 'common/format';
import Analyzer from 'Parser/Core/Analyzer';
import Combatants from 'Parser/Core/Modules/Combatants';

class HighfathersMachination extends Analyzer {
  static dependencies = {
      combatants: Combatants,
  };
  healing = 0;
  procUsed = 0;
  totalProc = 0;

  on_initialized() {
    this.active = this.combatants.selected.hasTrinket(ITEMS.HIGHFATHERS_MACHINATION.id);
  }

  on_byPlayer_heal(event) {
    const spellId = event.ability.guid;

    if (spellId === SPELLS.AMANTHULS_PRESENCEHEAL.id) {
      this.procUsed++;
      this.healing += (event.amount || 0) + (event.absorbed || 0);
    }
  }

  on_byPlayer_applybuff(event) {
      const spellId = event.ability.guid;
      if (spellId === SPELLS.AMANTHULS_PRESENCEBUFF.id) {
          this.totalProc++;
      }
  }

  on_byPlayer_applybuffstack(event) {
      const spellId = event.ability.guid;
      if (spellId === SPELLS.AMANTHULS_PRESENCEBUFF.id) {
          this.totalProc++;
      }
  }

  item() {
    return {
      item: ITEMS.HIGHFATHERS_MACHINATION,
      result: (
        <dfn data-tip={`The trinket applied a total of ${this.totalProc} healing stacks.
${this.procUsed} stacks were used to heal a total amount of ${formatNumber(this.healing)}.
${this.totalProc - this.procUsed} stacks wasted.`}>
        {this.owner.formatItemHealingDone(this.healing)}
        </dfn>),
    };
  }
}

export default HighfathersMachination;
<|endoftext|>


<commit_before>/*
Copyright (c) 2009-2011, Dan "Ducky" Little & GeoMOOSE.org
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.
*/

dojo.require('dojo.fx');
dojo.require('dijit.layout.BorderContainer');
dojo.require('dijit.layout.TabContainer');
dojo.require('dojox.widget.Standby');

dojo.registerModulePath('GeoMOOSE', '../../../geomoose/GeoMOOSE');
dojo.require('GeoMOOSE.Popup');
dojo.require('GeoMOOSE.Application');

dojo.require('GeoMOOSE.Handler.Box');
dojo.require('GeoMOOSE.Handler.MeasurePath');
dojo.require('GeoMOOSE.Control.Measure');
dojo.require('GeoMOOSE.Control.DeleteFeature');

dojo.require('GeoMOOSE.Dialog.AttributeEditor');
dojo.require('GeoMOOSE.Dialog.Download');

dojo.require('GeoMOOSE.MapSource');
dojo.require('GeoMOOSE.MapSource.Vector');
dojo.require('GeoMOOSE.MapSource.Vector.WFS');

dojo.require('GeoMOOSE.MapSource.WMS');
dojo.require('GeoMOOSE.MapSource.MapServer');
dojo.require('GeoMOOSE.MapSource.TMS');
dojo.require('GeoMOOSE.MapSource.XYZ');
dojo.require('GeoMOOSE.MapSource.Google');
dojo.require('GeoMOOSE.MapSource.Yahoo');
dojo.require('GeoMOOSE.MapSource.AGS');

dojo.require('GeoMOOSE.Tab');
dojo.require('GeoMOOSE.Tab.Service');
dojo.require('GeoMOOSE.Tab.Catalog');
dojo.require('GeoMOOSE.Tab.Catalog.LayerControl');
dojo.require('GeoMOOSE.Tab.Catalog.LayerControl.Activate');
dojo.require('GeoMOOSE.Tab.Catalog.LayerControl.Popups');
dojo.require('GeoMOOSE.Tab.Catalog.LayerControl.Up');
dojo.require('GeoMOOSE.Tab.Catalog.LayerControl.Fade');
dojo.require('GeoMOOSE.Tab.Catalog.LayerControl.Legend');

dojo.require('GeoMOOSE.ServiceManager');

dojo.require('GeoMOOSE.UI.Toolbar');
dojo.require('GeoMOOSE.Layout.Default');
dojo.require('GeoMOOSE.UI.CoordinateDisplay');
dojo.require('GeoMOOSE.UI.ScaleJumper');
dojo.require('GeoMOOSE.UI.ZoomTo');
dojo.require('GeoMOOSE.UI.LinksBar');

dojo.require('GeoMOOSE.Tool.MeasureArea');
<commit_msg>Removed Yahoo from requires<commit_after>/*
Copyright (c) 2009-2011, Dan "Ducky" Little & GeoMOOSE.org
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.
*/

dojo.require('dojo.fx');
dojo.require('dijit.layout.BorderContainer');
dojo.require('dijit.layout.TabContainer');
dojo.require('dojox.widget.Standby');

dojo.registerModulePath('GeoMOOSE', '../../../geomoose/GeoMOOSE');
dojo.require('GeoMOOSE.Popup');
dojo.require('GeoMOOSE.Application');

dojo.require('GeoMOOSE.Handler.Box');
dojo.require('GeoMOOSE.Handler.MeasurePath');
dojo.require('GeoMOOSE.Control.Measure');
dojo.require('GeoMOOSE.Control.DeleteFeature');

dojo.require('GeoMOOSE.Dialog.AttributeEditor');
dojo.require('GeoMOOSE.Dialog.Download');

dojo.require('GeoMOOSE.MapSource');
dojo.require('GeoMOOSE.MapSource.Vector');
dojo.require('GeoMOOSE.MapSource.Vector.WFS');

dojo.require('GeoMOOSE.MapSource.WMS');
dojo.require('GeoMOOSE.MapSource.MapServer');
dojo.require('GeoMOOSE.MapSource.TMS');
dojo.require('GeoMOOSE.MapSource.XYZ');
dojo.require('GeoMOOSE.MapSource.Google');
dojo.require('GeoMOOSE.MapSource.AGS');

dojo.require('GeoMOOSE.Tab');
dojo.require('GeoMOOSE.Tab.Service');
dojo.require('GeoMOOSE.Tab.Catalog');
dojo.require('GeoMOOSE.Tab.Catalog.LayerControl');
dojo.require('GeoMOOSE.Tab.Catalog.LayerControl.Activate');
dojo.require('GeoMOOSE.Tab.Catalog.LayerControl.Popups');
dojo.require('GeoMOOSE.Tab.Catalog.LayerControl.Up');
dojo.require('GeoMOOSE.Tab.Catalog.LayerControl.Fade');
dojo.require('GeoMOOSE.Tab.Catalog.LayerControl.Legend');

dojo.require('GeoMOOSE.ServiceManager');

dojo.require('GeoMOOSE.UI.Toolbar');
dojo.require('GeoMOOSE.Layout.Default');
dojo.require('GeoMOOSE.UI.CoordinateDisplay');
dojo.require('GeoMOOSE.UI.ScaleJumper');
dojo.require('GeoMOOSE.UI.ZoomTo');
dojo.require('GeoMOOSE.UI.LinksBar');

dojo.require('GeoMOOSE.Tool.MeasureArea');
<|endoftext|>


<commit_before>/* Puzzle input - check /input/day3.js */
var input = require('./input/day3.js');

/* Variables */
var santasVisits = [ [ 0, 0 ] ],
    coordX = 0,
    coordY = 0;

// Function to uniquify an array
function unique(array){
  var uniqueArray = array;

  for (var i = 0; i < array.length; i++) {
    if (uniqueArray.indexOf(array[i] !== -1)) {
      uniqueArray.splice(i, 1);
    };
  };

  return uniqueArray;
}

// For each character in puzzle input
for (var i = 0; i < input.length; i++) {
  var nextDirection = input[i];

  // Adjust coordinates on X and Y axis acoording to the direction characters
  if (nextDirection === '>') {
    // to east => X axis + 1
    coordX++;
  } else if (nextDirection === '<') {
    // to west => X axis - 1
    coordX--;
  } else if (nextDirection === '^') {
    // to north => Y axis + 1
    coordY++;
  } else if (nextDirection === 'v') {
    // to south => Y axis - 1
    coordY--;
  }

  // Store coordination pair
  var currentLocation = [coordX, coordY];
  // ... and push to santasVisits array
  santasVisits.push(currentLocation);
};

// Call unique() function to sort out duplicate visits
console.log(unique(santasVisits).length);
<commit_msg>Improve unique() function<commit_after>/* Puzzle input - check /input/day3.js */
var input = require('./input/day3.js');

/* Variables */
var santasVisits = [ [ 0, 0 ] ],
    coordX = 0,
    coordY = 0;

// Function to uniquify an array
function unique(array){
  var uniqueArray = [];

  for (var i = 0; i < array.length; i++) {
    if (uniqueArray.indexOf(array[i]) === -1) {
      uniqueArray.push(array[i]);
    }
  }

  return uniqueArray;
}

// For each character in puzzle input
for (var i = 0; i < input.length; i++) {
  var nextDirection = input[i];

  // Adjust coordinates on X and Y axis acoording to the direction characters
  if (nextDirection === '>') {
    // to east => X axis + 1
    coordX++;
  } else if (nextDirection === '<') {
    // to west => X axis - 1
    coordX--;
  } else if (nextDirection === '^') {
    // to north => Y axis + 1
    coordY++;
  } else if (nextDirection === 'v') {
    // to south => Y axis - 1
    coordY--;
  }

  // Store coordination pair
  var currentLocation = [coordX, coordY];
  // ... and push to santasVisits array
  santasVisits.push(currentLocation);
};

// Call unique() function to sort out duplicate visits
console.log(unique(santasVisits).length);
<|endoftext|>


<commit_before>import Widget from "./base_widget.js";

export default class OnboardingWidget extends Widget {
	constructor(opts) {
		super(opts);
	}

	make_body() {
		this.steps.forEach((step) => {
			this.add_step(step);
		});
	}

	add_step(step) {
		let $step = $(`

				${step.label}

`);

		$step.appendTo(this.body);
		return $step;
	}

	set_body() {
		this.widget.addClass("onboarding-widget-box");
		if (this.is_dismissed()) {
			this.widget.hide();
		} else {
			this.make_body();
		}
	}

	is_dismissed() {
		let dismissed = JSON.parse(localStorage.getItem("dismissed-onboarding")) || {};
		if (Object.keys(dismissed).includes(this.label)) {
			let last_hidden = new Date(dismissed[this.label]);
			let today = new Date();
			let diff = frappe.datetime.get_hour_diff(today, last_hidden)
			return diff < 24;
		}
		return false
	}

	set_title(title) {
		super.set_title(title);
		let subtitle = $(`<div class="widget-subtitle">${this.subtitle}</div>`);
		subtitle.appendTo(this.title_field);
	}

	set_actions() {
		this.action_area.empty();
		const dismiss = $(
			`<div class="small" style="cursor:pointer;">Dismiss</div>`
		);
		dismiss.on("click", () => {
			let dismissed = JSON.parse(localStorage.getItem("dismissed-onboarding")) || {};
			dismissed[this.label] = frappe.datetime.now_datetime();

			localStorage.setItem(
				"dismissed-onboarding",
				JSON.stringify(dismissed)
			);
			this.delete();
		});
		dismiss.appendTo(this.action_area);
	}
}<commit_msg>fix: default parameter for JSON Parse<commit_after>import Widget from "./base_widget.js";

export default class OnboardingWidget extends Widget {
	constructor(opts) {
		super(opts);
	}

	make_body() {
		this.steps.forEach((step) => {
			this.add_step(step);
		});
	}

	add_step(step) {
		let $step = $(`

				${step.label}

`);

		$step.appendTo(this.body);
		return $step;
	}

	set_body() {
		this.widget.addClass("onboarding-widget-box");
		if (this.is_dismissed()) {
			this.widget.hide();
		} else {
			this.make_body();
		}
	}

	is_dismissed() {
		let dismissed = JSON.parse(localStorage.getItem("dismissed-onboarding") || '{}');
		if (Object.keys(dismissed).includes(this.label)) {
			let last_hidden = new Date(dismissed[this.label]);
			let today = new Date();
			let diff = frappe.datetime.get_hour_diff(today, last_hidden)
			return diff < 24;
		}
		return false
	}

	set_title(title) {
		super.set_title(title);
		let subtitle = $(`<div class="widget-subtitle">${this.subtitle}</div>`);
		subtitle.appendTo(this.title_field);
	}

	set_actions() {
		this.action_area.empty();
		const dismiss = $(
			`<div class="small" style="cursor:pointer;">Dismiss</div>`
		);
		dismiss.on("click", () => {
			let dismissed = JSON.parse(localStorage.getItem("dismissed-onboarding") || '{}');
			dismissed[this.label] = frappe.datetime.now_datetime();

			localStorage.setItem(
				"dismissed-onboarding",
				JSON.stringify(dismissed)
			);
			this.delete();
		});
		dismiss.appendTo(this.action_area);
	}
}<|endoftext|>


<commit_before>/**
 * API function to create fetch store.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * 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
 *
 *     https://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.
 */

/**
 * External dependencies
 */
import invariant from 'invariant';

/**
 * Internal dependencies
 */
import { stringifyObject } from '../../util';

/**
 * Creates a store object implementing the necessary infrastructure for a
 * single fetch action.
 *
 * This function returns a partial store object with the following:
 * * action creators to fetch and to receive the data
 * * control to issue the API request
 * * reducer to set API request flag and receive the response
 * * selector to check whether the API request is in progress via flag
 *
 * The names of the pieces are based on the baseName provided.
 * For example, if baseName is 'saveSettings':
 * * The fetch action creator is called 'fetchSaveSettings'.
 * * The receive action creator is called 'receiveSaveSettings'.
 * * The fetching selector is called 'isFetchingSaveSettings'.
 *
 * All parts of the returned store objects should be considered internal. A
 * public action or selector should be implemented to actually call the
 * fetch action included in the returned store object.
 *
 * For example, if the fetch store is intended for an API-based
 * action 'storeMySetting':
 * * The basename passed should be 'storeMySetting'.
 * * The action 'storeMySetting' should call 'fetchStoreMySetting'.
 *
 * Or, if the fetch store is intended for an API-based selector
 * 'getSomeData':
 * * The baseName passed should be 'getSomeData'.
 * * The resolver for 'getSomeData' should call 'fetchGetSomeData'.
 *
 * @since n.e.x.t
 * @private
 *
 * @param {Object}   options                  Options for creating the fetch store.
 * @param {string}   options.baseName         The base name to use for all the created infrastructure.
 * @param {Function} options.controlCallback  Callback function to issue the API request. Will be used inside the
 *                                            control. The function receives a params object based on argsToParams,
 *                                            i.e. the respective values passed to the action.
 * @param {?Function} options.reducerCallback Optional. Callback function to modify state based on the API response.
 *                                            Will be used inside the reducer. The  function receives the store's state
 *                                            object as first parameter, the API response as second parameter, and the
 *                                            params object for the request (see above) as third parameter. If not
 *                                            provided, the default will return the unmodified state.
 * @param {?Function} options.argsToParams    Optional. Function that should validate expected arguments for the
 *                                            internal fetch action and parse them into an named parameters object,
 *                                            with the argument names used as keys. If not provided, the default
 *                                            function will return an empty object, essentially indicating that no
 *                                            arguments are supported/required.
 * @return {Object} Partial store object with properties 'actions', 'controls', 'reducer', 'resolvers', and 'selectors'.
 */
export const createFetchStore = ( {
	baseName,
	controlCallback,
	reducerCallback,
	argsToParams,
} ) => {
	invariant( baseName, 'baseName is required.' );
	invariant( 'function' === typeof controlCallback, 'controlCallback is required.' );

	if ( 'function' !== typeof reducerCallback ) {
		reducerCallback = ( state ) => {
			return { ...state };
		};
	}

	let requiresParams = true;
	if ( 'function' !== typeof argsToParams ) {
		requiresParams = false;
		argsToParams = () => {
			return {};
		};
	}

	const pascalCaseBaseName = baseName.charAt( 0 ).toUpperCase() + baseName.slice( 1 );
	const constantBaseName = baseName.replace( /([a-z0-9]{1})([A-Z]{1})/g, '$1_$2' ).toUpperCase();

	const FETCH = `FETCH_${ constantBaseName }`;
	const START_FETCH = `START_FETCH_${ constantBaseName }`;
	const FINISH_FETCH = `FINISH_FETCH_${ constantBaseName }`;
	const CATCH_FETCH = `CATCH_FETCH_${ constantBaseName }`;
	const RECEIVE = `RECEIVE_${ constantBaseName }`;

	const fetchCreator = `fetch${ pascalCaseBaseName }`;
	const receiveCreator = `receive${ pascalCaseBaseName }`;
	const isFetching = `isFetching${ pascalCaseBaseName }`;

	const actions = {
		[ fetchCreator ]: function*( ...args ) { // eslint-disable-line object-shorthand
			let response, error, params;

			try {
				params = argsToParams( ...args );
			} catch ( err ) {
				// Parameters should never be invalid here, this needs to be
				// strict and inform the developer of the issue.
				global.console.error( err.message );
				error = err;
				return { response, error };
			}

			yield {
				payload: { params },
				type: START_FETCH,
			};

			try {
				response = yield {
					payload: { params },
					type: FETCH,
				};

				yield actions[ receiveCreator ]( response, params );

				yield {
					payload: { params },
					type: FINISH_FETCH,
				};
			} catch ( e ) {
				error = e;

				yield {
					payload: { error, params },
					type: CATCH_FETCH,
				};
			}

			return { response, error };
		},

		[ receiveCreator ]: function( response, params ) { // eslint-disable-line object-shorthand
			invariant( 'undefined' !== typeof response, 'response is required.' );
			if ( requiresParams ) {
				invariant( 'object' === typeof params, 'params is required.' );
			} else {
				params = {};
			}

			return {
				payload: { response, params },
				type: RECEIVE,
			};
		},
	};

	const controls = {
		[ FETCH ]: ( { payload } ) => {
			return controlCallback( payload.params );
		},
	};

	const reducer = ( state, { type, payload } ) => {
		switch ( type ) {
			case START_FETCH: {
				const { params } = payload;
				return {
					...state,
					[ isFetching ]: {
						...( state[ isFetching ] || {} ),
						[ stringifyObject( params ) ]: true,
					},
				};
			}

			case RECEIVE: {
				const { response, params } = payload;
				return reducerCallback( state, response, params );
			}

			case FINISH_FETCH: {
				const { params } = payload;
				return {
					...state,
					[ isFetching ]: {
						...( state[ isFetching ] || {} ),
						[ stringifyObject( params ) ]: false,
					},
				};
			}

			case CATCH_FETCH: {
				const { error, params } = payload;
				return {
					...state,
					error,
					[ isFetching ]: {
						...( state[ isFetching ] || {} ),
						[ stringifyObject( params ) ]: false,
					},
				};
			}

			default: {
				return { ...state };
			}
		}
	};

	const selectors = {
		[ isFetching ]: ( state, ...args ) => {
			if ( 'undefined' === typeof state[ isFetching ] ) {
				return false;
			}

			let params;
			try {
				params = argsToParams( ...args );
			} catch ( err ) {
				// If parameters are invalid, fail silently here. It likely is
				// because some dependency selector is still resolving.
				return false;
			}

			return !! state[ isFetching ][ stringifyObject( params ) ];
		},
	};

	return {
		actions,
		controls,
		reducer,
		resolvers: {},
		selectors,
	};
};
<commit_msg>Improve handling of createFetchStore defaults.<commit_after>/**
 * API function to create fetch store.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * 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
 *
 *     https://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.
 */

/**
 * External dependencies
 */
import invariant from 'invariant';

/**
 * Internal dependencies
 */
import { stringifyObject } from '../../util';

const defaultReducerCallback = ( state ) => {
	return { ...state };
};

const defaultArgsToParams = () => {
	return {};
};

/**
 * Creates a store object implementing the necessary infrastructure for a
 * single fetch action.
 *
 * This function returns a partial store object with the following:
 * * action creators to fetch and to receive the data
 * * control to issue the API request
 * * reducer to set API request flag and receive the response
 * * selector to check whether the API request is in progress via flag
 *
 * The names of the pieces are based on the baseName provided.
 * For example, if baseName is 'saveSettings':
 * * The fetch action creator is called 'fetchSaveSettings'.
 * * The receive action creator is called 'receiveSaveSettings'.
 * * The fetching selector is called 'isFetchingSaveSettings'.
 *
 * All parts of the returned store objects should be considered internal. A
 * public action or selector should be implemented to actually call the
 * fetch action included in the returned store object.
 *
 * For example, if the fetch store is intended for an API-based
 * action 'storeMySetting':
 * * The basename passed should be 'storeMySetting'.
 * * The action 'storeMySetting' should call 'fetchStoreMySetting'.
 *
 * Or, if the fetch store is intended for an API-based selector
 * 'getSomeData':
 * * The baseName passed should be 'getSomeData'.
 * * The resolver for 'getSomeData' should call 'fetchGetSomeData'.
 *
 * @since n.e.x.t
 * @private
 *
 * @param {Object}   options                  Options for creating the fetch store.
 * @param {string}   options.baseName         The base name to use for all the created infrastructure.
 * @param {Function} options.controlCallback  Callback function to issue the API request. Will be used inside the
 *                                            control. The function receives a params object based on argsToParams,
 *                                            i.e. the respective values passed to the action.
 * @param {?Function} options.reducerCallback Optional. Callback function to modify state based on the API response.
 *                                            Will be used inside the reducer. The  function receives the store's state
 *                                            object as first parameter, the API response as second parameter, and the
 *                                            params object for the request (see above) as third parameter. If not
 *                                            provided, the default will return the unmodified state.
 * @param {?Function} options.argsToParams    Optional. Function that should validate expected arguments for the
 *                                            internal fetch action and parse them into an named parameters object,
 *                                            with the argument names used as keys. If not provided, the default
 *                                            function will return an empty object, essentially indicating that no
 *                                            arguments are supported/required.
 * @return {Object} Partial store object with properties 'actions', 'controls', 'reducer', 'resolvers', and 'selectors'.
 */
export const createFetchStore = ( {
	baseName,
	controlCallback,
	reducerCallback = defaultReducerCallback,
	argsToParams = defaultArgsToParams,
} ) => {
	invariant( baseName, 'baseName is required.' );
	invariant( 'function' === typeof controlCallback, 'controlCallback is required and must be a function.' );
	invariant( 'function' === typeof reducerCallback, 'reducerCallback must be a function.' );
	invariant( 'function' === typeof argsToParams, 'argsToParams must be a function.' );

	// If argsToParams without any arguments does not result in an error, we
	// know params is okay to be empty.
	let requiresParams;
	try {
		argsToParams();
		requiresParams = false;
	} catch ( error ) {
		requiresParams = true;
	}

	const pascalCaseBaseName = baseName.charAt( 0 ).toUpperCase() + baseName.slice( 1 );
	const constantBaseName = baseName.replace( /([a-z0-9]{1})([A-Z]{1})/g, '$1_$2' ).toUpperCase();

	const FETCH = `FETCH_${ constantBaseName }`;
	const START_FETCH = `START_FETCH_${ constantBaseName }`;
	const FINISH_FETCH = `FINISH_FETCH_${ constantBaseName }`;
	const CATCH_FETCH = `CATCH_FETCH_${ constantBaseName }`;
	const RECEIVE = `RECEIVE_${ constantBaseName }`;

	const fetchCreator = `fetch${ pascalCaseBaseName }`;
	const receiveCreator = `receive${ pascalCaseBaseName }`;
	const isFetching = `isFetching${ pascalCaseBaseName }`;

	const actions = {
		[ fetchCreator ]: function*( ...args ) { // eslint-disable-line object-shorthand
			let response, error, params;

			try {
				params = argsToParams( ...args );
			} catch ( err ) {
				// Parameters should never be invalid here, this needs to be
				// strict and inform the developer of the issue.
				global.console.error( err.message );
				error = err;
				return { response, error };
			}

			yield {
				payload: { params },
				type: START_FETCH,
			};

			try {
				response = yield {
					payload: { params },
					type: FETCH,
				};

				yield actions[ receiveCreator ]( response, params );

				yield {
					payload: { params },
					type: FINISH_FETCH,
				};
			} catch ( e ) {
				error = e;

				yield {
					payload: { error, params },
					type: CATCH_FETCH,
				};
			}

			return { response, error };
		},

		[ receiveCreator ]: function( response, params ) { // eslint-disable-line object-shorthand
			invariant( 'undefined' !== typeof response, 'response is required.' );
			if ( requiresParams ) {
				invariant( 'object' === typeof params, 'params is required.' );
			} else {
				params = {};
			}

			return {
				payload: { response, params },
				type: RECEIVE,
			};
		},
	};

	const controls = {
		[ FETCH ]: ( { payload } ) => {
			return controlCallback( payload.params );
		},
	};

	const reducer = ( state, { type, payload } ) => {
		switch ( type ) {
			case START_FETCH: {
				const { params } = payload;
				return {
					...state,
					[ isFetching ]: {
						...( state[ isFetching ] || {} ),
						[ stringifyObject( params ) ]: true,
					},
				};
			}

			case RECEIVE: {
				const { response, params } = payload;
				return reducerCallback( state, response, params );
			}

			case FINISH_FETCH: {
				const { params } = payload;
				return {
					...state,
					[ isFetching ]: {
						...( state[ isFetching ] || {} ),
						[ stringifyObject( params ) ]: false,
					},
				};
			}

			case CATCH_FETCH: {
				const { error, params } = payload;
				return {
					...state,
					error,
					[ isFetching ]: {
						...( state[ isFetching ] || {} ),
						[ stringifyObject( params ) ]: false,
					},
				};
			}

			default: {
				return { ...state };
			}
		}
	};

	const selectors = {
		[ isFetching ]: ( state, ...args ) => {
			if ( 'undefined' === typeof state[ isFetching ] ) {
				return false;
			}

			let params;
			try {
				params = argsToParams( ...args );
			} catch ( err ) {
				// If parameters are invalid, fail silently here. It likely is
				// because some dependency selector is still resolving.
				return false;
			}

			return !! state[ isFetching ][ stringifyObject( params ) ];
		},
	};

	return {
		actions,
		controls,
		reducer,
		resolvers: {},
		selectors,
	};
};
<|endoftext|>


<commit_before>/**
 * Created by fsuda on 18.09.2018.
 */
import { details, mergeInEmptyDraft } from "../detail-definitions.js";
import {
  realEstateFloorSizeDetail,
  realEstateNumberOfRoomsDetail,
  realEstateFeaturesDetail,
} from "../details/real-estate.js";
import won from "../../app/won-es6.js";
import { perHourRentDetail } from "../details/musician.js";
import { findLatestIntervallEndInJsonLdOrNowAndAddMillis } from "../../app/won-utils.js";
import {
  filterNumericProperty,
  filterPrice,
  concatenateFilters,
  sparqlQuery,
} from "../../app/sparql-builder-utils.js";

export const rehearsalRoomOffer = {
  identifier: "rehearsalRoomOffer",
  label: "Offer Rehearsal Room",
  icon: "#ico36_uc_realestate",
  timeToLiveMillisDefault: 1000 * 60 * 60 * 24 * 30 * 3,
  doNotMatchAfter: findLatestIntervallEndInJsonLdOrNowAndAddMillis,
  draft: {
    ...mergeInEmptyDraft({
      content: {
        type: "won:RehearsalRoomRentOffer",
        title: "Offer Rehearsal Room!",
      },
      seeks: {
        type: "won:RehearsalRoomRentDemand",
      },
    }),
  },
  details: {
    title: { ...details.title },
    description: { ...details.description },
    location: {
      ...details.location,
      mandatory: true,
    },
    floorSize: {
      ...realEstateFloorSizeDetail,
      mandatory: true,
    },
    numberOfRooms: {
      ...realEstateNumberOfRoomsDetail,
      mandatory: true,
    },
    features: {
      ...realEstateFeaturesDetail,
      placeholder: "e.g. PA, Drumkit",
    },
    rent: {
      ...perHourRentDetail,
      mandatory: true,
    },
    fromDatetime: { ...details.fromDatetime },
    throughDatetime: { ...details.throughDatetime },
  },

  seeksDetails: undefined,
  generateQuery: (draft, resultName) => {
    const draftContent = draft && draft.content;
    const location = draftContent && draftContent.location;
    const rent = draftContent && draftContent.rent;
    const floorSize = draftContent && draftContent.floorSize;

    let filter;

    if (location && location.lat && location.lng) {
      const filters = [
        {
          // to select is-branch
          prefixes: {
            won: won.defaultContext["won"],
            rdf: won.defaultContext["rdf"],
            sh: won.defaultContext["sh"], //needed for the filterNumericProperty calls
            s: won.defaultContext["s"],
            geo: "http://www.bigdata.com/rdf/geospatial#",
            xsd: "http://www.w3.org/2001/XMLSchema#",
          },
          operations: [
            `${resultName} a won:Need.`,
            `${resultName} won:seeks ?seeks.`,
            `${resultName} rdf:type won:RehearsalRoomRentDemand.`,
            "?seeks (won:hasLocation|s:location ?location.",
            "?location s:geo ?location_geo.",
            "?location_geo s:latitude ?location_lat;",
            "s:longitude ?location_lon;",
            `bind (abs(xsd:decimal(?location_lat) - ${
              location.lat
            }) as ?latDiffRaw)`,
            `bind (abs(xsd:decimal(?location_lon) - ${
              location.lng
            }) as ?lonDiff)`,
            "bind (if ( ?latDiffRaw > 180, 360 - ?latDiffRaw, ?latDiffRaw ) as ?latDiff)",
            "bind ( ?latDiff * ?latDiff + ?lonDiff * ?lonDiff as ?location_geoDistanceScore)",
            "bind (?location_geoDistanceScore as ?distScore)",
          ],
        },
        rent && filterPrice("?seeks", rent.amount, rent.currency, "rent"),
        floorSize &&
          filterNumericProperty("?seeks", floorSize, "s:floorSize", "size"),
      ];

      filter = concatenateFilters(filters);
    } else {
      const filters = [
        {
          // to select is-branch
          prefixes: {
            won: won.defaultContext["won"],
            rdf: won.defaultContext["rdf"],
            sh: won.defaultContext["sh"], //needed for the filterNumericProperty calls
          },
          operations: [
            `${resultName} a won:Need.`,
            `${resultName} won:seeks ?seeks.`,
            `${resultName} rdf:type won:RehearsalRoomRentDemand.`,
          ],
        },
        rent && filterPrice("?seeks", rent.amount, rent.currency, "rent"),
        floorSize &&
          filterNumericProperty("?seeks", floorSize, "s:floorSize", "size"),
      ];

      filter = concatenateFilters(filters);
    }

    const generatedQuery = sparqlQuery({
      prefixes: filter.prefixes,
      distinct: true,
      variables: [resultName],
      where: filter.operations,
      orderBy: [
        {
          order: "ASC",
          variable: "?distScore",
        },
      ],
    });

    return generatedQuery;
  },
};
<commit_msg>Adds missing )<commit_after>/**
 * Created by fsuda on 18.09.2018.
 */
import { details, mergeInEmptyDraft } from "../detail-definitions.js";
import {
  realEstateFloorSizeDetail,
  realEstateNumberOfRoomsDetail,
  realEstateFeaturesDetail,
} from "../details/real-estate.js";
import won from "../../app/won-es6.js";
import { perHourRentDetail } from "../details/musician.js";
import { findLatestIntervallEndInJsonLdOrNowAndAddMillis } from "../../app/won-utils.js";
import {
  filterNumericProperty,
  filterPrice,
  concatenateFilters,
  sparqlQuery,
} from "../../app/sparql-builder-utils.js";

export const rehearsalRoomOffer = {
  identifier: "rehearsalRoomOffer",
  label: "Offer Rehearsal Room",
  icon: "#ico36_uc_realestate",
  timeToLiveMillisDefault: 1000 * 60 * 60 * 24 * 30 * 3,
  doNotMatchAfter: findLatestIntervallEndInJsonLdOrNowAndAddMillis,
  draft: {
    ...mergeInEmptyDraft({
      content: {
        type: "won:RehearsalRoomRentOffer",
        title: "Offer Rehearsal Room!",
      },
      seeks: {
        type: "won:RehearsalRoomRentDemand",
      },
    }),
  },
  details: {
    title: { ...details.title },
    description: { ...details.description },
    location: {
      ...details.location,
      mandatory: true,
    },
    floorSize: {
      ...realEstateFloorSizeDetail,
      mandatory: true,
    },
    numberOfRooms: {
      ...realEstateNumberOfRoomsDetail,
      mandatory: true,
    },
    features: {
      ...realEstateFeaturesDetail,
      placeholder: "e.g. PA, Drumkit",
    },
    rent: {
      ...perHourRentDetail,
      mandatory: true,
    },
    fromDatetime: { ...details.fromDatetime },
    throughDatetime: { ...details.throughDatetime },
  },

  seeksDetails: undefined,
  generateQuery: (draft, resultName) => {
    const draftContent = draft && draft.content;
    const location = draftContent && draftContent.location;
    const rent = draftContent && draftContent.rent;
    const floorSize = draftContent && draftContent.floorSize;

    let filter;

    if (location && location.lat && location.lng) {
      const filters = [
        {
          // to select is-branch
          prefixes: {
            won: won.defaultContext["won"],
            rdf: won.defaultContext["rdf"],
            sh: won.defaultContext["sh"], //needed for the filterNumericProperty calls
            s: won.defaultContext["s"],
            geo: "http://www.bigdata.com/rdf/geospatial#",
            xsd: "http://www.w3.org/2001/XMLSchema#",
          },
          operations: [
            `${resultName} a won:Need.`,
            `${resultName} won:seeks ?seeks.`,
            `${resultName} rdf:type won:RehearsalRoomRentDemand.`,
            "?seeks (won:hasLocation|s:location) ?location.",
            "?location s:geo ?location_geo.",
            "?location_geo s:latitude ?location_lat;",
            "s:longitude ?location_lon;",
            `bind (abs(xsd:decimal(?location_lat) - ${
              location.lat
            }) as ?latDiffRaw)`,
            `bind (abs(xsd:decimal(?location_lon) - ${
              location.lng
            }) as ?lonDiff)`,
            "bind (if ( ?latDiffRaw > 180, 360 - ?latDiffRaw, ?latDiffRaw ) as ?latDiff)",
            "bind ( ?latDiff * ?latDiff + ?lonDiff * ?lonDiff as ?location_geoDistanceScore)",
            "bind (?location_geoDistanceScore as ?distScore)",
          ],
        },
        rent && filterPrice("?seeks", rent.amount, rent.currency, "rent"),
        floorSize &&
          filterNumericProperty("?seeks", floorSize, "s:floorSize", "size"),
      ];

      filter = concatenateFilters(filters);
    } else {
      const filters = [
        {
          // to select is-branch
          prefixes: {
            won: won.defaultContext["won"],
            rdf: won.defaultContext["rdf"],
            sh: won.defaultContext["sh"], //needed for the filterNumericProperty calls
          },
          operations: [
            `${resultName} a won:Need.`,
            `${resultName} won:seeks ?seeks.`,
            `${resultName} rdf:type won:RehearsalRoomRentDemand.`,
          ],
        },
        rent && filterPrice("?seeks", rent.amount, rent.currency, "rent"),
        floorSize &&
          filterNumericProperty("?seeks", floorSize, "s:floorSize", "size"),
      ];

      filter = concatenateFilters(filters);
    }

    const generatedQuery = sparqlQuery({
      prefixes: filter.prefixes,
      distinct: true,
      variables: [resultName],
      where: filter.operations,
      orderBy: [
        {
          order: "ASC",
          variable: "?distScore",
        },
      ],
    });

    return generatedQuery;
  },
};
<|endoftext|>


<commit_before>var PassportConfigurator =
    require('loopback-component-passport').PassportConfigurator;

module.exports = function(app) {
    var passportConfigurator = new PassportConfigurator(app);
    var passport = passportConfigurator.init();

    var strategy = 'facebook-login';
    var opts = require('../../providers.json')[strategy];

    // Doesn't look like we need this..yet, but it would be good to set proper options
    // up front so we can use the proper values directly below.
    opts.session = opts.session !== false;

    opts.customCallback = function (req, res, next) {
        // We need url, because we want to use to to parse the url and then reformat it with params.
        var url = require('url');

        // Note that we have to only use variables that are in scope right now, like opts.
        passport.authenticate(
            strategy,
            {session: false},
            //See http://passportjs.org/guide/authenticate/
            // err, user, and info are passed to this by passport
            function(err, user, info) {
                if (err) {
                    return next(err);
                }
                if (!user) {
                    // TODO - we might want to add some params here too for failures.
                    return res.redirect(opts.failureRedirect);
                }
                // Add the tokens to the callback as params.
                var redirect = url.parse(opts.successRedirect, true);

                // this is needed or query is ignored. See url module docs.
                delete redirect.search;

                redirect.query = {
                    'access_token': info.accessToken.id,
                    // Note the .toString here is necessary.
                    'userId': user.id.toString()
                };
                // Put the url back together. It should now have params set.
                redirect = url.format(redirect);
                return res.redirect(redirect);
            }
        )(req, res, next);
    };

    passportConfigurator.setupModels({
        userModel: app.models.User,
        userIdentityModel: app.models.UserIdentity,
        userCredentialModel: app.models.UserCredential
    });

    passportConfigurator.configureProvider(strategy, opts);
};
<commit_msg>Modified responses to include query parameters after React Router hash in url.<commit_after>var PassportConfigurator =
    require('loopback-component-passport').PassportConfigurator;

module.exports = function(app) {
    var passportConfigurator = new PassportConfigurator(app);
    var passport = passportConfigurator.init();

    var strategy = 'facebook-login';
    var opts = require('../../providers.json')[strategy];

    opts.session = opts.session !== false;

    opts.customCallback = function (req, res, next) {
        passport.authenticate(
            strategy,
            {session: false},
            //See http://passportjs.org/guide/authenticate/
            // err, user, and info are passed to this by passport
            function(err, user, info) {
                if (err) {
                    return next(err);
                }
                if (!user) {
                    // TODO - we might want to add some params here too for failures.
                    return res.redirect(opts.failureRedirect);
                }

                var redirect = opts.successRedirect + '?' + 'access_token=' +
                    info.accessToken.id + '&userId=' + user.id.toString()
                return res.redirect(redirect);
            }
        )(req, res, next);
    };

    passportConfigurator.setupModels({
        userModel: app.models.User,
        userIdentityModel: app.models.UserIdentity,
        userCredentialModel: app.models.UserCredential
    });

    passportConfigurator.configureProvider(strategy, opts);
};
<|endoftext|>