<commit_before>'use strict';

const regression = require('./regression');
const { DEFAULT_LAMBDA, DECLARATION_INPUTS_KEY } = require('./constants.js');
const fs = require('fs');
const FreeSurfer = require('freesurfer-parser');
const get = require('lodash/get');
const pkg = require('../package.json');
const n = require('numeric');
const distributions = require('distributions');

/**
 * Get FreeSurfer region of interest picker.
 *
 * @param {string} feature
 * @returns {Function} FreeSurfer data picker
 */
/* eslint-disable arrow-parens,arrow-body-style */
const getFreeSurferDataPicker = feature => freeSurferData => {
  return new FreeSurfer({ string: freeSurferData })[feature];
};
/* eslint-enable arrow-parens,arrow-body-style */

/**
 * Read file.
 *
 * @param {string} file
 * @returns {Promise} Resolves to `file`'s contents
 */
const readFileAsync = file => new Promise((resolve, reject) => {
  fs.readFile(file, (error, data) => {
    if (error) {
      reject(error);
    } else {
      resolve(data.toString());
    }
  });
});

/**
 * Get normalized tags.
 *
 * @param {Object} file
 * @param {Object} file.tags Hash map of tag names to values
 * @returns {Array} Normalized tags
 */
const getNormalizedTags = file => Object.keys(file.tags).sort().reduce(
  (memo, tag) => {
    const value = file.tags[tag];

    if (typeof value === 'boolean') {
      return memo.concat(value === true ? 1 : -1);
    } else if (typeof value === 'number') {
      return memo.concat(value);
    }

    return memo;
  },
  []
);

module.exports = {
  name: pkg.name,
  version: pkg.version,
  local: [{
    type: 'function',
    fn(opts) {
      let features = get(opts, 'remoteResult.pluginState.inputs[0][0]');
      let lambda = get(opts, 'remoteResult.pluginState.inputs[0][1]');
      const files = get(opts, 'userData.files');

      // TODO: This is a hack for simulator. Figure out how to load plugin state
      /* eslint-disable no-underscore-dangle */
      if (!features && opts.userData[DECLARATION_INPUTS_KEY]) {
        features = opts.userData[DECLARATION_INPUTS_KEY][0][0];
        lambda = opts.userData[DECLARATION_INPUTS_KEY][0][1];
      }
      /* eslint-enable no-underscore-dangle */

      if (!Array.isArray(features) || !features.length) {
        return Promise.reject(new Error('Expected RoI features inputs'));
      } else if (features.some(f => FreeSurfer.validFields.indexOf(f) < 0)) {
        return Promise.reject(new Error(
          `Invalid FreeSurfer feature in ${features.toString()}`
        ));
      } else if (!Array.isArray(files) || !files.length) {
        return Promise.reject(new Error('Expected user data to contain files'));
      } else if (typeof lambda !== 'number') {
        return Promise.reject(new Error('Lambda required'));
      }

      const pickFeature = getFreeSurferDataPicker(features[0]);

      return Promise.all(files.map(f => readFileAsync(f.filename)))
        .then(freeSurferDatas => { // eslint-disable-line arrow-parens
          const x = files.map(getNormalizedTags); // covariates
          const y = freeSurferDatas.map(pickFeature); // RoIs

          // calculate regression result and localMeanY
          const biasedX = x.map(covariates => [1].concat(covariates));
          const localCount = y.length;
          const betaVector = regression.oneShot(biasedX, y, lambda);
          const rSquared = regression.rSquared(biasedX, y, betaVector);
          const tValue = regression.tValue(biasedX, y, betaVector);
          /* eslint-disable new-cap */
          const tdist = distributions.Studentt(localCount - betaVector.length);
          /* eslint-disable new-cap */
          const tcdf = tValue.map(r => tdist.cdf(Math.abs(r)));
          const pValue = n.mul(2, n.sub(1, tcdf));
          const localMeanY = n.sum(y) / localCount;

          /* eslint-disable no-console */
          console.log('X is:', biasedX);
          console.log('y is:', y);
          console.log('beta vector is:', betaVector);
          console.log('local r squared for original betaVector:', rSquared);
          console.log('local t Values for original betaVector:', tValue);
          console.log('local p values for original betaVector:', pValue);
          /* eslint-enable no-console */

          return {
            betaVector,
            localCount,
            localMeanY,
            rSquared,
            tValue,
            pValue,
            biasedX,
            y,
          };
        });
    },
    inputs: [{
      help: 'Select Freesurfer region(s) of interest',
      label: 'Freesurfer ROI',
      type: 'select',
      values: FreeSurfer.validFields,
    }, {
      defaultValue: DEFAULT_LAMBDA,
      label: 'Lambda',
      max: 1,
      min: 0,
      step: 0.05,
      type: 'number',
    }, {
      label: 'Covariates',
      type: 'covariates',
    }],
  }, {
    // step two: receive the globalMeanY and averageBetaVector,
    //  then calculate sseLocal, sstLocal and varXLocal
    type: 'function',
    fn(opts) {
      // use deconstructing to assign variables
      const {
        previousData: {
          betaVector,
          biasedX,
          pValue,
          rSquared,
          tValue,
          y,
         },
        remoteResult: {
           data: {
             averageBetaVector,
             globalMeanY,
              },
            },
      } = opts;

      const localCount = y.length;
      const rSquaredLocal = regression.rSquared(biasedX, y, averageBetaVector);
      const tValueLocal = regression.tValue(biasedX, y, averageBetaVector);
      /* eslint-disable new-cap */
      const tDist = distributions.Studentt(localCount - averageBetaVector.length);
      /* eslint-disable new-cap */
      const tCdf = tValueLocal.map(r => tDist.cdf(Math.abs((r))));
      const pValueLocal = n.mul(2, n.sub(1, tCdf));
      const sseLocal = n.sum(n.pow(n.sub(y, n.dot(biasedX, averageBetaVector)), 2));
      const sstLocal = n.sum(n.pow(n.sub(y, n.rep(n.dim(y), globalMeanY)), 2));
      const varXLocalMatrix = n.dot(n.transpose(biasedX), biasedX);

      /* eslint-disable no-console */
      console.log('local r squared for averageBetaVector', rSquaredLocal);
      console.log('local t Values for averageBetaVector', tValueLocal);
      console.log('local p Values for averageBetaVector', pValueLocal);
      /* eslint-enable no-console */

      return {
        betaVector,
        sseLocal,
        sstLocal,
        varXLocalMatrix,
        averageBetaVector,
        localCount,
        rSquared,
        tValue,
        pValue,
        rSquaredLocal,
        tValueLocal,
        pValueLocal,
      };
    },

  }],
  remote: [{
    type: 'function',
    fn(opts) {
      const userResults = opts.userResults;

      // Not all user results contain betas. Return early.
      if (userResults.some(userResult => !get(userResult, 'data.betaVector'))) {
        return {};
      }

      // calculate averageBetaVector
      const averageBetaVector = [];
      const betaCount = userResults[0].data.betaVector.length;
      const userCount = userResults.length;

      for (let i = 0; i < betaCount; i += 1) {
        averageBetaVector.push(userResults.reduce(
          (sum, userResult) => sum + userResult.data.betaVector[i], 0
        ) / userCount);
      }

      // calculate globalMeanY (rewrite it using more concise way)

      const globalMeanY =
          n.sum(
             userResults.map(result => result.data.localMeanY * result.data.localCount)
          ) /
          n.sum(
             userResults.map(result => result.data.localCount)
          );

      /* eslint-disable no-console */
      console.log('Average beta vector:', averageBetaVector);
      console.log('globalMeanY is :', globalMeanY);
      /* eslint-enable no-console */

      // Extract X and y variable name list from userData

      /* eslint-disable no-underscore-dangle */
      const yLabel = opts.userResults[0].userData.__FEATURES__;
      /* eslint-enable no-underscore-dangle */
      const xLabel = Object.keys(opts.userResults[0].userData.files[0].tags);

      /* eslint-disable no-console */
      console.log('xLabel is', xLabel);
      console.log('yLabel is', yLabel);
      /* eslint-enable no-console */

      return {
        averageBetaVector,
        globalMeanY,
        xLabel,
        yLabel,
      };
    },
    verbose: true,
  }, {
    // get sstNode from each local node and calculate the statistics
    type: 'function',
    fn(opts) {
      const {
       previousData: { xLabel, yLabel },
       userResults,
       userResults: [{
        data: { averageBetaVector },
        }],
     } = opts;

      const betaVectorLocal = userResults.map(r => r.data.betaVector);
      const rSquaredLocalOriginal = userResults.map(r => r.data.rSquared);
      const tValueLocalOriginal = userResults.map(r => r.data.tValue);
      const pValueLocalOriginal = userResults.map(r => r.data.pValue);
      const rSquaredLocal = userResults.map(r => r.data.rSquaredLocal);
      const tValueLocal = userResults.map(r => r.data.tValueLocal);
      const pValueLocal = userResults.map(r => r.data.pValueLocal);

      // calculate global parameters
      const sseGlobal = userResults.reduce((sum, userResult) => sum +
                        userResult.data.sseLocal, 0);
      const sstGlobal = userResults.reduce((sum, userResult) => sum +
                        userResult.data.sstLocal, 0);
      const globalYCount = userResults.reduce((sum, userResult) => sum +
                           userResult.data.localCount, 0);

      const varError = (1 / (globalYCount - averageBetaVector.length)) * sseGlobal;
      const seBetaGlobal = [];
      const tValueGlobal = [];

      // calculate tValueGlobal
      let varXGlobalMatrix = n.rep([averageBetaVector.length, averageBetaVector.length], 0);

      for (let i = 0; i < userResults.length; i += 1) {
        varXGlobalMatrix = n.add(varXGlobalMatrix, userResults[i].data.varXLocalMatrix);
      }

      /* eslint-disable no-console */
      console.log('varXGlobalMatrix is', varXGlobalMatrix);
      /* eslint-enable no-console */

      const varBetaGlobal = n.mul(n.inv(varXGlobalMatrix), varError);

      for (let i = 0; i < averageBetaVector.length; i += 1) {
        seBetaGlobal[i] = Math.sqrt(varBetaGlobal[i][i]);
        tValueGlobal[i] = averageBetaVector[i] / seBetaGlobal[i];
      }

      const rSquaredGlobal = 1 - (sseGlobal / sstGlobal);
      const tDist = distributions.Studentt(globalYCount - averageBetaVector.length);
      const tCdf = tValueGlobal.map(r => tDist.cdf(Math.abs(r)));
      const pValueGlobal = n.mul(2, (n.sub(1, tCdf))); // two tail pValue

      /* eslint-disable no-console */
      console.log('The global r squared for averageBetaVector :', rSquaredGlobal);
      console.log('The global t Values for averageBetaVector :', tValueGlobal);
      console.log('The global p Values for averageBetaVector :', pValueGlobal);
      /* eslint-disable no-console */

      const result = {
        betaVectorLocal,
        averageBetaVector,
        rSquaredLocalOriginal,
        tValueLocalOriginal,
        pValueLocalOriginal,
        rSquaredLocal,
        tValueLocal,
        pValueLocal,
        rSquaredGlobal,
        tValueGlobal,
        pValueGlobal,
        xLabel,
        yLabel,
        complete: true,
      };

      console.log('Final result!', result);

      return result;
    },
    verbose: true,
  }],
  plugins: ['group-step', 'inputs'],

};
<commit_msg>Improve destructure block's spacing.<commit_after>'use strict';

const regression = require('./regression');
const { DEFAULT_LAMBDA, DECLARATION_INPUTS_KEY } = require('./constants.js');
const fs = require('fs');
const FreeSurfer = require('freesurfer-parser');
const get = require('lodash/get');
const pkg = require('../package.json');
const n = require('numeric');
const distributions = require('distributions');

/**
 * Get FreeSurfer region of interest picker.
 *
 * @param {string} feature
 * @returns {Function} FreeSurfer data picker
 */
/* eslint-disable arrow-parens,arrow-body-style */
const getFreeSurferDataPicker = feature => freeSurferData => {
  return new FreeSurfer({ string: freeSurferData })[feature];
};
/* eslint-enable arrow-parens,arrow-body-style */

/**
 * Read file.
 *
 * @param {string} file
 * @returns {Promise} Resolves to `file`'s contents
 */
const readFileAsync = file => new Promise((resolve, reject) => {
  fs.readFile(file, (error, data) => {
    if (error) {
      reject(error);
    } else {
      resolve(data.toString());
    }
  });
});

/**
 * Get normalized tags.
 *
 * @param {Object} file
 * @param {Object} file.tags Hash map of tag names to values
 * @returns {Array} Normalized tags
 */
const getNormalizedTags = file => Object.keys(file.tags).sort().reduce(
  (memo, tag) => {
    const value = file.tags[tag];

    if (typeof value === 'boolean') {
      return memo.concat(value === true ? 1 : -1);
    } else if (typeof value === 'number') {
      return memo.concat(value);
    }

    return memo;
  },
  []
);

module.exports = {
  name: pkg.name,
  version: pkg.version,
  local: [{
    type: 'function',
    fn(opts) {
      let features = get(opts, 'remoteResult.pluginState.inputs[0][0]');
      let lambda = get(opts, 'remoteResult.pluginState.inputs[0][1]');
      const files = get(opts, 'userData.files');

      // TODO: This is a hack for simulator. Figure out how to load plugin state
      /* eslint-disable no-underscore-dangle */
      if (!features && opts.userData[DECLARATION_INPUTS_KEY]) {
        features = opts.userData[DECLARATION_INPUTS_KEY][0][0];
        lambda = opts.userData[DECLARATION_INPUTS_KEY][0][1];
      }
      /* eslint-enable no-underscore-dangle */

      if (!Array.isArray(features) || !features.length) {
        return Promise.reject(new Error('Expected RoI features inputs'));
      } else if (features.some(f => FreeSurfer.validFields.indexOf(f) < 0)) {
        return Promise.reject(new Error(
          `Invalid FreeSurfer feature in ${features.toString()}`
        ));
      } else if (!Array.isArray(files) || !files.length) {
        return Promise.reject(new Error('Expected user data to contain files'));
      } else if (typeof lambda !== 'number') {
        return Promise.reject(new Error('Lambda required'));
      }

      const pickFeature = getFreeSurferDataPicker(features[0]);

      return Promise.all(files.map(f => readFileAsync(f.filename)))
        .then(freeSurferDatas => { // eslint-disable-line arrow-parens
          const x = files.map(getNormalizedTags); // covariates
          const y = freeSurferDatas.map(pickFeature); // RoIs

          // calculate regression result and localMeanY
          const biasedX = x.map(covariates => [1].concat(covariates));
          const localCount = y.length;
          const betaVector = regression.oneShot(biasedX, y, lambda);
          const rSquared = regression.rSquared(biasedX, y, betaVector);
          const tValue = regression.tValue(biasedX, y, betaVector);
          /* eslint-disable new-cap */
          const tdist = distributions.Studentt(localCount - betaVector.length);
          /* eslint-disable new-cap */
          const tcdf = tValue.map(r => tdist.cdf(Math.abs(r)));
          const pValue = n.mul(2, n.sub(1, tcdf));
          const localMeanY = n.sum(y) / localCount;

          /* eslint-disable no-console */
          console.log('X is:', biasedX);
          console.log('y is:', y);
          console.log('beta vector is:', betaVector);
          console.log('local r squared for original betaVector:', rSquared);
          console.log('local t Values for original betaVector:', tValue);
          console.log('local p values for original betaVector:', pValue);
          /* eslint-enable no-console */

          return {
            betaVector,
            localCount,
            localMeanY,
            rSquared,
            tValue,
            pValue,
            biasedX,
            y,
          };
        });
    },
    inputs: [{
      help: 'Select Freesurfer region(s) of interest',
      label: 'Freesurfer ROI',
      type: 'select',
      values: FreeSurfer.validFields,
    }, {
      defaultValue: DEFAULT_LAMBDA,
      label: 'Lambda',
      max: 1,
      min: 0,
      step: 0.05,
      type: 'number',
    }, {
      label: 'Covariates',
      type: 'covariates',
    }],
  }, {
    // step two: receive the globalMeanY and averageBetaVector,
    //  then calculate sseLocal, sstLocal and varXLocal
    type: 'function',
    fn(opts) {
      // use deconstructing to assign variables
      const {
        previousData: {
          betaVector,
          biasedX,
          pValue,
          rSquared,
          tValue,
          y,
         },
        remoteResult: {
           data: {
             averageBetaVector,
             globalMeanY,
              },
            },
      } = opts;

      const localCount = y.length;
      const rSquaredLocal = regression.rSquared(biasedX, y, averageBetaVector);
      const tValueLocal = regression.tValue(biasedX, y, averageBetaVector);
      /* eslint-disable new-cap */
      const tDist = distributions.Studentt(localCount - averageBetaVector.length);
      /* eslint-disable new-cap */
      const tCdf = tValueLocal.map(r => tDist.cdf(Math.abs((r))));
      const pValueLocal = n.mul(2, n.sub(1, tCdf));
      const sseLocal = n.sum(n.pow(n.sub(y, n.dot(biasedX, averageBetaVector)), 2));
      const sstLocal = n.sum(n.pow(n.sub(y, n.rep(n.dim(y), globalMeanY)), 2));
      const varXLocalMatrix = n.dot(n.transpose(biasedX), biasedX);

      /* eslint-disable no-console */
      console.log('local r squared for averageBetaVector', rSquaredLocal);
      console.log('local t Values for averageBetaVector', tValueLocal);
      console.log('local p Values for averageBetaVector', pValueLocal);
      /* eslint-enable no-console */

      return {
        betaVector,
        sseLocal,
        sstLocal,
        varXLocalMatrix,
        averageBetaVector,
        localCount,
        rSquared,
        tValue,
        pValue,
        rSquaredLocal,
        tValueLocal,
        pValueLocal,
      };
    },

  }],
  remote: [{
    type: 'function',
    fn(opts) {
      const userResults = opts.userResults;

      // Not all user results contain betas. Return early.
      if (userResults.some(userResult => !get(userResult, 'data.betaVector'))) {
        return {};
      }

      // calculate averageBetaVector
      const averageBetaVector = [];
      const betaCount = userResults[0].data.betaVector.length;
      const userCount = userResults.length;

      for (let i = 0; i < betaCount; i += 1) {
        averageBetaVector.push(userResults.reduce(
          (sum, userResult) => sum + userResult.data.betaVector[i], 0
        ) / userCount);
      }

      // calculate globalMeanY (rewrite it using more concise way)

      const globalMeanY =
          n.sum(
             userResults.map(result => result.data.localMeanY * result.data.localCount)
          ) /
          n.sum(
             userResults.map(result => result.data.localCount)
          );

      /* eslint-disable no-console */
      console.log('Average beta vector:', averageBetaVector);
      console.log('globalMeanY is :', globalMeanY);
      /* eslint-enable no-console */

      // Extract X and y variable name list from userData

      /* eslint-disable no-underscore-dangle */
      const yLabel = opts.userResults[0].userData.__FEATURES__;
      /* eslint-enable no-underscore-dangle */
      const xLabel = Object.keys(opts.userResults[0].userData.files[0].tags);

      /* eslint-disable no-console */
      console.log('xLabel is', xLabel);
      console.log('yLabel is', yLabel);
      /* eslint-enable no-console */

      return {
        averageBetaVector,
        globalMeanY,
        xLabel,
        yLabel,
      };
    },
    verbose: true,
  }, {
    // get sstNode from each local node and calculate the statistics
    type: 'function',
    fn(opts) {
      const {
       previousData: { xLabel, yLabel },
        userResults,
        userResults: [{
          data: { averageBetaVector },
        }],
      } = opts;

      const betaVectorLocal = userResults.map(r => r.data.betaVector);
      const rSquaredLocalOriginal = userResults.map(r => r.data.rSquared);
      const tValueLocalOriginal = userResults.map(r => r.data.tValue);
      const pValueLocalOriginal = userResults.map(r => r.data.pValue);
      const rSquaredLocal = userResults.map(r => r.data.rSquaredLocal);
      const tValueLocal = userResults.map(r => r.data.tValueLocal);
      const pValueLocal = userResults.map(r => r.data.pValueLocal);

      // calculate global parameters
      const sseGlobal = userResults.reduce((sum, userResult) => sum +
                        userResult.data.sseLocal, 0);
      const sstGlobal = userResults.reduce((sum, userResult) => sum +
                        userResult.data.sstLocal, 0);
      const globalYCount = userResults.reduce((sum, userResult) => sum +
                           userResult.data.localCount, 0);

      const varError = (1 / (globalYCount - averageBetaVector.length)) * sseGlobal;
      const seBetaGlobal = [];
      const tValueGlobal = [];

      // calculate tValueGlobal
      let varXGlobalMatrix = n.rep([averageBetaVector.length, averageBetaVector.length], 0);

      for (let i = 0; i < userResults.length; i += 1) {
        varXGlobalMatrix = n.add(varXGlobalMatrix, userResults[i].data.varXLocalMatrix);
      }

      /* eslint-disable no-console */
      console.log('varXGlobalMatrix is', varXGlobalMatrix);
      /* eslint-enable no-console */

      const varBetaGlobal = n.mul(n.inv(varXGlobalMatrix), varError);

      for (let i = 0; i < averageBetaVector.length; i += 1) {
        seBetaGlobal[i] = Math.sqrt(varBetaGlobal[i][i]);
        tValueGlobal[i] = averageBetaVector[i] / seBetaGlobal[i];
      }

      const rSquaredGlobal = 1 - (sseGlobal / sstGlobal);
      const tDist = distributions.Studentt(globalYCount - averageBetaVector.length);
      const tCdf = tValueGlobal.map(r => tDist.cdf(Math.abs(r)));
      const pValueGlobal = n.mul(2, (n.sub(1, tCdf))); // two tail pValue

      /* eslint-disable no-console */
      console.log('The global r squared for averageBetaVector :', rSquaredGlobal);
      console.log('The global t Values for averageBetaVector :', tValueGlobal);
      console.log('The global p Values for averageBetaVector :', pValueGlobal);
      /* eslint-disable no-console */

      const result = {
        betaVectorLocal,
        averageBetaVector,
        rSquaredLocalOriginal,
        tValueLocalOriginal,
        pValueLocalOriginal,
        rSquaredLocal,
        tValueLocal,
        pValueLocal,
        rSquaredGlobal,
        tValueGlobal,
        pValueGlobal,
        xLabel,
        yLabel,
        complete: true,
      };

      console.log('Final result!', result);

      return result;
    },
    verbose: true,
  }],
  plugins: ['group-step', 'inputs'],

};
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

/**
 * @fileoverview Caja is a whitelisting javascript sanitizing rewriter.
 * This file tames the APIs that are exposed to a gadget.
 */

caja___ = (function() {
  // currently limited to one cajoled gadget per ifr
  var tamingFrame;
  var tame___;      // tame___ === tamingFrame.contentWindow.___
  var guestFrame;
  var pendingScript;

  // URI policy: Rewrites all uris in a cajoled gadget
  var uriCallback = {
    rewrite: function rewrite(uri, mimeTypes) {
      uri = String(uri);
      if (/^#/.test(uri)) {
        // Allow references to anchors within the gadget
        return '#' + encodeURIComponent(decodeURIComponent(uri.substring(1)));
      } else if (/^\/[^\/]/.test(uri)) {
        // Unqualified uris aren't resolved in a useful way in gadgets, so
        // this isn't a real case, but some of the samples use relative
        // uris for images, and it looks odd if they don't work cajoled.
        return gadgets.io.getProxyUrl(
          location.protocol + '//' + location.host + uri);
      } else {
        // Proxy all other dynamically constructed urls
        return gadgets.io.getProxyUrl(uri);
      }
    }
  };

  function fire(globalScope) {
    for (var tamer in tamings___) {
      if (tamings___.hasOwnProperty(tamer)) {
        tamings___[tamer].call(tame___.USELESS, globalScope);
      }
    }
  }

  function getPendingScript() {
    return pendingScript;
  }

  function getTameGlobal() {
    return tamingFrame.contentWindow;
  }

  function getUseless() {
    return tame___ && tame___.USELESS;
  }

  function markTameAsFunction(func, name) {
    return tame___.markTameAsFunction(func, name);
  }

  function tame(obj) {
    return tame___.tame(obj);
  }

  function tamesTo(feral, tame) {
    tame___.tamesTo(feral, tame);
  }

  function untame(obj) {
    return tame___.untame(obj);
  }

  function whitelistCtors(schemas) {
    var length = schemas.length;
    for (var i = 0; i < length; i++) {
      var schema = schemas[i];
      if (typeof schema[0][schema[1]] === 'function') {
        tame___.markTameAsCtor(
            schema[0][schema[1]] /* func */,
            schema[2] /* parent */,
            schema[1] /* name */);
      } else {
        gadgets.warn('Error taming constructor: '
                     + schema[0] + '.' + schema[1]);
      }
    }
  }

  function whitelistFuncs(schemas) {
    var length = schemas.length;
    for (var i = 0; i < length; i++) {
      var schema = schemas[i];
      if (typeof schema[0][schema[1]] === 'function') {
        tame___.markTameAsFunction(schema[0][schema[1]], schema[1]);
      } else {
        gadgets.warn('Error taming function: ' + schema[0] + '.' + schema[1]);
      }
    }
  }

  function whitelistMeths(schemas) {
    var length = schemas.length;
    for (var i = 0; i < length; i++) {
      var schema = schemas[i];
      if (typeof schema[0].prototype[schema[1]] == 'function') {
        tame___.grantTameAsMethod(schema[0], schema[1]);
      } else {
        gadgets.warn('Error taming method: ' + schema[0] + '.' + schema[1]);
      }
    }
  }

  function whitelistProps(schemas) {
    var length = schemas.length;
    for (var i = 0; i < length; i++) {
      var schema = schemas[i];
      tame___.grantTameAsRead(schemas[0], schemas[1]);
    }
  }

  function makeFrame(id) {
    var frame = document.createElement('iframe');
    frame.style.display = 'none';
    frame.id = id;
    frame.height = 0;
    frame.width = 0;
    document.body.appendChild(frame);
    return frame;
  }

  function start(script, debug) {
    var debugArg = debug ? '?debug=1' : '';

    // guestFrame must be created before loadedTamingFrame fires
    guestFrame = makeFrame('caja-guest-frame');
    var gdoc = guestFrame.contentWindow.document;
    gdoc.write('\n');
    gdoc.write('


<commit_before>import 'babel-regenerator-runtime';
import 'source-map-support/register';
import Application from './application';
import memoryCache from './memory-cache';
import redisCache from './redis-cache';
import httpTransport from './http-transport';

const app = (options) => {
  return new Application(options);
};

app.memoryCache   = memoryCache;
app.redisCache    = redisCache;
app.httpTransport = httpTransport;

export default app;
<commit_msg>Created connection helper function<commit_after>import 'babel-regenerator-runtime';
import 'source-map-support/register';
import Application from './application';
import memoryCache from './memory-cache';
import redisCache from './redis-cache';
import httpTransport from './http-transport';

export { memoryCache, redisCache, httpTransport };

/**
 * Factory function that automatically starts the service
 * @param  {[type]}   options.name       [description]
 * @param  {[type]}   options.brokerPath [description]
 * @param  {[type]}   options.transport  [description]
 * @param  {[type]}   options.cache      [description]
 * @param  {Function} callback           [description]
 * @return {[type]}                      [description]
 */
export function connect({ name, brokerPath, transport, cache }, callback) {

  if(! (typeof arguments[0] == 'string' && typeof arguments[1] == 'string' && typeof arguments[2] !== 'function')) {

  }

  let service = new Application({ name });
  let wait = [];

  if(transport)
    wait.push(service.set('transport', transport));

  if(cache)
    wait.push(service.set('cache', cache));

  return Promise
    .all(wait)
    .then(() => service.start({ brokerPath }))
    .then(() => callback(service))
    .catch(e => {
      return service
        .stop()
        .then(() => console.log(e.stack))
        .catch(() => console.log(e.stack));
    });
};

/**
 * Default export of the application factory
 * @param  {[type]} options [description]
 * @return {[type]}         [description]
 */
export default function app(options) {
  return new Application(options);
};

app.memoryCache   = memoryCache;
app.redisCache    = redisCache;
app.httpTransport = httpTransport;

<|endoftext|>


<commit_before>import glob from 'glob'
import fromPairs from 'lodash.frompairs'

function entryName (globPattern, path) {
  return path
    .split('/')
    .pop()
    .split('.')
    .shift()
}

const PatternToEntries = entryNameFn => pattern => {
  const pairsOfEntries = glob
    .sync(pattern)
    .map(path => [entryNameFn(pattern, path), path])

  return fromPairs(pairsOfEntries)
}

export default function entry (entryNameFn, ...patterns) {
  if (entryNameFn instanceof String) {
    patterns.unshift(entryNameFn)
    entryNameFn = entryName
  } else if (!(entryNameFn instanceof Function)) {
    throw new TypeError('First parameter of entry must be String or Function')
  }

  const entries = patterns.map(PatternToEntries(entryNameFn))

  return Object.assign(...entries)
}
<commit_msg>fix: fix type check in entry function<commit_after>import glob from 'glob'
import fromPairs from 'lodash.frompairs'

function entryName (globPattern, path) {
  return path
    .split('/')
    .pop()
    .split('.')
    .shift()
}

const PatternToEntries = entryNameFn => pattern => {
  const pairsOfEntries = glob
    .sync(pattern)
    .map(path => [entryNameFn(pattern, path), path])

  return fromPairs(pairsOfEntries)
}

export default function entry (entryNameFn, ...patterns) {
  if (typeof entryNameFn === 'string') {
    patterns.unshift(entryNameFn)
    entryNameFn = entryName
  } else if (!(entryNameFn instanceof Function)) {
    throw new TypeError('First parameter of entry must be String or Function')
  }

  const entries = patterns.map(PatternToEntries(entryNameFn))

  return Object.assign(...entries)
}
<|endoftext|>


<commit_before>import _ from 'lodash';
import events from 'events';
import fs from 'fs';
import stream from 'stream';
import { GCodeParser } from 'gcode-parser';

const noop = () => {};

const streamify = (str) => {
    let s = new stream.Readable();
    s.push(str);
    s.push(null);
    return s;
};

const partitionWordsByGroup = (words) => {
    let groups = [];

    _.each(words, (word) => {
        let letter = word[0];
        let argument = word[1];

        if (_.includes(['G', 'M'], letter)) {
            groups.push([word]);
            return;
        }

        if (_.size(groups) > 0) {
            groups[groups.length - 1].push(word);
        } else {
            groups.push([word]);
        }
    });

    return groups;
};

const interpret = (self, data) => {
    let groups = partitionWordsByGroup(data.words);
    _.each(groups, (words) => {
        let word = words[0] || [];
        let letter = word[0];
        let arg = word[1];
        let cmd = (letter + arg);
        let args = {};

        if (_.includes(['G', 'M'], letter)) {
            self.cmd = cmd;
            args = _.fromPairs(words.slice(1)); // returns an object composed from arrays of property names and values
        } else {
            // Use the same command if the line does not start with Gxx or Mxx.
            // For example:
            // G0 Z0.25
            //  X-0.5 Y0.
            //  Z0.1
            // G01 Z0. F5.
            //  X0.5 Y0. I0. J-0.5
            //  X0. Y-0.5 I-0.5 J0.
            //  X-0.5 Y0. I0. J0.5
            cmd = self.cmd;
            args = _.fromPairs(words); // returns an object composed from arrays of property names and values.
        }

        if (typeof self.handlers[cmd] === 'function') {
            let func = self.handlers[cmd];
            func(args);
        }

        if (typeof self[cmd] === 'function') {
            let func = self[cmd].bind(self);
            func(args);
        }
    });
};

class GCodeInterpreter extends events.EventEmitter {
    cmd = '';
    handlers = {};

    constructor(options) {
        super();

        options = options || {};
        options.handlers = options.handlers || {};

        this.handlers = options.handlers;
    }
    loadFromStream(stream, callback = noop) {
        callback = callback || (() => {});

        try {
            let results = [];
            stream.pipe(new GCodeParser())
                .on('data', (data) => {
                    this.emit('data', data);
                    results.push(data);
                    interpret(this, data);
                })
                .on('progress', ({ current, total }) => {
                    this.emit('progress', { current, total });
                })
                .on('end', () => {
                    this.emit('end', results);
                    callback(null, results);
                })
                .on('error', (err) => {
                    callback(err);
                });
        }
        catch(err) {
            callback(err);
            return this;
        }

        return this;
    }
    loadFromFile(file, callback = noop) {
        file = file || '';
        let s = fs.createReadStream(file, { encoding: 'utf8' });
        s.on('error', callback);
        return this.loadFromStream(s, callback);
    }
    loadFromString(str, callback = noop) {
        let s = streamify(str);
        return this.loadFromStream(s, callback);
    }
}

export {
    GCodeInterpreter
};
<commit_msg>Upgrade gcode-parser to v0.8.0<commit_after>import _ from 'lodash';
import events from 'events';
import { parseFile, parseStream, parseString } from 'gcode-parser';

const noop = () => {};

const partitionWordsByGroup = (words) => {
    let groups = [];

    _.each(words, (word) => {
        let letter = word[0];
        let argument = word[1];

        if (_.includes(['G', 'M'], letter)) {
            groups.push([word]);
            return;
        }

        if (_.size(groups) > 0) {
            groups[groups.length - 1].push(word);
        } else {
            groups.push([word]);
        }
    });

    return groups;
};

const interpret = (self, data) => {
    let groups = partitionWordsByGroup(data.words);
    _.each(groups, (words) => {
        let word = words[0] || [];
        let letter = word[0];
        let arg = word[1];
        let cmd = (letter + arg);
        let args = {};

        if (_.includes(['G', 'M'], letter)) {
            self.cmd = cmd;
            args = _.fromPairs(words.slice(1)); // returns an object composed from arrays of property names and values
        } else {
            // Use the same command if the line does not start with Gxx or Mxx.
            // For example:
            // G0 Z0.25
            //  X-0.5 Y0.
            //  Z0.1
            // G01 Z0. F5.
            //  X0.5 Y0. I0. J-0.5
            //  X0. Y-0.5 I-0.5 J0.
            //  X-0.5 Y0. I0. J0.5
            cmd = self.cmd;
            args = _.fromPairs(words); // returns an object composed from arrays of property names and values.
        }

        if (typeof self.handlers[cmd] === 'function') {
            let func = self.handlers[cmd];
            func(args);
        }

        if (typeof self[cmd] === 'function') {
            let func = self[cmd].bind(self);
            func(args);
        }
    });
};

class GCodeInterpreter extends events.EventEmitter {
    cmd = '';
    handlers = {};

    constructor(options) {
        super();

        options = options || {};
        options.handlers = options.handlers || {};

        this.handlers = options.handlers;
    }
    loadFromStream(stream, callback = noop) {
        let s = parseStream(stream, callback);
        s.on('data', (data) => {
            interpret(this, data);
        });
        return s;
    }
    loadFromFile(file, callback = noop) {
        let s = parseFile(file, callback);
        s.on('data', (data) => {
            interpret(this, data);
        });
        return s;
    }
    loadFromString(str, callback = noop) {
        let s = parseString(str, callback);
        s.on('data', (data) => {
            interpret(this, data);
        });
        return s;
    }
}

export {
    GCodeInterpreter
};
<|endoftext|>


<commit_before>var Server = require('./server.js')

var update = require('./update.js')

// this function is called when you want the server to die gracefully
// i.e. wait for existing connections
var gracefulShutdown = function () {
  Server.server.close(function () {
    process.exit()
  })

  // if after
  setTimeout(function () {
    process.exit()
  }, 10 * 1000)
}

// listen for TERM signal .e.g. kill
process.on('SIGTERM', gracefulShutdown)

// listen for INT signal e.g. Ctrl-C
process.on('SIGINT', gracefulShutdown)
<commit_msg>index doc<commit_after>//launch the server
var Server = require('./server.js')

var update = require('./update.js')

// this function is called when you want the server to die gracefully
// i.e. wait for existing connections
var gracefulShutdown = function () {
  Server.server.close(function () {
    process.exit()
  })

  // if after
  setTimeout(function () {
    process.exit()
  }, 10 * 1000)
}

// listen for TERM signal .e.g. kill
process.on('SIGTERM', gracefulShutdown)

// listen for INT signal e.g. Ctrl-C
process.on('SIGINT', gracefulShutdown)
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
  Dimensions,
  Modal,
  DeviceEventEmitter,
  TouchableWithoutFeedback,
  KeyboardAvoidingView,
  PanResponder,
  Animated,
} from 'react-native';
import PropTypes from 'prop-types';
import {
  View,
  initializeRegistryWithDefinitions,
  registerAnimation,
  createAnimation,
} from 'react-native-animatable';
import * as ANIMATION_DEFINITIONS from './animations';

import styles from './index.style.js';

// Override default animations
initializeRegistryWithDefinitions(ANIMATION_DEFINITIONS);

// Utility for creating custom animations
const makeAnimation = (name, obj) => {
  registerAnimation(name, createAnimation(obj));
};

const isObject = obj => {
  return obj !== null && typeof obj === 'object';
};

const horizontalDirections = direction => {
  return direction == 'right' || direction == 'left';
}

export class ReactNativeModal extends Component {
  static propTypes = {
    animationIn: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    animationInTiming: PropTypes.number,
    animationOut: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    animationOutTiming: PropTypes.number,
    avoidKeyboard: PropTypes.bool,
    backdropColor: PropTypes.string,
    backdropOpacity: PropTypes.number,
    backdropTransitionInTiming: PropTypes.number,
    backdropTransitionOutTiming: PropTypes.number,
    children: PropTypes.node.isRequired,
    isVisible: PropTypes.bool.isRequired,
    onModalShow: PropTypes.func,
    onModalHide: PropTypes.func,
    onBackButtonPress: PropTypes.func,
    onBackdropPress: PropTypes.func,
    onSwipe: PropTypes.func,
    onSwipeThreshold: PropTypes.number,
    useNativeDriver: PropTypes.bool,
    style: PropTypes.any,
    swipeDirection: PropTypes.string,
  };

  static defaultProps = {
    animationIn: 'slideInUp',
    animationInTiming: 300,
    animationOut: 'slideOutDown',
    animationOutTiming: 300,
    avoidKeyboard: false,
    backdropColor: 'black',
    backdropOpacity: 0.7,
    backdropTransitionInTiming: 300,
    backdropTransitionOutTiming: 300,
    onModalShow: () => null,
    onModalHide: () => null,
    isVisible: false,
    onBackdropPress: () => null,
    onBackButtonPress: () => null,
    onSwipe: () => null,
    onSwipeThreshold: 100,
    useNativeDriver: false,
    swipeDirection: null,
  };

  // We use an internal state for keeping track of the modal visibility: this allows us to keep
  // the modal visibile during the exit animation, even if the user has already change the
  // isVisible prop to false.
  // We also store in the state the device width and height so that we can update the modal on
  // device rotation.
  state = {
    isVisible: false,
    deviceWidth: Dimensions.get('window').width,
    deviceHeight: Dimensions.get('window').height,
    pan: new Animated.ValueXY(),
  };

  transitionLock = null;

  constructor(props) {
    super(props);
    this._buildAnimations(props);
  }

  componentWillReceiveProps(nextProps) {
    if (!this.state.isVisible && nextProps.isVisible) {
      this.setState({ isVisible: true });
    }
    if (
      this.props.animationIn !== nextProps.animationIn ||
      this.props.animationOut !== nextProps.animationOut
    ) {
      this._buildAnimations(nextProps);
    }
  }

  componentWillMount() {
    if (this.props.isVisible) {
      this.setState({ isVisible: true });
    }
    if (this.props.swipeDirection) {
      this._buildPanResponder(this.props);
    }
  }

  componentDidMount() {
    if (this.state.isVisible) {
      this._open();
    }
    DeviceEventEmitter.addListener('didUpdateDimensions', this._handleDimensionsUpdate);
  }

  componentWillUnmount() {
    DeviceEventEmitter.removeListener('didUpdateDimensions', this._handleDimensionsUpdate);
  }

  componentDidUpdate(prevProps, prevState) {
    // On modal open request, we slide the view up and fade in the backdrop
    if (this.props.isVisible && !prevProps.isVisible) {
      this._open();
    }
    // On modal close request, we slide the view down and fade out the backdrop
    else if (!this.props.isVisible && prevProps.isVisible) {
      this._close();
    }
  }

  _buildPanResponder = props => {

    let animEvt = null;

    if ( horizontalDirections(this.props.swipeDirection) ) {
      animEvt = Animated.event([null,{
        dx : this.state.pan.x,
      }]);
    }
    else {
      animEvt = Animated.event([null,{
        dy : this.state.pan.y,
      }]);
    }

    this.panResponder = PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onPanResponderMove: (evt, gestureState) => {
        if ( this._isSwipeDirectionAllowed(gestureState) ) {
          this.backdropRef.transitionTo({ opacity: this.props.backdropOpacity * (1 - (this._getAccDistancePerDirection(gestureState) / this.state.deviceWidth))});
          animEvt(evt, gestureState);
        }
      },
      onPanResponderRelease: (evt, gestureState) => {
        if (this._getAccDistancePerDirection(gestureState) > this.props.onSwipeThreshold) {
          this.props.onSwipe();
          return;
        }

        this.backdropRef.transitionTo({ opacity: this.props.backdropOpacity });
        Animated.spring(
          this.state.pan,
          { toValue: {x: 0, y: 0} }
        ).start();
      }
    });
  }

  _getAccDistancePerDirection = gestureState => {
    switch (this.props.swipeDirection) {
      case 'top':
        return -gestureState.dy;
      case 'bottom':
        return gestureState.dy;
      case 'right':
        return gestureState.dx;
      case 'left':
        return -gestureState.dx;
      default:
        return 0;
    }
  }

  _isSwipeDirectionAllowed = ({dy, dx}) => {
    const draggedDown = dy > 0;
    const draggedUp = dy < 0;
    const draggedLeft = dx < 0;
    const draggedRight = dx > 0;

    switch (this.props.swipeDirection) {
      case 'top':
        if (draggedUp) return true;
        break;
      case 'bottom':
        if (draggedDown) return true;
        break;
      case 'right':
        if (draggedRight) return true;
        break;
      case 'left':
        if (draggedLeft) return true;
        break;
      default:
        return false;
    }

    return false;
  }

  // User can define custom react-native-animatable animations, see PR #72
  _buildAnimations = props => {
    let animationIn = props.animationIn;
    let animationOut = props.animationOut;

    if (isObject(animationIn)) {
      makeAnimation('animationIn', animationIn);
      animationIn = 'animationIn';
    }

    if (isObject(animationOut)) {
      makeAnimation('animationOut', animationOut);
      animationOut = 'animationOut';
    }

    this.animationIn = animationIn;
    this.animationOut = animationOut;
  };

  _handleDimensionsUpdate = dimensionsUpdate => {
    // Here we update the device dimensions in the state if the layout changed (triggering a render)
    const deviceWidth = Dimensions.get('window').width;
    const deviceHeight = Dimensions.get('window').height;
    if (deviceWidth !== this.state.deviceWidth || deviceHeight !== this.state.deviceHeight) {
      this.setState({ deviceWidth, deviceHeight });
    }
  };

  _open = () => {
    if (this.transitionLock) return;
    this.transitionLock = true;
    this.backdropRef.transitionTo(
      { opacity: this.props.backdropOpacity },
      this.props.backdropTransitionInTiming,
    );

    // This is for reset the pan position, if not modal get stuck
    // at the last release position when you try to open it.
    // Could certainly be improve - no idea for the moment.
    this.state.pan.setValue({ x: 0, y: 0});

    this.contentRef[this.animationIn](this.props.animationInTiming).then(() => {
      this.transitionLock = false;
      if (!this.props.isVisible) {
        this._close();
      }
      else {
        this.props.onModalShow();
      }
    });
  };

  _close = () => {
    if (this.transitionLock) return;
    this.transitionLock = true;
    this.backdropRef.transitionTo({ opacity: 0 }, this.props.backdropTransitionOutTiming);
    this.contentRef[this.animationOut](this.props.animationOutTiming).then(() => {
      this.transitionLock = false;
      if (this.props.isVisible) {
        this._open();
      }
      else {
        this.setState({ isVisible: false });
        this.props.onModalHide();
      }
    });
  };

  render() {
    const {
      animationIn,
      animationInTiming,
      animationOut,
      animationOutTiming,
      avoidKeyboard,
      backdropColor,
      backdropOpacity,
      backdropTransitionInTiming,
      backdropTransitionOutTiming,
      children,
      isVisible,
      onModalShow,
      onBackdropPress,
      onBackButtonPress,
      useNativeDriver,
      style,
      ...otherProps
    } = this.props;
    const { deviceWidth, deviceHeight } = this.state;

    const computedStyle = [
      { margin: deviceWidth * 0.05, transform: [{ translateY: 0 }] },
      styles.content,
      style,
    ];

    const containerView = (
      <View
        { ...this.panResponder.panHandlers }
        ref={ref => (this.contentRef = ref)}
        style={[this.state.pan.getLayout(), computedStyle]}
        pointerEvents={'box-none'}
        useNativeDriver={useNativeDriver}
        onLayout={this._containerViewOnLayout}
        {...otherProps}
      >
        {children}
      </View>
    );

    return (
      <Modal
        transparent={true}
        animationType={'none'}
        visible={this.state.isVisible}
        onRequestClose={onBackButtonPress}
        {...otherProps}
      >
        <TouchableWithoutFeedback onPress={onBackdropPress}>
          <View
            ref={ref => (this.backdropRef = ref)}
            useNativeDriver={useNativeDriver}
            style={[
              styles.backdrop,
              {
                backgroundColor: backdropColor,
                width: deviceWidth,
                height: deviceHeight,
              },
            ]}
          />
        </TouchableWithoutFeedback>

          {avoidKeyboard && (
            <KeyboardAvoidingView
              behavior={'padding'}
              pointerEvents={'box-none'}
              style={computedStyle.concat([{ margin: 0 }])}
            >
              {containerView}
            </KeyboardAvoidingView>
          )}

          {!avoidKeyboard && containerView}
      </Modal>
    );
  }
}

export default ReactNativeModal;<commit_msg>Ignore animationOut when onSwipe is called, reset position if onSwipe not set<commit_after>import React, { Component } from 'react';
import {
  Dimensions,
  Modal,
  DeviceEventEmitter,
  TouchableWithoutFeedback,
  KeyboardAvoidingView,
  PanResponder,
  Animated,
} from 'react-native';
import PropTypes from 'prop-types';
import {
  View,
  initializeRegistryWithDefinitions,
  registerAnimation,
  createAnimation,
} from 'react-native-animatable';
import * as ANIMATION_DEFINITIONS from './animations';

import styles from './index.style.js';

// Override default animations
initializeRegistryWithDefinitions(ANIMATION_DEFINITIONS);

// Utility for creating custom animations
const makeAnimation = (name, obj) => {
  registerAnimation(name, createAnimation(obj));
};

const isObject = obj => {
  return obj !== null && typeof obj === 'object';
};

const horizontalDirections = direction => {
  return direction == 'right' || direction == 'left';
}

export class ReactNativeModal extends Component {
  static propTypes = {
    animationIn: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    animationInTiming: PropTypes.number,
    animationOut: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    animationOutTiming: PropTypes.number,
    avoidKeyboard: PropTypes.bool,
    backdropColor: PropTypes.string,
    backdropOpacity: PropTypes.number,
    backdropTransitionInTiming: PropTypes.number,
    backdropTransitionOutTiming: PropTypes.number,
    children: PropTypes.node.isRequired,
    isVisible: PropTypes.bool.isRequired,
    onModalShow: PropTypes.func,
    onModalHide: PropTypes.func,
    onBackButtonPress: PropTypes.func,
    onBackdropPress: PropTypes.func,
    onSwipe: PropTypes.func,
    onSwipeThreshold: PropTypes.number,
    useNativeDriver: PropTypes.bool,
    style: PropTypes.any,
    swipeDirection: PropTypes.string,
  };

  static defaultProps = {
    animationIn: 'slideInUp',
    animationInTiming: 300,
    animationOut: 'slideOutDown',
    animationOutTiming: 300,
    avoidKeyboard: false,
    backdropColor: 'black',
    backdropOpacity: 0.7,
    backdropTransitionInTiming: 300,
    backdropTransitionOutTiming: 300,
    onModalShow: () => null,
    onModalHide: () => null,
    isVisible: false,
    onBackdropPress: () => null,
    onBackButtonPress: () => null,
    onSwipeThreshold: 100,
    useNativeDriver: false,
    swipeDirection: null,
  };

  // We use an internal state for keeping track of the modal visibility: this allows us to keep
  // the modal visibile during the exit animation, even if the user has already change the
  // isVisible prop to false.
  // We also store in the state the device width and height so that we can update the modal on
  // device rotation.
  state = {
    isVisible: false,
    deviceWidth: Dimensions.get('window').width,
    deviceHeight: Dimensions.get('window').height,
    pan: this.props.swipeDirection ? new Animated.ValueXY() : null,
  };

  transitionLock = null;

  constructor(props) {
    super(props);
    this._buildAnimations(props);
  }

  componentWillReceiveProps(nextProps) {
    if (!this.state.isVisible && nextProps.isVisible) {
      this.setState({ isVisible: true });
    }
    if (
      this.props.animationIn !== nextProps.animationIn ||
      this.props.animationOut !== nextProps.animationOut
    ) {
      this._buildAnimations(nextProps);
    }
  }

  componentWillMount() {
    if (this.props.isVisible) {
      this.setState({ isVisible: true });
    }
    if (this.props.swipeDirection) {
      this._buildPanResponder(this.props);
    }
  }

  componentDidMount() {
    if (this.state.isVisible) {
      this._open();
    }
    DeviceEventEmitter.addListener('didUpdateDimensions', this._handleDimensionsUpdate);
  }

  componentWillUnmount() {
    DeviceEventEmitter.removeListener('didUpdateDimensions', this._handleDimensionsUpdate);
  }

  componentDidUpdate(prevProps, prevState) {
    // On modal open request, we slide the view up and fade in the backdrop
    if (this.props.isVisible && !prevProps.isVisible) {
      this._open();
    }
    // On modal close request, we slide the view down and fade out the backdrop
    else if (!this.props.isVisible && prevProps.isVisible) {
      this._close();
    }
  }

  _buildPanResponder = props => {
    let animEvt = null;

    if (horizontalDirections(this.props.swipeDirection)) {
      animEvt = Animated.event([null,{ dx : this.state.pan.x }]);
    }
    else {
      animEvt = Animated.event([null,{ dy : this.state.pan.y }]);
    }

    this.panResponder = PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onPanResponderMove: (evt, gestureState) => {
        if (this._isSwipeDirectionAllowed(gestureState)) {
          this.backdropRef.transitionTo({ opacity: this.props.backdropOpacity * (1 - (this._getAccDistancePerDirection(gestureState) / this.state.deviceWidth))});
          animEvt(evt, gestureState);
        }
      },
      onPanResponderRelease: (evt, gestureState) => {
        if (this._getAccDistancePerDirection(gestureState) > this.props.onSwipeThreshold) {
          if ( this.props.onSwipe ) {
            this.inSwipeClosingState = true;
            this.props.onSwipe();
            return;
          }
        }

        //Reset backdrop opacity & modal position
        this.backdropRef.transitionTo({ opacity: this.props.backdropOpacity }, this.props.backdropTransitionInTiming);
        Animated.spring(
          this.state.pan,
          { toValue: {x: 0, y: 0} }
        ).start();
      }
    });
  }

  _getAccDistancePerDirection = gestureState => {
    switch (this.props.swipeDirection) {
      case 'top':
        return -gestureState.dy;
      case 'bottom':
        return gestureState.dy;
      case 'right':
        return gestureState.dx;
      case 'left':
        return -gestureState.dx;
      default:
        return 0;
    }
  }

  _isSwipeDirectionAllowed = ({dy, dx}) => {
    const draggedDown = dy > 0;
    const draggedUp = dy < 0;
    const draggedLeft = dx < 0;
    const draggedRight = dx > 0;

    switch (this.props.swipeDirection) {
      case 'top':
        if (draggedUp) return true;
        break;
      case 'bottom':
        if (draggedDown) return true;
        break;
      case 'right':
        if (draggedRight) return true;
        break;
      case 'left':
        if (draggedLeft) return true;
        break;
      default:
        return false;
    }

    return false;
  }

  // User can define custom react-native-animatable animations, see PR #72
  _buildAnimations = props => {
    let animationIn = props.animationIn;
    let animationOut = props.animationOut;

    if (isObject(animationIn)) {
      makeAnimation('animationIn', animationIn);
      animationIn = 'animationIn';
    }

    if (isObject(animationOut)) {
      makeAnimation('animationOut', animationOut);
      animationOut = 'animationOut';
    }

    this.animationIn = animationIn;
    this.animationOut = animationOut;
  };

  _handleDimensionsUpdate = dimensionsUpdate => {
    // Here we update the device dimensions in the state if the layout changed (triggering a render)
    const deviceWidth = Dimensions.get('window').width;
    const deviceHeight = Dimensions.get('window').height;
    if (deviceWidth !== this.state.deviceWidth || deviceHeight !== this.state.deviceHeight) {
      this.setState({ deviceWidth, deviceHeight });
    }
  };

  _open = () => {
    if (this.transitionLock) return;
    this.transitionLock = true;
    this.backdropRef.transitionTo(
      { opacity: this.props.backdropOpacity },
      this.props.backdropTransitionInTiming,
    );

    // This is for reset the pan position, if not modal get stuck
    // at the last release position when you try to open it.
    // Could certainly be improve - no idea for the moment.
    if ( this.state.pan ) {
      this.state.pan.setValue({ x: 0, y: 0});
    }

    this.contentRef[this.animationIn](this.props.animationInTiming).then(() => {
      this.transitionLock = false;
      if (!this.props.isVisible) {
        this._close();
      }
      else {
        this.props.onModalShow();
      }
    });
  };

  _close = () => {
    if (this.transitionLock) return;
    this.transitionLock = true;
    this.backdropRef.transitionTo({ opacity: 0 }, this.props.backdropTransitionOutTiming);

    let animationOut = this.animationOut;

    if ( this.inSwipeClosingState ) {
      this.inSwipeClosingState = false;
      switch (this.props.swipeDirection) {
        case 'top':
          animationOut = 'slideOutUp';
          break;
        case 'bottom':
          animationOut = 'slideOutDown';
          break;
        case 'right':
          animationOut = 'slideOutRight';
          break;
        case 'left':
          animationOut = 'slideOutLeft';
          break;
      }
    }

    this.contentRef[animationOut](this.props.animationOutTiming).then(() => {
      this.transitionLock = false;
      if (this.props.isVisible) {
        this._open();
      }
      else {
        this.setState({ isVisible: false });
        this.props.onModalHide();
      }
    });
  };

  render() {
    const {
      animationIn,
      animationInTiming,
      animationOut,
      animationOutTiming,
      avoidKeyboard,
      backdropColor,
      backdropOpacity,
      backdropTransitionInTiming,
      backdropTransitionOutTiming,
      children,
      isVisible,
      onModalShow,
      onBackdropPress,
      onBackButtonPress,
      useNativeDriver,
      style,
      ...otherProps
    } = this.props;
    const { deviceWidth, deviceHeight } = this.state;

    const computedStyle = [
      { margin: deviceWidth * 0.05, transform: [{ translateY: 0 }] },
      styles.content,
      style,
    ];

    const panHandlers = this.props.swipeDirection ? { ...this.panResponder.panHandlers } : {};
    const panPosition = this.state.pan ? this.state.pan.getLayout() : {};

    const containerView = (
      <View
        { ...panHandlers }
        ref={ref => (this.contentRef = ref)}
        style={[panPosition, computedStyle]}
        pointerEvents={'box-none'}
        useNativeDriver={useNativeDriver}
        onLayout={this._containerViewOnLayout}
        {...otherProps}
      >
        {children}
      </View>
    );

    return (
      <Modal
        transparent={true}
        animationType={'none'}
        visible={this.state.isVisible}
        onRequestClose={onBackButtonPress}
        {...otherProps}
      >
        <TouchableWithoutFeedback onPress={onBackdropPress}>
          <View
            ref={ref => (this.backdropRef = ref)}
            useNativeDriver={useNativeDriver}
            style={[
              styles.backdrop,
              {
                backgroundColor: backdropColor,
                width: deviceWidth,
                height: deviceHeight,
              },
            ]}
          />
        </TouchableWithoutFeedback>

          {avoidKeyboard && (
            <KeyboardAvoidingView
              behavior={'padding'}
              pointerEvents={'box-none'}
              style={computedStyle.concat([{ margin: 0 }])}
            >
              {containerView}
            </KeyboardAvoidingView>
          )}

          {!avoidKeyboard && containerView}
      </Modal>
    );
  }
}

export default ReactNativeModal;<|endoftext|>


<commit_before>// @flow
import React from 'react'
import {connect} from 'react-redux'
import {navigateUp} from '../../../actions/route-tree'
import {showEditor} from '../../../actions/chat'
import {NativeClipboard, PopupMenu} from '../../../common-adapters/index.native'
import MessagePopupHeader from './popup-header'

import type {TextProps} from './popup'
import type {RouteProps} from '../../../route-tree/render-route'
import type {TypedState} from '../../../constants/reducer'
import type {ServerMessage, TextMessage} from '../../../constants/chat'

function MessagePopup ({message, onShowEditor, onHidden}: TextProps) {
  if (message.type !== 'Text' && message.type !== 'Attachment') return null

  const items = []

  if (message.type === 'Text') {
    const textMessage: TextMessage = message

    items.push({
      onClick: () => {
        onShowEditor(message)
        onHidden()
      },
      title: 'Edit',
    })
    items.push({
      onClick: () => {
        NativeClipboard.setString(textMessage.message.stringValue())
        onHidden()
      },
      title: 'Copy Text',
    })
  }

  const menuProps = {
    header: {
      title: 'header',
      view: <MessagePopupHeader message={message} />,
    },
    items,
    onHidden,
  }

  return (
    <PopupMenu {...menuProps} />
  )
}

type MessagePopupRouteProps = RouteProps<{
  message: ServerMessage,
  onShowEditor: (message: TextMessage) => void,
}, {}>
type OwnProps = MessagePopupRouteProps & {}

export default connect(
  (state: TypedState, {routeProps}: OwnProps) => {
    const {message} = routeProps
    return {
      message,
    }
  },
  (dispatch: Dispatch, {routeProps}: OwnProps) => ({
    onHidden: () => dispatch(navigateUp()),
    onShowEditor: () => dispatch(showEditor(routeProps.message)),
  })
)(MessagePopup)
<commit_msg>Hook up message deletion<commit_after>// @flow
import React from 'react'
import {connect} from 'react-redux'
import {navigateUp} from '../../../actions/route-tree'
import {deleteMessage, showEditor} from '../../../actions/chat'
import {NativeClipboard, PopupMenu} from '../../../common-adapters/index.native'
import MessagePopupHeader from './popup-header'

import type {TextProps} from './popup'
import type {RouteProps} from '../../../route-tree/render-route'
import type {TypedState} from '../../../constants/reducer'
import type {ServerMessage, TextMessage} from '../../../constants/chat'

function MessagePopup ({message, onDeleteMessage, onHidden, onShowEditor}: TextProps) {
  if (message.type !== 'Text' && message.type !== 'Attachment') return null

  const items = []

  if (message.type === 'Text') {
    const textMessage: TextMessage = message

    items.push({
      onClick: () => {
        onShowEditor(message)
        onHidden()
      },
      title: 'Edit',
    })
    items.push({
      onClick: () => {
        NativeClipboard.setString(textMessage.message.stringValue())
        onHidden()
      },
      title: 'Copy Text',
    })
  }

  items.push({
    danger: true,
    onClick: () => {
      onDeleteMessage(message)
      onHidden()
    },
    title: 'Delete',
  })

  const menuProps = {
    header: {
      title: 'header',
      view: <MessagePopupHeader message={message} />,
    },
    items,
    onHidden,
  }

  return (
    <PopupMenu {...menuProps} />
  )
}

type MessagePopupRouteProps = RouteProps<{
  message: ServerMessage,
  onShowEditor: (message: TextMessage) => void,
}, {}>
type OwnProps = MessagePopupRouteProps & {}

export default connect(
  (state: TypedState, {routeProps}: OwnProps) => {
    const {message} = routeProps
    return {
      message,
    }
  },
  (dispatch: Dispatch, {routeProps}: OwnProps) => ({
    onDeleteMessage: (message: ServerMessage) => { dispatch(deleteMessage(message)) },
    onHidden: () => dispatch(navigateUp()),
    onShowEditor: () => dispatch(showEditor(routeProps.message)),
  })
)(MessagePopup)
<|endoftext|>


<commit_before>'use strict';

const app = require('./app');
const port = app.get('port');
const server = app.listen(port);

server.on('listening', () =>
  console.log(`Feathers application started on ${app.get('host')}:${port}`)
);
<commit_msg>Updates to packages.json<commit_after>'use strict';

const app = require('./app');
const port = app.get('port');
const server = app.listen(process.env.PORT);

server.on('listening', () =>
  console.log(`Feathers application started on ${app.get('host')}:${port}`)
);
<|endoftext|>


<commit_before>// @flow
import * as React from 'react'
import * as Kb from '../../../common-adapters'
import * as Styles from '../../../styles'
import {ParticipantsRow} from '../../common'
import {isLargeScreen} from '../../../constants/platform'
import {SelectedEntry, DropdownEntry, DropdownText} from './dropdown'
import Search from './search'
import type {Account} from '.'
import {debounce} from 'lodash-es'

type ToKeybaseUserProps = {|
  isRequest: boolean,
  recipientUsername: string,
  errorMessage?: string,
  onShowProfile: string => void,
  onShowSuggestions: () => void,
  onRemoveProfile: () => void,
  onChangeRecipient: string => void,
  onScanQRCode: ?() => void,
|}

const placeholderExample = isLargeScreen ? 'Ex: G12345... or you*example.com' : 'G12.. or you*example.com'

const ToKeybaseUser = (props: ToKeybaseUserProps) => {
  if (props.recipientUsername) {
    // A username has been set, so display their name and avatar.
    return (
      <ParticipantsRow
        heading={props.isRequest ? 'From' : 'To'}
        headingAlignment="Left"
        dividerColor={props.errorMessage ? Styles.globalColors.red : ''}
        style={styles.toKeybaseUser}
      >
        <Kb.Box2 direction="vertical" fullWidth={true} style={styles.inputBox}>
          <Kb.Box2 direction="horizontal" centerChildren={true} fullWidth={true}>
            <Kb.ConnectedNameWithIcon
              colorFollowing={true}
              horizontal={true}
              containerStyle={styles.toKeybaseUserNameWithIcon}
              username={props.recipientUsername}
              avatarStyle={styles.avatar}
              avatarSize={32}
              onClick="tracker"
            />
            <Kb.Icon
              type="iconfont-remove"
              boxStyle={Kb.iconCastPlatformStyles(styles.keybaseUserRemoveButton)}
              fontSize={16}
              color={Styles.globalColors.black_20}
              onClick={props.onRemoveProfile}
            />
          </Kb.Box2>
          {!!props.errorMessage && (
            <Kb.Text type="BodySmall" style={styles.errorText}>
              {props.errorMessage}
            </Kb.Text>
          )}
        </Kb.Box2>
      </ParticipantsRow>
    )
  }

  // No username, so show search box.
  return (
    <Search
      heading={props.isRequest ? 'From' : 'To'}
      onClickResult={props.onChangeRecipient}
      onShowSuggestions={props.onShowSuggestions}
      onShowTracker={props.onShowProfile}
      onScanQRCode={props.onScanQRCode}
    />
  )
}

type ToStellarPublicKeyProps = {|
  recipientPublicKey: string,
  errorMessage?: string,
  onChangeRecipient: string => void,
  onScanQRCode: ?() => void,
  setReadyToReview: boolean => void,
  keyCounter: number,
|}

type ToStellarPublicKeyState = {|
  recipientPublicKey: string,
|}

class ToStellarPublicKey extends React.Component<ToStellarPublicKeyProps, ToStellarPublicKeyState> {
  state = {recipientPublicKey: this.props.recipientPublicKey}
  _propsOnChangeRecipient = debounce(this.props.onChangeRecipient, 1e3)
  _onChangeRecipient = recipientPublicKey => {
    this.setState({recipientPublicKey})
    this.props.setReadyToReview(false)
    this._propsOnChangeRecipient(recipientPublicKey)
  }

  render = () => (
    <ParticipantsRow
      heading="To"
      headingAlignment="Left"
      headingStyle={styles.heading}
      dividerColor={this.props.errorMessage ? Styles.globalColors.red : ''}
      style={styles.toStellarPublicKey}
    >
      <Kb.Box2 direction="vertical" fullWidth={!Styles.isMobile} style={styles.inputBox}>
        <Kb.Box2 direction="horizontal" gap="xxtiny" fullWidth={!Styles.isMobile} style={styles.inputInner}>
          <Kb.Icon
            type="iconfont-identity-stellar"
            color={
              this.state.recipientPublicKey.length === 0 || this.props.errorMessage
                ? Styles.globalColors.black_50
                : Styles.globalColors.black
            }
          />
          <Kb.Box2 direction="horizontal" style={styles.publicKeyInputContainer}>
            <Kb.NewInput
              type="text"
              onChangeText={this._onChangeRecipient}
              textType="BodySemibold"
              hideBorder={true}
              containerStyle={styles.input}
              multiline={true}
              rowsMin={2}
              rowsMax={3}
              value={this.state.recipientPublicKey}
            />
            {!this.state.recipientPublicKey && (
              <Kb.Box
                activeOpacity={1}
                pointerEvents="none"
                style={Styles.collapseStyles([Styles.globalStyles.fillAbsolute, styles.placeholderContainer])}
              >
                <Kb.Text type="BodySemibold" style={styles.colorBlack20}>
                  Stellar address
                </Kb.Text>
                <Kb.Text type="BodySemibold" style={styles.colorBlack20} lineClamp={1} ellipsizeMode="middle">
                  {placeholderExample}
                </Kb.Text>
              </Kb.Box>
            )}
          </Kb.Box2>
          {!this.state.recipientPublicKey && this.props.onScanQRCode && (
            <Kb.Icon
              color={Styles.globalColors.black_50}
              type="iconfont-qr-code"
              fontSize={24}
              onClick={this.props.onScanQRCode}
              style={Kb.iconCastPlatformStyles(styles.qrCode)}
            />
          )}
        </Kb.Box2>
        {!!this.props.errorMessage && (
          <Kb.Text type="BodySmall" style={styles.errorText}>
            {this.props.errorMessage}
          </Kb.Text>
        )}
      </Kb.Box2>
    </ParticipantsRow>
  )
}

type ToOtherAccountProps = {|
  user: string,
  toAccount?: Account,
  allAccounts: Account[],
  onChangeRecipient: string => void,
  onLinkAccount: () => void,
  onCreateNewAccount: () => void,
  showSpinner: boolean,
|}

class ToOtherAccount extends React.Component<ToOtherAccountProps> {
  onAccountDropdownChange = (node: React.Node) => {
    if (React.isValidElement(node)) {
      // $FlowIssue React.isValidElement refinement doesn't happen, see https://github.com/facebook/flow/issues/6392
      const element = (node: React.Element<any>)
      if (element.key === 'create-new') {
        this.props.onCreateNewAccount()
      } else if (element.key === 'link-existing') {
        this.props.onLinkAccount()
      } else {
        this.props.onChangeRecipient(element.props.account.id)
      }
    }
  }

  render = () => {
    if (this.props.allAccounts.length <= 1) {
      // A user is sending to another account, but has no other
      // accounts. Show a "create new account" button.
      return (
        <Kb.Box2 direction="horizontal" centerChildren={true} style={{width: 270}}>
          <Kb.Button
            type="Wallet"
            style={styles.createNewAccountButton}
            label="Create a new account"
            onClick={this.props.onCreateNewAccount}
          />
        </Kb.Box2>
      )
    }

    // A user is sending from an account to another account with other
    // accounts. Show a dropdown list of other accounts, in addition
    // to the link existing and create new actions.
    let items = [
      <DropdownText
        spinner={this.props.showSpinner}
        key="link-existing"
        text="Link an existing Stellar account"
      />,
      <DropdownText spinner={this.props.showSpinner} key="create-new" text="Create a new account" />,
    ]

    if (this.props.allAccounts.length > 0) {
      const walletItems = this.props.allAccounts.map(account => (
        <DropdownEntry key={account.id} account={account} user={this.props.user} />
      ))
      items = walletItems.concat(items)
    }

    return (
      <ParticipantsRow heading="To" headingAlignment="Right" style={styles.toAccountRow}>
        <Kb.Dropdown
          onChanged={this.onAccountDropdownChange}
          items={items}
          style={styles.dropdown}
          selectedBoxStyle={styles.dropdownSelectedBox}
          selected={
            this.props.toAccount ? (
              <SelectedEntry
                spinner={this.props.showSpinner}
                account={this.props.toAccount}
                user={this.props.user}
              />
            ) : (
              <DropdownText
                spinner={this.props.showSpinner}
                key="placeholder-select"
                text="Pick another account"
              />
            )
          }
        />
      </ParticipantsRow>
    )
  }
}

const styles = Styles.styleSheetCreate({
  avatar: {
    marginRight: 8,
  },
  colorBlack20: {
    color: Styles.globalColors.black_20,
  },
  createNewAccountButton: Styles.platformStyles({
    isElectron: {
      width: 194,
    },
  }),
  dropdown: Styles.platformStyles({
    isMobile: {height: 32},
  }),
  dropdownSelectedBox: Styles.platformStyles({
    isMobile: {minHeight: 32},
  }),
  errorText: Styles.platformStyles({
    common: {
      color: Styles.globalColors.red,
      width: '100%',
    },
    isElectron: {
      wordWrap: 'break-word',
    },
  }),
  heading: {
    alignSelf: 'flex-start',
  },
  input: Styles.platformStyles({
    common: {
      padding: 0,
    },
    isMobile: {
      paddingLeft: Styles.globalMargins.xtiny,
    },
  }),
  inputBox: Styles.platformStyles({isElectron: {flexGrow: 1}, isMobile: {flex: 1}}),
  inputInner: Styles.platformStyles({
    common: {
      alignItems: 'flex-start',
      flex: 1,
      position: 'relative',
    },
    isElectron: {
      flexShrink: 0,
    },
  }),
  keybaseUserRemoveButton: {
    flex: 1,
    marginRight: Styles.globalMargins.tiny,
    textAlign: 'right', // consistent with UserInput
  },
  placeholderContainer: Styles.platformStyles({
    common: {
      display: 'flex',
      flexDirection: 'column',
      paddingLeft: (Styles.isMobile ? 0 : 16) + 4,
    },
    isElectron: {
      pointerEvents: 'none',
    },
  }),
  publicKeyInputContainer: {flexGrow: 1, flexShrink: 1},
  qrCode: {
    marginRight: Styles.globalMargins.tiny,
    marginTop: Styles.globalMargins.tiny,
  },
  toAccountRow: Styles.platformStyles({
    isMobile: {
      height: 40,
      paddingBottom: 4,
      paddingTop: 4,
    },
  }),
  toKeybaseUser: {
    height: 48,
  },
  toKeybaseUserNameWithIcon: {
    flexGrow: 1,
  },
  toStellarPublicKey: {
    alignItems: 'flex-start',
    minHeight: 52,
  },
})

export type {ToKeybaseUserProps, ToStellarPublicKeyProps}

export {ToKeybaseUser, ToStellarPublicKey, ToOtherAccount}
<commit_msg>Make the Stellar logo smaller on mobile. (#16687)<commit_after>// @flow
import * as React from 'react'
import * as Kb from '../../../common-adapters'
import * as Styles from '../../../styles'
import {ParticipantsRow} from '../../common'
import {isLargeScreen} from '../../../constants/platform'
import {SelectedEntry, DropdownEntry, DropdownText} from './dropdown'
import Search from './search'
import type {Account} from '.'
import {debounce} from 'lodash-es'

type ToKeybaseUserProps = {|
  isRequest: boolean,
  recipientUsername: string,
  errorMessage?: string,
  onShowProfile: string => void,
  onShowSuggestions: () => void,
  onRemoveProfile: () => void,
  onChangeRecipient: string => void,
  onScanQRCode: ?() => void,
|}

const placeholderExample = isLargeScreen ? 'Ex: G12345... or you*example.com' : 'G12.. or you*example.com'

const ToKeybaseUser = (props: ToKeybaseUserProps) => {
  if (props.recipientUsername) {
    // A username has been set, so display their name and avatar.
    return (
      <ParticipantsRow
        heading={props.isRequest ? 'From' : 'To'}
        headingAlignment="Left"
        dividerColor={props.errorMessage ? Styles.globalColors.red : ''}
        style={styles.toKeybaseUser}
      >
        <Kb.Box2 direction="vertical" fullWidth={true} style={styles.inputBox}>
          <Kb.Box2 direction="horizontal" centerChildren={true} fullWidth={true}>
            <Kb.ConnectedNameWithIcon
              colorFollowing={true}
              horizontal={true}
              containerStyle={styles.toKeybaseUserNameWithIcon}
              username={props.recipientUsername}
              avatarStyle={styles.avatar}
              avatarSize={32}
              onClick="tracker"
            />
            <Kb.Icon
              type="iconfont-remove"
              boxStyle={Kb.iconCastPlatformStyles(styles.keybaseUserRemoveButton)}
              fontSize={16}
              color={Styles.globalColors.black_20}
              onClick={props.onRemoveProfile}
            />
          </Kb.Box2>
          {!!props.errorMessage && (
            <Kb.Text type="BodySmall" style={styles.errorText}>
              {props.errorMessage}
            </Kb.Text>
          )}
        </Kb.Box2>
      </ParticipantsRow>
    )
  }

  // No username, so show search box.
  return (
    <Search
      heading={props.isRequest ? 'From' : 'To'}
      onClickResult={props.onChangeRecipient}
      onShowSuggestions={props.onShowSuggestions}
      onShowTracker={props.onShowProfile}
      onScanQRCode={props.onScanQRCode}
    />
  )
}

type ToStellarPublicKeyProps = {|
  recipientPublicKey: string,
  errorMessage?: string,
  onChangeRecipient: string => void,
  onScanQRCode: ?() => void,
  setReadyToReview: boolean => void,
  keyCounter: number,
|}

type ToStellarPublicKeyState = {|
  recipientPublicKey: string,
|}

class ToStellarPublicKey extends React.Component<ToStellarPublicKeyProps, ToStellarPublicKeyState> {
  state = {recipientPublicKey: this.props.recipientPublicKey}
  _propsOnChangeRecipient = debounce(this.props.onChangeRecipient, 1e3)
  _onChangeRecipient = recipientPublicKey => {
    this.setState({recipientPublicKey})
    this.props.setReadyToReview(false)
    this._propsOnChangeRecipient(recipientPublicKey)
  }

  render = () => (
    <ParticipantsRow
      heading="To"
      headingAlignment="Left"
      headingStyle={styles.heading}
      dividerColor={this.props.errorMessage ? Styles.globalColors.red : ''}
      style={styles.toStellarPublicKey}
    >
      <Kb.Box2 direction="vertical" fullWidth={!Styles.isMobile} style={styles.inputBox}>
        <Kb.Box2 direction="horizontal" gap="xxtiny" fullWidth={!Styles.isMobile} style={styles.inputInner}>
          <Kb.Icon
            sizeType={Styles.isMobile ? 'Small' : 'Default'}
            type="iconfont-identity-stellar"
            color={
              this.state.recipientPublicKey.length === 0 || this.props.errorMessage
                ? Styles.globalColors.black_50
                : Styles.globalColors.black
            }
          />
          <Kb.Box2 direction="horizontal" style={styles.publicKeyInputContainer}>
            <Kb.NewInput
              type="text"
              onChangeText={this._onChangeRecipient}
              textType="BodySemibold"
              hideBorder={true}
              containerStyle={styles.input}
              multiline={true}
              rowsMin={2}
              rowsMax={3}
              value={this.state.recipientPublicKey}
            />
            {!this.state.recipientPublicKey && (
              <Kb.Box
                activeOpacity={1}
                pointerEvents="none"
                style={Styles.collapseStyles([Styles.globalStyles.fillAbsolute, styles.placeholderContainer])}
              >
                <Kb.Text type="BodySemibold" style={styles.colorBlack20}>
                  Stellar address
                </Kb.Text>
                <Kb.Text type="BodySemibold" style={styles.colorBlack20} lineClamp={1} ellipsizeMode="middle">
                  {placeholderExample}
                </Kb.Text>
              </Kb.Box>
            )}
          </Kb.Box2>
          {!this.state.recipientPublicKey && this.props.onScanQRCode && (
            <Kb.Icon
              color={Styles.globalColors.black_50}
              type="iconfont-qr-code"
              fontSize={24}
              onClick={this.props.onScanQRCode}
              style={Kb.iconCastPlatformStyles(styles.qrCode)}
            />
          )}
        </Kb.Box2>
        {!!this.props.errorMessage && (
          <Kb.Text type="BodySmall" style={styles.errorText}>
            {this.props.errorMessage}
          </Kb.Text>
        )}
      </Kb.Box2>
    </ParticipantsRow>
  )
}

type ToOtherAccountProps = {|
  user: string,
  toAccount?: Account,
  allAccounts: Account[],
  onChangeRecipient: string => void,
  onLinkAccount: () => void,
  onCreateNewAccount: () => void,
  showSpinner: boolean,
|}

class ToOtherAccount extends React.Component<ToOtherAccountProps> {
  onAccountDropdownChange = (node: React.Node) => {
    if (React.isValidElement(node)) {
      // $FlowIssue React.isValidElement refinement doesn't happen, see https://github.com/facebook/flow/issues/6392
      const element = (node: React.Element<any>)
      if (element.key === 'create-new') {
        this.props.onCreateNewAccount()
      } else if (element.key === 'link-existing') {
        this.props.onLinkAccount()
      } else {
        this.props.onChangeRecipient(element.props.account.id)
      }
    }
  }

  render = () => {
    if (this.props.allAccounts.length <= 1) {
      // A user is sending to another account, but has no other
      // accounts. Show a "create new account" button.
      return (
        <Kb.Box2 direction="horizontal" centerChildren={true} style={{width: 270}}>
          <Kb.Button
            type="Wallet"
            style={styles.createNewAccountButton}
            label="Create a new account"
            onClick={this.props.onCreateNewAccount}
          />
        </Kb.Box2>
      )
    }

    // A user is sending from an account to another account with other
    // accounts. Show a dropdown list of other accounts, in addition
    // to the link existing and create new actions.
    let items = [
      <DropdownText
        spinner={this.props.showSpinner}
        key="link-existing"
        text="Link an existing Stellar account"
      />,
      <DropdownText spinner={this.props.showSpinner} key="create-new" text="Create a new account" />,
    ]

    if (this.props.allAccounts.length > 0) {
      const walletItems = this.props.allAccounts.map(account => (
        <DropdownEntry key={account.id} account={account} user={this.props.user} />
      ))
      items = walletItems.concat(items)
    }

    return (
      <ParticipantsRow heading="To" headingAlignment="Right" style={styles.toAccountRow}>
        <Kb.Dropdown
          onChanged={this.onAccountDropdownChange}
          items={items}
          style={styles.dropdown}
          selectedBoxStyle={styles.dropdownSelectedBox}
          selected={
            this.props.toAccount ? (
              <SelectedEntry
                spinner={this.props.showSpinner}
                account={this.props.toAccount}
                user={this.props.user}
              />
            ) : (
              <DropdownText
                spinner={this.props.showSpinner}
                key="placeholder-select"
                text="Pick another account"
              />
            )
          }
        />
      </ParticipantsRow>
    )
  }
}

const styles = Styles.styleSheetCreate({
  avatar: {
    marginRight: 8,
  },
  colorBlack20: {
    color: Styles.globalColors.black_20,
  },
  createNewAccountButton: Styles.platformStyles({
    isElectron: {
      width: 194,
    },
  }),
  dropdown: Styles.platformStyles({
    isMobile: {height: 32},
  }),
  dropdownSelectedBox: Styles.platformStyles({
    isMobile: {minHeight: 32},
  }),
  errorText: Styles.platformStyles({
    common: {
      color: Styles.globalColors.red,
      width: '100%',
    },
    isElectron: {
      wordWrap: 'break-word',
    },
  }),
  heading: {
    alignSelf: 'flex-start',
  },
  input: Styles.platformStyles({
    common: {
      padding: 0,
    },
    isMobile: {
      paddingLeft: Styles.globalMargins.xtiny,
    },
  }),
  inputBox: Styles.platformStyles({isElectron: {flexGrow: 1}, isMobile: {flex: 1}}),
  inputInner: Styles.platformStyles({
    common: {
      alignItems: 'flex-start',
      flex: 1,
      position: 'relative',
    },
    isElectron: {
      flexShrink: 0,
    },
  }),
  keybaseUserRemoveButton: {
    flex: 1,
    marginRight: Styles.globalMargins.tiny,
    textAlign: 'right', // consistent with UserInput
  },
  placeholderContainer: Styles.platformStyles({
    common: {
      display: 'flex',
      flexDirection: 'column',
      paddingLeft: (Styles.isMobile ? 0 : 16) + 4,
    },
    isElectron: {
      pointerEvents: 'none',
    },
  }),
  publicKeyInputContainer: {flexGrow: 1, flexShrink: 1},
  qrCode: {
    marginRight: Styles.globalMargins.tiny,
    marginTop: Styles.globalMargins.tiny,
  },
  toAccountRow: Styles.platformStyles({
    isMobile: {
      height: 40,
      paddingBottom: 4,
      paddingTop: 4,
    },
  }),
  toKeybaseUser: {
    height: 48,
  },
  toKeybaseUserNameWithIcon: {
    flexGrow: 1,
  },
  toStellarPublicKey: {
    alignItems: 'flex-start',
    minHeight: 52,
  },
})

export type {ToKeybaseUserProps, ToStellarPublicKeyProps}

export {ToKeybaseUser, ToStellarPublicKey, ToOtherAccount}
<|endoftext|>


<commit_before>import Server from './Server';

// process.env.SERVER_ETC is set in the docker image
const cd = process.env.SERVER_ETC ? process.env.SERVER_ETC : 'etc';
process.chdir( cd );

const server = new Server( {
  config: 'server.yaml'
} );

// On container shutdown exit quickly
process.on('SIGTERM', () => {
  server.stop();
  process.exit(0);
});
<commit_msg>When running docker with -it then ^C will now shut down the server<commit_after>import Server from './Server';

// process.env.SERVER_ETC is set in the docker image
const cd = process.env.SERVER_ETC ? process.env.SERVER_ETC : 'etc';
process.chdir( cd );

const server = new Server( {
  config: 'server.yaml'
} );

// On container shutdown exit quickly
const stop = () => {
  server.stop();
  process.exit(0);
};
process.on('SIGTERM', stop);
process.on('SIGINT', stop);
<|endoftext|>


<commit_before>import { join } from 'path'
import { fork } from 'spawncommand'

const BIN = join(__dirname, 'bin', process.env.ALAMODE_ENV == 'test-build' ? 'zoroaster' : '')

/**
 * Start zoroaster process, and return a child process with a `promise` property.
 * @param {string[]} args An array of strings as arguments
 * @param {import('child_process').ForkOptions} options Options to pass when creating child process
 * @returns {ChildProcess} An instance of a ChildProcess, with `.promise` property,
 * which will be resolved when tests are finished.
 */
function run(args, options = {}) {
  const proc = fork(BIN, args, {
    stdio: 'pipe',
    ...options,
  })
  return proc
}

export default run

export { default as throws } from 'assert-throws'
export { default as assert, equal, ok } from 'assert'
export { deepEqual } from 'assert-diff'

/* documentary types/make-test-suite.xml */
/**
 * @typedef {Object} Context A context made with a constructor.
 * @prop {() => void} [_init] A function to initialise the context.
 * @prop {() => void} [_destroy] A function to destroy the context.
 *
 * @typedef {Object} MakeTestSuiteConf Configuration for making test suites.
 * @prop {({new(): Context}|{new(): Context}[]|{})} [context] Single or multiple context constructors or objects to initialise for each test.
 * @prop {(input: string, ...contexts?: Context[]) => string} [getResults] A function which should return results of a test.
 * @prop {(input: string, ...contexts?: Context[]) => { fn: function, args?: any[], message?: (string|RegExp) }} [getThrowsConfig] A function which should return a configuration for [`assert-throws`](https://github.com/artdecocode/assert-throws), including `fn` and `args`, when testing an error.
 * @prop {(results: any) => string} [mapActual] An optional function to get a value to test against `expected` mask property from results. By default, the full result is used.
 * @prop {(results: any, props: Object.<string, (string|object)>) => void} [assertResults] A function containing any addition assertions on the results. The results from `getResults` and a map of expected values extracted from the mask using `customProps` and `jsonProps` will be passed as first and second arguments.
 * @prop {string[]} [customProps] An array of custom properties' names to extract from the mask.
 * @prop {string[]} [jsonProps] Any additional properties to extract from the mask, and parse as _JSON_ values.
 */
<commit_msg>dep makeTestSuite<commit_after>import { join } from 'path'
import { fork } from 'spawncommand'

const BIN = join(__dirname, 'bin', process.env.ALAMODE_ENV == 'test-build' ? 'zoroaster' : '')

/**
 * Start zoroaster process, and return a child process with a `promise` property.
 * @param {string[]} args An array of strings as arguments
 * @param {import('child_process').ForkOptions} options Options to pass when creating child process
 * @returns {ChildProcess} An instance of a ChildProcess, with `.promise` property,
 * which will be resolved when tests are finished.
 */
function run(args, options = {}) {
  const proc = fork(BIN, args, {
    stdio: 'pipe',
    ...options,
  })
  return proc
}

export default run

export { default as throws } from 'assert-throws'
export { default as assert, equal, ok } from 'assert'
export { deepEqual } from 'assert-diff'

export const makeTestSuite = () => {
  throw new Error('Please use @zoroaster/mask for mask testing.')
}<|endoftext|>