<commit_before>/* eslint-disable no-underscore-dangle */

// TODO figure out caching

import merge from 'deepmerge';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

import WEB3_API from './web3Api';
import { getWeb3Method, createContractTransaction } from './actions';

function reduxifyWeb3({ web3, networkId }) {
  const api = {};
  Object.keys(WEB3_API).forEach((key) => {
    const keys = key.split('.');
    const groupKey = keys[0];
    const methodKey = keys[1];
    if (!api[groupKey]) { api[groupKey] = {}; }
    const method = web3[groupKey][methodKey];
    const collection = WEB3_API[key].collection || 'web3';
    const actionCreator = WEB3_API[key].actionCreator || getWeb3Method;
    api[groupKey][methodKey] = (...args) => {
      return actionCreator({ collection, key, method, args, networkId });
    };
  });
  return api;
}

function reduxifyContract({ abi, address, web3, networkId, getStore }) {
  if (!address) { throw new Error('Address not defined'); }
  const contractInstance = (web3.__web3 || web3).eth.contract(abi).at(address);
  const api = {};
  // TODO optimize/cache?
  abi.forEach((definition) => {
    if (definition.type !== 'function') { return; }
    api[definition.name] = {};

    // standard getter
    api[definition.name] = (...args) => {
      return (getStore().getIn(['web3Redux', 'networks', networkId, 'contracts', address, 'calls', definition.name, JSON.stringify(args)]) || {}).value;
    };
    // hook up transactions
    api[definition.name].transaction = (...args) => {
      return createContractTransaction({ networkId, args, address, method: contractInstance[definition.name] });
    };
    // hook up calls
    const callKey = ['calls', definition.name].join('.');
    api[definition.name].call = (...args) => {
      return getWeb3Method({ networkId, args, address, collection: 'contracts', key: callKey, method: contractInstance[definition.name].call });
    };
  });
  return api;
}

const cachedContracts = {};

function generateContractAPI({ abi, address, networkId, getStore, getDispatch, web3 }) {
  if (!web3) { return null; }
  // TODO use provider url, too (hint, yes.)?
  const cacheKey = `${networkId}${address}`;
  if (cachedContracts[cacheKey]) { return cachedContracts[cacheKey]; }
  const contractRedux = reduxifyContract({ abi, address, web3, networkId, getStore });
  // bind action creators for `call` and `transaction`
  const api = Object.keys(contractRedux).reduce((o, k) => {
    const { transaction, call } = contractRedux[k];
    const actions = bindActionCreators({ transaction, call }, getDispatch());
    const wrappedMethod = contractRedux[k];
    wrappedMethod.transaction = actions.transaction;
    wrappedMethod.call = actions.call;
    return { ...o, [k]: wrappedMethod };
  }, {});
  cachedContracts[cacheKey] = api;
  return { ...api, __web3: web3.__web3 || web3 };
}

function generateWeb3API({ network, getStore, getDispatch, web3 }) {
  const networkId = network.id;
  if (!web3) { return null; }
  const web3Redux = reduxifyWeb3({ networkId, web3 });
  const api = merge(
    Object.keys(web3Redux).reduce((o, k) => ({
      ...o, [k]: Object.keys(web3Redux[k]).reduce((o2, k2) => {
        if (k2.indexOf('get') !== 0) { return o2; }
        const getterMethod = k2.split('get')[1];
        const getterKey = `${getterMethod[0].toLowerCase()}${getterMethod.slice(1)}`;
        const getterFn = (...args) => {
          const gotStore = getStore();
          if (!gotStore) { return null; }
          if (getterKey === 'transaction') {
            return (gotStore.getIn(['web3Redux', 'networks', networkId, 'transactions', args[0]]) || {}).value;
          }
          return (gotStore.getIn(['web3Redux', 'networks', networkId, 'web3', k, k2, JSON.stringify(args)]) || {}).value;
        };
        return { ...o2, [getterKey]: getterFn };
      }, {}),
    }), {})
  ,
    Object.keys(web3Redux).reduce((o, k) => ({
      ...o, [k]: bindActionCreators(web3Redux[k], getDispatch()),
    }), {})
  );

  api.eth.waitForMined = (tx, pollTime = 10 * 1000) => {
    // TODO poll for getTransactionReceipt, then resolve
    return new Promise((resolve, reject) => {
      function poll() {
        return api.eth.getTransactionReceipt(tx).then((res) => {
          if (res) {
            // got the transaction receipt
            resolve(res);
          } else {
            // no dice, try agian
            setTimeout(poll, pollTime);
          }
        }).catch(reject);
      }
      poll();
    });
  };

  const contract = (abi) => {
    return {
      at: (address) => generateContractAPI({ abi, address, networkId, getStore, getDispatch, web3 }),
      new: (...args) => {
        const instance = web3.eth.contract(abi);
        const data = instance.new.getData.apply(instance, args);
        return api.eth.sendTransaction({ ...args, data }).then(tx => api.eth.waitForMined(tx));
      },
    };
  };

  return {
    ...api,
    __web3: web3,
    eth: {
      ...api.eth,
      contract,
    },
  };
}

export default function (arg) {
  // const web3s;
  // use store/dispatch pointer and cache reducer in this namespace for perf & getter syntax
  let store;
  let dispatch;
  let resolvedWeb3;
  function getStore() { return store; }
  function getDispatch() { return dispatch; }

  function resolveWeb3() {
    if (resolvedWeb3) {
      return resolvedWeb3;
    }
    if (typeof arg === 'function') {
      return arg({ getStore, getDispatch, generateWeb3API });
    }
    resolvedWeb3 = (typeof arg !== 'function') && Object.keys(arg).reduce((o, k) => ({
      ...o, [k]: generateWeb3API({ network: { id: k }, web3: arg[k], getStore, getDispatch }),
    }), {});
    return resolvedWeb3;
  }

  function mapStateToProps(newStore) {
    store = newStore;
    const obj = store.get('web3Redux');
    const web3ReduxStore = obj && obj.toJS() || {};
    return { web3ReduxStore };
  }

  function mapDispatchToProps(newDispatch) {
    dispatch = newDispatch;
    return {};
  }

  function mergeProps(stateProps, dispatchProps, ownProps) {
    return {
      ...ownProps,
      ...stateProps,
      web3s: resolveWeb3(),
      status: store.getIn(['web3Redux', 'status']) || {},
    };
  }

  return connect(mapStateToProps, mapDispatchToProps, mergeProps);
}
<commit_msg>add `new` contract method<commit_after>/* eslint-disable no-underscore-dangle */

// TODO figure out caching

import merge from 'deepmerge';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

import WEB3_API from './web3Api';
import { getWeb3Method, createContractTransaction } from './actions';

function reduxifyWeb3({ web3, networkId }) {
  const api = {};
  Object.keys(WEB3_API).forEach((key) => {
    const keys = key.split('.');
    const groupKey = keys[0];
    const methodKey = keys[1];
    if (!api[groupKey]) { api[groupKey] = {}; }
    const method = web3[groupKey][methodKey];
    const collection = WEB3_API[key].collection || 'web3';
    const actionCreator = WEB3_API[key].actionCreator || getWeb3Method;
    api[groupKey][methodKey] = (...args) => {
      return actionCreator({ collection, key, method, args, networkId });
    };
  });
  return api;
}

function reduxifyContract({ abi, address, web3, networkId, getStore }) {
  if (!address) { throw new Error('Address not defined'); }
  const contractInstance = (web3.__web3 || web3).eth.contract(abi).at(address);
  const api = {};
  // TODO optimize/cache?
  abi.forEach((definition) => {
    if (definition.type !== 'function') { return; }
    api[definition.name] = {};

    // standard getter
    api[definition.name] = (...args) => {
      return (getStore().getIn(['web3Redux', 'networks', networkId, 'contracts', address, 'calls', definition.name, JSON.stringify(args)]) || {}).value;
    };
    // hook up transactions
    api[definition.name].transaction = (...args) => {
      return createContractTransaction({ networkId, args, address, method: contractInstance[definition.name] });
    };
    // hook up calls
    const callKey = ['calls', definition.name].join('.');
    api[definition.name].call = (...args) => {
      return getWeb3Method({ networkId, args, address, collection: 'contracts', key: callKey, method: contractInstance[definition.name].call });
    };
  });
  return api;
}

const cachedContracts = {};

function generateContractAPI({ abi, address, networkId, getStore, getDispatch, web3 }) {
  if (!web3) { return null; }
  // TODO use provider url, too (hint, yes.)?
  const cacheKey = `${networkId}${address}`;
  if (cachedContracts[cacheKey]) { return cachedContracts[cacheKey]; }
  const contractRedux = reduxifyContract({ abi, address, web3, networkId, getStore });
  // bind action creators for `call` and `transaction`
  const api = Object.keys(contractRedux).reduce((o, k) => {
    const { transaction, call } = contractRedux[k];
    const actions = bindActionCreators({ transaction, call }, getDispatch());
    const wrappedMethod = contractRedux[k];
    wrappedMethod.transaction = actions.transaction;
    wrappedMethod.call = actions.call;
    return { ...o, [k]: wrappedMethod };
  }, {});
  cachedContracts[cacheKey] = api;
  return { ...api, __web3: web3.__web3 || web3 };
}

function generateWeb3API({ network, getStore, getDispatch, web3 }) {
  const networkId = network.id;
  if (!web3) { return null; }
  const web3Redux = reduxifyWeb3({ networkId, web3 });
  const api = merge(
    Object.keys(web3Redux).reduce((o, k) => ({
      ...o, [k]: Object.keys(web3Redux[k]).reduce((o2, k2) => {
        if (k2.indexOf('get') !== 0) { return o2; }
        const getterMethod = k2.split('get')[1];
        const getterKey = `${getterMethod[0].toLowerCase()}${getterMethod.slice(1)}`;
        const getterFn = (...args) => {
          const gotStore = getStore();
          if (!gotStore) { return null; }
          if (getterKey === 'transaction') {
            return (gotStore.getIn(['web3Redux', 'networks', networkId, 'transactions', args[0]]) || {}).value;
          }
          return (gotStore.getIn(['web3Redux', 'networks', networkId, 'web3', k, k2, JSON.stringify(args)]) || {}).value;
        };
        return { ...o2, [getterKey]: getterFn };
      }, {}),
    }), {})
  ,
    Object.keys(web3Redux).reduce((o, k) => ({
      ...o, [k]: bindActionCreators(web3Redux[k], getDispatch()),
    }), {})
  );

  api.eth.waitForMined = (tx, pollTime = 10 * 1000) => {
    // TODO poll for getTransactionReceipt, then resolve
    return new Promise((resolve, reject) => {
      function poll() {
        return api.eth.getTransactionReceipt(tx).then((res) => {
          if (res) {
            // got the transaction receipt
            resolve(res);
          } else {
            // no dice, try agian
            setTimeout(poll, pollTime);
          }
        }).catch(reject);
      }
      poll();
    });
  };

  const contract = (abi) => {
    return {
      at: (address) => generateContractAPI({ abi, address, networkId, getStore, getDispatch, web3 }),
      new: (...params) => {
        const instance = web3.eth.contract(abi);
        const args = params;
        const { data, ...rest } = args[args.length - 1];
        args[args.length] = { data };
        const newData = instance.new.getData.apply(instance, args);
        args[args.length] = { ...rest, data: newData };
        return api.eth.sendTransaction.apply(null, args).then(tx => api.eth.waitForMined(tx));
      },
    };
  };

  return {
    ...api,
    __web3: web3,
    eth: {
      ...api.eth,
      contract,
    },
  };
}

export default function (arg) {
  // const web3s;
  // use store/dispatch pointer and cache reducer in this namespace for perf & getter syntax
  let store;
  let dispatch;
  let resolvedWeb3;
  function getStore() { return store; }
  function getDispatch() { return dispatch; }

  function resolveWeb3() {
    if (resolvedWeb3) {
      return resolvedWeb3;
    }
    if (typeof arg === 'function') {
      return arg({ getStore, getDispatch, generateWeb3API });
    }
    resolvedWeb3 = (typeof arg !== 'function') && Object.keys(arg).reduce((o, k) => ({
      ...o, [k]: generateWeb3API({ network: { id: k }, web3: arg[k], getStore, getDispatch }),
    }), {});
    return resolvedWeb3;
  }

  function mapStateToProps(newStore) {
    store = newStore;
    const obj = store.get('web3Redux');
    const web3ReduxStore = obj && obj.toJS() || {};
    return { web3ReduxStore };
  }

  function mapDispatchToProps(newDispatch) {
    dispatch = newDispatch;
    return {};
  }

  function mergeProps(stateProps, dispatchProps, ownProps) {
    return {
      ...ownProps,
      ...stateProps,
      web3s: resolveWeb3(),
      status: store.getIn(['web3Redux', 'status']) || {},
    };
  }

  return connect(mapStateToProps, mapDispatchToProps, mergeProps);
}
<|endoftext|>


<commit_before>const SVGO = require('svgo');
const { getOptions } = require('loader-utils');
const { version } = require('vue');
const { major } = require('semver')

module.exports = async function (svg) {
  const callback = this.async();
  const { svgo: svgoConfig } = getOptions(this) || {};

  if (svgoConfig !== false) {
    const svgo = new SVGO(svgoConfig);

    try {
      ({ data: svg } = await svgo.optimize(svg, {
        path: this.resourcePath,
      }));
    } catch (error) {
      callback(error);
      return;
    }
  }

  if (major(version) === 2) {
    svg = svg.replace('<svg', '<svg v-on="$listeners"');
  }

  callback(null, `<template>${svg}</template>`)
};
<commit_msg>Reduce memory footprint by importing specific function from `semver` package<commit_after>const SVGO = require('svgo');
const { getOptions } = require('loader-utils');
const { version } = require('vue');
const semverMajor = require('semver/functions/major')

module.exports = async function (svg) {
  const callback = this.async();
  const { svgo: svgoConfig } = getOptions(this) || {};

  if (svgoConfig !== false) {
    const svgo = new SVGO(svgoConfig);

    try {
      ({ data: svg } = await svgo.optimize(svg, {
        path: this.resourcePath,
      }));
    } catch (error) {
      callback(error);
      return;
    }
  }

  if (semverMajor(version) === 2) {
    svg = svg.replace('<svg', '<svg v-on="$listeners"');
  }

  callback(null, `<template>${svg}</template>`)
};
<|endoftext|>


<commit_before>// Just pretend this magically works and we'll both be a lot happier.

//          ┌──┬──┬──┐
//          │ 0│ 1│ 2│
//          ├──┼──┼──┤
//          │ 3│ 4│ 5│
//          ├──┼──┼──┤
//          │ 6│ 7│ 8│
// ┌──┬──┬──┼──┼──┼──┼──┬──┬──┐
// │ 9│10│11│12│13│14│15│16│17│
// ├──┼──┼──┼──┼──┼──┼──┼──┼──┤
// │18│19│20│21│22│23│24│25│26│
// ├──┼──┼──┼──┼──┼──┼──┼──┼──┤
// │27│28│29│30│31│32│33│34│35│
// └──┴──┴──┼──┼──┼──┼──┴──┴──┘
//          │36│37│38│
//          ├──┼──┼──┤
//          │39│40│41│
//          ├──┼──┼──┤
//          │42│43│44│
//          ├──┼──┼──┤
//          │45│46│47│
//          ├──┼──┼──┤
//          │48│49│50│
//          ├──┼──┼──┤
//          │51│52│53│
//          └──┴──┴──┘

var movesInAlg = function(alg) {
  return alg.match(/[UDRLFBudlrfbxyzMES]w?[2']?/g)
};

var stickerCount = 54;
var solved = function() {
  var r = [];
  for (var i = 0; i < stickerCount; i++) {
    r.push(i);
  }
  return r;
};

var moveDefs = [
  ["U", [       6,  3,  0,
                7,  4,  1,
                8,  5,  2,
   12, 13, 14, 15, 16, 17, 53, 52, 51,
   18, 19, 20, 21, 22, 23, 24, 25, 26,
   27, 28, 29, 30, 31, 32, 33, 34, 35,
               36, 37, 38,
               39, 40, 41,
               42, 43, 44,
               45, 46, 47,
               48, 49, 50,
               11, 10,  9]],
  ["x", [      12, 13, 14,
               21, 22, 23,
               30, 31, 32,
   11, 20, 29, 36, 37, 38, 33, 24, 15,
   10, 19, 28, 39, 40, 41, 34, 25, 16,
    9, 18, 27, 42, 43, 44, 35, 26, 17,
               45, 46, 47,
               48, 49, 50,
               51, 52, 53,
                0,  1,  2,
                3,  4,  5,
                6,  7,  8]],
  ["y", [       6,  3,  0,
                7,  4,  1,
                8,  5,  2,
   12, 13, 14, 15, 16, 17, 53, 52, 51,
   21, 22, 23, 24, 25, 26, 50, 49, 48,
   30, 31, 32, 33, 34, 35, 47, 46, 45,
               38, 41, 44,
               37, 40, 43,
               36, 39, 42,
               29, 28, 27,
               20, 19, 18,
               11, 10,  9]],
  ["z" , "x y x'"],
  ["D" , "x2 U x2"],
  ["R" , "z D z'"],
  ["L" , "y2 R y2"],
  ["F" , "y' R y"],
  ["B" , "y2 F y2"],
  ["M" , "L' R x'"],
  ["E" , "z M z'"],
  ["S" , "y M y'"],
  ["Rw", "M' R"],
  ["Lw", "M L"],
  ["Uw", "M' R"],
  ["Dw", "y' U"],
  ["Fw", "z B'"],
  ["Bw", "z' F"],
  ["r" , "Rw"],
  ["l" , "Lw"],
  ["u" , "Uw"],
  ["d" , "Dw"],
  ["f" , "Fw"],
  ["b" , "Bw"]
];

var cubesEqual = function(cube1, cube2) {
  for (var i = 0; i < stickerCount; i++) {
    if (cube1[i] !== cube2[i]) return false;
  }
  return true;
}

var applyMove = function(cube, move) {
  if (!moveEffects.hasOwnProperty(move)) {
    throw new Error("Unknown move '" + move + "'");
  }
  var effect = moveEffects[move];
  if (typeof effect === "string") {
    return movesInAlg(effect).reduce(applyMove, cube);
  } else {
    return effect.map(function(i) { return cube[i] });
  }
};

var moveEffects = {};

moveDefs.forEach(function(def) {
  var k = def[0];
  var v = def[1];
  if (typeof v === "object") {
    moveEffects[k] = v;
  } else {
    var moves = movesInAlg(v);
    moveEffects[k] = moves.reduce(applyMove, solved());
  }
  var result = applyMove(solved(), k);
  moveEffects[k] = result;
  result = applyMove(result, k);
  moveEffects[k + "2"] = result;
  result = applyMove(result, k);
  moveEffects[k + "'"] = result;
});

var Cubid = function() {
  var init;
  var alg = arguments[0];
  if (arguments.length === 1) {
    init = solved();
  } else if (arguments.length === 2) {
    init = arguments[1];
  } else {
    throw new Error("new Cubid(...) takes 1 or 2 arguments.");
  }

  var moves = movesInAlg(alg);
  this.contents = moves.reduce(applyMove, init);
};

var sides = [
  [ 0,  1,  2,  3,  4,  5,  6,  7,  8],
  [ 9, 10, 11, 18, 19, 20, 27, 28, 29],
  [12, 13, 14, 21, 22, 23, 30, 31, 32],
  [15, 16, 17, 24, 25, 26, 33, 34, 35],
  [36, 37, 38, 39, 40, 41, 42, 43, 44],
  [45, 46, 47, 48, 49, 50, 51, 52, 53]
];

var colours = {};
sides.forEach(function(side, i) {
  side.forEach(function(sticker) {
    colours[sticker] = i;
  });
});

Cubid.prototype.isSolved = function() {
  for (var i = 0; i < sides.length; i++) {
    var col = colours[this.contents[sides[i][0]]];
    for (var j = 1; j < sides[i].length; j++) {
      if (col !== colours[this.contents[sides[i][j]]]) {
        return false;
      }
    }
  };
  return true;
};

Cubid.prototype.apply = function(alg) {
  return new Cubid(alg, this.contents);
};

module.exports = Cubid;
<commit_msg>remove cubesEqual<commit_after>// Just pretend this magically works and we'll both be a lot happier.

//          ┌──┬──┬──┐
//          │ 0│ 1│ 2│
//          ├──┼──┼──┤
//          │ 3│ 4│ 5│
//          ├──┼──┼──┤
//          │ 6│ 7│ 8│
// ┌──┬──┬──┼──┼──┼──┼──┬──┬──┐
// │ 9│10│11│12│13│14│15│16│17│
// ├──┼──┼──┼──┼──┼──┼──┼──┼──┤
// │18│19│20│21│22│23│24│25│26│
// ├──┼──┼──┼──┼──┼──┼──┼──┼──┤
// │27│28│29│30│31│32│33│34│35│
// └──┴──┴──┼──┼──┼──┼──┴──┴──┘
//          │36│37│38│
//          ├──┼──┼──┤
//          │39│40│41│
//          ├──┼──┼──┤
//          │42│43│44│
//          ├──┼──┼──┤
//          │45│46│47│
//          ├──┼──┼──┤
//          │48│49│50│
//          ├──┼──┼──┤
//          │51│52│53│
//          └──┴──┴──┘

var movesInAlg = function(alg) {
  return alg.match(/[UDRLFBudlrfbxyzMES]w?[2']?/g)
};

var stickerCount = 54;
var solved = function() {
  var r = [];
  for (var i = 0; i < stickerCount; i++) {
    r.push(i);
  }
  return r;
};

var moveDefs = [
  ["U", [       6,  3,  0,
                7,  4,  1,
                8,  5,  2,
   12, 13, 14, 15, 16, 17, 53, 52, 51,
   18, 19, 20, 21, 22, 23, 24, 25, 26,
   27, 28, 29, 30, 31, 32, 33, 34, 35,
               36, 37, 38,
               39, 40, 41,
               42, 43, 44,
               45, 46, 47,
               48, 49, 50,
               11, 10,  9]],
  ["x", [      12, 13, 14,
               21, 22, 23,
               30, 31, 32,
   11, 20, 29, 36, 37, 38, 33, 24, 15,
   10, 19, 28, 39, 40, 41, 34, 25, 16,
    9, 18, 27, 42, 43, 44, 35, 26, 17,
               45, 46, 47,
               48, 49, 50,
               51, 52, 53,
                0,  1,  2,
                3,  4,  5,
                6,  7,  8]],
  ["y", [       6,  3,  0,
                7,  4,  1,
                8,  5,  2,
   12, 13, 14, 15, 16, 17, 53, 52, 51,
   21, 22, 23, 24, 25, 26, 50, 49, 48,
   30, 31, 32, 33, 34, 35, 47, 46, 45,
               38, 41, 44,
               37, 40, 43,
               36, 39, 42,
               29, 28, 27,
               20, 19, 18,
               11, 10,  9]],
  ["z" , "x y x'"],
  ["D" , "x2 U x2"],
  ["R" , "z D z'"],
  ["L" , "y2 R y2"],
  ["F" , "y' R y"],
  ["B" , "y2 F y2"],
  ["M" , "L' R x'"],
  ["E" , "z M z'"],
  ["S" , "y M y'"],
  ["Rw", "M' R"],
  ["Lw", "M L"],
  ["Uw", "M' R"],
  ["Dw", "y' U"],
  ["Fw", "z B'"],
  ["Bw", "z' F"],
  ["r" , "Rw"],
  ["l" , "Lw"],
  ["u" , "Uw"],
  ["d" , "Dw"],
  ["f" , "Fw"],
  ["b" , "Bw"]
];

var applyMove = function(cube, move) {
  if (!moveEffects.hasOwnProperty(move)) {
    throw new Error("Unknown move '" + move + "'");
  }
  var effect = moveEffects[move];
  if (typeof effect === "string") {
    return movesInAlg(effect).reduce(applyMove, cube);
  } else {
    return effect.map(function(i) { return cube[i] });
  }
};

var moveEffects = {};

moveDefs.forEach(function(def) {
  var k = def[0];
  var v = def[1];
  if (typeof v === "object") {
    moveEffects[k] = v;
  } else {
    var moves = movesInAlg(v);
    moveEffects[k] = moves.reduce(applyMove, solved());
  }
  var result = applyMove(solved(), k);
  moveEffects[k] = result;
  result = applyMove(result, k);
  moveEffects[k + "2"] = result;
  result = applyMove(result, k);
  moveEffects[k + "'"] = result;
});

var Cubid = function() {
  var init;
  var alg = arguments[0];
  if (arguments.length === 1) {
    init = solved();
  } else if (arguments.length === 2) {
    init = arguments[1];
  } else {
    throw new Error("new Cubid(...) takes 1 or 2 arguments.");
  }

  var moves = movesInAlg(alg);
  this.contents = moves.reduce(applyMove, init);
};

var sides = [
  [ 0,  1,  2,  3,  4,  5,  6,  7,  8],
  [ 9, 10, 11, 18, 19, 20, 27, 28, 29],
  [12, 13, 14, 21, 22, 23, 30, 31, 32],
  [15, 16, 17, 24, 25, 26, 33, 34, 35],
  [36, 37, 38, 39, 40, 41, 42, 43, 44],
  [45, 46, 47, 48, 49, 50, 51, 52, 53]
];

var colours = {};
sides.forEach(function(side, i) {
  side.forEach(function(sticker) {
    colours[sticker] = i;
  });
});

Cubid.prototype.isSolved = function() {
  for (var i = 0; i < sides.length; i++) {
    var col = colours[this.contents[sides[i][0]]];
    for (var j = 1; j < sides[i].length; j++) {
      if (col !== colours[this.contents[sides[i][j]]]) {
        return false;
      }
    }
  };
  return true;
};

Cubid.prototype.apply = function(alg) {
  return new Cubid(alg, this.contents);
};

module.exports = Cubid;
<|endoftext|>


<commit_before>import game from './scripts/game'
import _ from 'lodash'
import $ from 'jquery'
import io from 'socket.io-client'
import { cp } from './scripts/helpers'

const roomNoMin = 1000
const roomNoMax = 9999

// Initialize the game
const tictac = game({ size: 3 })
let player = 2

// Socket
let socket = io('http://localhost:3000')

const $joinRoom = $('#join-room')

// Render boxes
const render = ($board) => {
  return (action, { board }) => {
    // Update boxes
    const letter = { 1: 'X', 2: 'O' }
    return _.flatMap(board, (xa, x) => {
      return xa.map((player, y) => {
        const $field = $(`.box[data-x=${x}][data-y=${y}]`)
        if ($field.length) {
          $field.text(letter[player])
        } else {
          return $board.append(`<div class="box" data-x="${x}" data-y="${y}"></div>`)
        }
      })
    })
  }
}

const renderStatus = ($status) => {
  return (action, { nowPlaying }) => {
    // Update colors
    if(nowPlaying){
      $status.find(`[data-player="${nowPlaying}"] > .mark`).removeClass('inactive')
    }
    else {
      $status.find('.player > .mark').addClass('inactive')
    }
  }
}

// When the socket sends an update
const send = (action, state) => {
  if(!action.fromSocket) {
    socket.emit('update', cp(action, { room: state.room }))
  }
}

const startGame = (room) => {
  // Initiate game
  tictac.dispatch({ type: 'INIT', room: room, size: 3 })

  // Add event listener for playing
  $('#board .box').on('click', function(){
    tictac.dispatch({ type: 'MOVE', x: $(this).attr('data-x'), y: $(this).attr('data-y'), player })
  })

  // Dispatching actions from other players
  socket.on('update', update => {
    tictac.dispatch(cp(update, { fromSocket: true }))
  })

  // Wait for other players to join
  socket.on('joined', state => {
    player = 1
    console.log('dosao neko')
    tictac.dispatch({ type: 'START' })
  })

  // Join the room at server
  socket.emit('joinRoom', room)
  window.location.hash = room
  $joinRoom.val(room)
}

// Joining room
$joinRoom.on('keyup', (e) => {
  const roomNo = $(e.target).val()
  if(_.inRange(roomNo, roomNoMin, roomNoMax)){
    startGame(roomNo)
  }
})

// Game rendering
tictac.subscribe(render($('#board')))

// Action sending
tictac.subscribe(send, ['INIT', 'MOVE', 'JOIN', 'START'])

// Status rendering
tictac.subscribe(renderStatus($('#scoreboard')))

// Start game at random room
const hashRoom = window.location.hash && window.location.hash.substr(1)
if(hashRoom && !isNaN(hashRoom)){
  startGame(hashRoom)
}
else {
  startGame(_.random(roomNoMin, roomNoMax))
}
<commit_msg>showing now playing status in UI<commit_after>import game from './scripts/game'
import _ from 'lodash'
import $ from 'jquery'
import io from 'socket.io-client'
import { cp } from './scripts/helpers'

const roomNoMin = 1000
const roomNoMax = 9999

// Initialize the game
const tictac = game({ size: 3 })
let player = 2

// Socket
let socket = io('http://localhost:3000')

const $joinRoom = $('#join-room')

// Render boxes
const render = ($board) => {
  return (action, { board }) => {
    // Update boxes
    const letter = { 1: 'X', 2: 'O' }
    return _.flatMap(board, (xa, x) => {
      return xa.map((player, y) => {
        const $field = $(`.box[data-x=${x}][data-y=${y}]`)
        if ($field.length) {
          $field.text(letter[player])
        } else {
          return $board.append(`<div class="box" data-x="${x}" data-y="${y}"></div>`)
        }
      })
    })
  }
}

const renderStatus = ($status) => {
  return (action, { nowPlaying }) => {
    // Update colors
    $status.find('.player > .mark').addClass('inactive')
    if(nowPlaying){
      $status.find(`[data-player="${nowPlaying}"] > .mark`).removeClass('inactive')
    }
  }
}

// When the socket sends an update
const send = (action, state) => {
  if(!action.fromSocket) {
    socket.emit('update', cp(action, { room: state.room }))
  }
}

const startGame = (room) => {
  // Initiate game
  tictac.dispatch({ type: 'INIT', room: room, size: 3 })

  // Add event listener for playing
  $('#board .box').on('click', function(){
    tictac.dispatch({ type: 'MOVE', x: $(this).attr('data-x'), y: $(this).attr('data-y'), player })
  })

  // Dispatching actions from other players
  socket.on('update', update => {
    tictac.dispatch(cp(update, { fromSocket: true }))
  })

  // Wait for other players to join
  socket.on('joined', state => {
    player = 1
    tictac.dispatch({ type: 'START' })
  })

  // Join the room at server
  socket.emit('joinRoom', room)
  window.location.hash = room
  $joinRoom.val(room)
}

// Joining room
$joinRoom.on('keyup', (e) => {
  const roomNo = $(e.target).val()
  if(_.inRange(roomNo, roomNoMin, roomNoMax)){
    startGame(roomNo)
  }
})

// Game rendering
tictac.subscribe(render($('#board')))

// Action sending
tictac.subscribe(send)

// Status rendering
tictac.subscribe(renderStatus($('#scoreboard')))

// Start game at random room
const hashRoom = window.location.hash && window.location.hash.substr(1)
if(hashRoom && !isNaN(hashRoom)){
  startGame(hashRoom)
}
else {
  startGame(_.random(roomNoMin, roomNoMax))
}
<|endoftext|>


<commit_before>'use strict';

/**
 * Watch
 *   Watch source files of a bunch of specific tasks and run corresponding task when a file changes.
 *
 * zh_TW：
 *   watch 只要指定相依的 task 即可。
 *   然後自動由相依的 task 找出需要監控的對應檔案，並在檔案變動時，自動執行對應的 task。
 *
 * Recipe:
 *   watch
 *
 * Ingredients:
 *   browser-sync
 *   gulp.watch()
 *
 */
function watch() {
	var browserSync = require('browser-sync');
	var log = require('gulplog');

	var gulp = this.gulp;
	var options = this.config.options || {};
	var tasks = this.tasks || [];

	tasks.forEach(function (task) {
		if (task.config && task.config.src) {
			log.info('watch', 'watching ' + JSON.stringify(task.config.src.globs) + ' for ' + task.displayName);
			gulp.watch(task.config.src.globs, options, task)
				.on('change', browserSync.reload);
		}
	});
}

watch.schema = {
	title: 'watch',
	description: 'Watch source files of a bunch of specific tasks and run corresponding task when a file changes.',
	type: 'object',
	properties: {
		options: {
			properties: {
				browserSync: {},
				persistent: {},
				ignored: {},
				ignoreInitial: {},
				followSymlinks: {},
				cwd: {},
				usePolling: {},
				interval: {},
				binaryInterval: {},
				useFsEvents: {},
				alwaysStat: {},
				depth: {},
				awaitWriteFinish: {},
				ignorePermissionErrors: {},
				atomic: {}
			}
		}
	}
};

watch.type = 'flow';

module.exports = watch;
<commit_msg>recursively add child task's sources<commit_after>'use strict';

/**
 * Watch
 *   Watch source files of a bunch of specific tasks and run corresponding task when a file changes.
 *
 * zh_TW：
 *   watch 只要指定相依的 task 即可。
 *   然後自動由相依的 task 找出需要監控的對應檔案，並在檔案變動時，自動執行對應的 task。
 *
 * Recipe:
 *   watch
 *
 * Ingredients:
 *   browser-sync
 *   gulp.watch()
 *
 */
function watch() {
	var browserSync = require('browser-sync');
	var log = require('gulplog');

	var gulp = this.gulp;
	var config = this.config;
	var options = config.options || {};
	var tasks = this.tasks || [];

	if (config.run) {
		// run tasks before watch.
	}

	tasks.forEach(function (task) {
		var src;

		src = sources([], task);
		if (src.length) {
			log.info('watch', 'watching ' + JSON.stringify(src) + ' for ' + task.displayName);
			gulp.watch(src, options, task).on('change', browserSync.reload);
		} else {
			log.warn('watch', 'warning', task.displayName + ' has no `src` property.');
		}
	});

	// recursively add child task's sources.
	function sources(result, task) {
		var ret = result;

		if (task.config && task.config.src) {
			ret = ret.concat(task.config.src.globs);
		}
		if (task.tasks) {
			ret = task.tasks.reduce(sources);
		}
		return ret;
	}
}

watch.schema = {
	title: 'watch',
	description: 'Watch source files of a bunch of specific tasks and run corresponding task when a file changes.',
	type: 'object',
	properties: {
		run: {
			description: 'Run tasks before watch.',
			type: 'boolean'
		},
		browserSync: {
			description: 'Options for browser-sync.',
			type: 'object'
		},
		options: {
			properties: {
				persistent: {},
				ignored: {},
				ignoreInitial: {},
				followSymlinks: {},
				cwd: {},
				usePolling: {},
				interval: {},
				binaryInterval: {},
				useFsEvents: {},
				alwaysStat: {},
				depth: {},
				awaitWriteFinish: {},
				ignorePermissionErrors: {},
				atomic: {}
			}
		}
	}
};

watch.type = 'flow';

module.exports = watch;
<|endoftext|>


<commit_before>var request = require("request");
var methods = require("./api-methods");

function serializeObjToUri(obj) {
  return Object.keys(obj)
    .map(function(key) {
      return key + "=" + encodeURIComponent(obj[key]);
    })
    .join("&");
}

var Api = function(config) {
  this._uri = this.uri;
};

Object.keys(methods).forEach(function(mName) {
  var m = methods[mName];

  Api.prototype[mName] = function(parameters, path, callback) {
    if (arguments.length === 1) callback = parameters;
    if (arguments.length === 2) callback = path;

    var computedPath = m.path;
    if (typeof arguments[1] === "object") {
      computedPath = m.path.replace(/{([^}]*)}/g, function(s, p) {
        return path[p];
      });
    }

    var reqUri = this._uri + computedPath;

    if (m.method === "GET" && parameters) {
      reqUri = reqUri + "?" + serializeObjToUri(parameters);
    }

    var opts = {
      url: reqUri,
      method: m.method,
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json"
      },
      body: m.method !== "GET" && parameters ? parameters : null,
      json: false
    };
    request(opts, function(error, response, body) {
      if (body === "") body = "{}";
      if (error) {
        return callback([error, body]);
      }
      if (response.statusCode === 403) {
        return callback([JSON.parse(body).message, body]);
      }
      try {
        callback(null, JSON.parse(body));
      } catch (err) {
        callback(["Bad response", err, reqUri]);
      }
    });
  };
});

var connect = function(config, callback) {
  var that = new Api(config);
  return that;
};

connect.connect = connect; // backwards compatible
connect.Api = Api;
module.exports = connect;
<commit_msg>Fix url issue<commit_after>var request = require("request");
var methods = require("./api-methods");

function serializeObjToUri(obj) {
  return Object.keys(obj)
    .map(function(key) {
      return key + "=" + encodeURIComponent(obj[key]);
    })
    .join("&");
}

var Api = function(config) {
  config = config || {}
  const basicAuthToken = config.basicAuth ?
    config.basicAuth.username + ':' + config.basicAuth.password + '@' : ''

  this._uri = (config.protocol || 'http') + '://' + basicAuthToken +
    (config.host || 'localhost') + ':' + (config.port || '12900') +
    (config.path || '')
};

Object.keys(methods).forEach(function(mName) {
  var m = methods[mName];

  Api.prototype[mName] = function(parameters, path, callback) {
    if (arguments.length === 1) callback = parameters;
    if (arguments.length === 2) callback = path;

    var computedPath = m.path;
    if (typeof arguments[1] === "object") {
      computedPath = m.path.replace(/{([^}]*)}/g, function(s, p) {
        return path[p];
      });
    }

    var reqUri = this._uri + computedPath;

    if (m.method === "GET" && parameters) {
      reqUri = reqUri + "?" + serializeObjToUri(parameters);
    }

    var opts = {
      url: reqUri,
      method: m.method,
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json"
      },
      body: m.method !== "GET" && parameters ? parameters : null,
      json: false
    };
    request(opts, function(error, response, body) {
      if (body === "") body = "{}";
      if (error) {
        return callback([error, body]);
      }
      if (response.statusCode === 403) {
        return callback([JSON.parse(body).message, body]);
      }
      try {
        callback(null, JSON.parse(body));
      } catch (err) {
        callback(["Bad response", err, reqUri]);
      }
    });
  };
});

var connect = function(config, callback) {
  var that = new Api(config);
  return that;
};

connect.connect = connect; // backwards compatible
connect.Api = Api;
module.exports = connect;
<|endoftext|>


<commit_before>var net = require('net'),
    _ = require('underscore')._,
    os = require("os");

function GraphiteClient(options) {

    var queue = {};

    var defaults = {
        host: '127.0.0.1',
        port: 2003,
        debug: false,
        interval: 60000,
        prefix: "monitoring." + os.hostname() + "."
    };

    function init() {
        options = _.defaults(options || {}, defaults);

        if (options.interval !== 0) {
            setInterval(send, options.interval);
        }

        return {
            increment: increment,
            collectLastValue: collectLastValue,
            collectMaximum: collectMaximum,
            options: options,
            send: send
        }
    }

    function increment(name, value) {
        calculateValues(name, function(item) {
            if (item === undefined) {
                item = { value: value };
            } else {
                item.value += value;
            }
            return item;
        });
    }

    function collectMaximum(name, value) {
        calculateValues(name, function(item) {
            if (item === undefined) {
                item = { value: value };
            } else if (item.value < value){
                item.value = value;
            }
            return item;
        });
    }

    function collectLastValue(name, value) {
        calculateValues(name, function(item) {
            return { value: value };
        });
    }

    function calculateValues(name, f) {
        var timestamp = String(Date.now()).substr(0, 10);
        queue[name] = f(queue[name]);
        queue[name].timestamp = timestamp;
    }

    function getQueueAsPlainText() {
        var text = '';
        for(var name in queue) {
            text += options.prefix + name +' '+ queue[name].value +' '+ queue[name].timestamp +'\n'
        }
        return text
    }

    function send(done) {
        if(Object.keys(queue).length === 0) {
            return;
        }

        var queueString = getQueueAsPlainText();
        var socket = net.createConnection(options.port, options.host, function() {
            socket.write(queueString);
            socket.end();
        });
        socket.on('error', function (e) {
            console.log("Graphite connection failed: " + e.code);
        });

        queue = {};
        if (typeof(done) == "function") {
            done();
        }
    }

    return init()
}

module.exports = {
    createClient: function (options) {
        return new GraphiteClient(options)
    }
};
<commit_msg>Always call done - even if queue is empty<commit_after>var net = require('net'),
    _ = require('underscore')._,
    os = require("os");

function GraphiteClient(options) {

    var queue = {};

    var defaults = {
        host: '127.0.0.1',
        port: 2003,
        debug: false,
        interval: 60000,
        prefix: "monitoring." + os.hostname() + "."
    };

    function init() {
        options = _.defaults(options || {}, defaults);

        if (options.interval !== 0) {
            setInterval(send, options.interval);
        }

        return {
            increment: increment,
            collectLastValue: collectLastValue,
            collectMaximum: collectMaximum,
            options: options,
            send: send
        }
    }

    function increment(name, value) {
        calculateValues(name, function(item) {
            if (item === undefined) {
                item = { value: value };
            } else {
                item.value += value;
            }
            return item;
        });
    }

    function collectMaximum(name, value) {
        calculateValues(name, function(item) {
            if (item === undefined) {
                item = { value: value };
            } else if (item.value < value){
                item.value = value;
            }
            return item;
        });
    }

    function collectLastValue(name, value) {
        calculateValues(name, function(item) {
            return { value: value };
        });
    }

    function calculateValues(name, f) {
        var timestamp = String(Date.now()).substr(0, 10);
        queue[name] = f(queue[name]);
        queue[name].timestamp = timestamp;
    }

    function getQueueAsPlainText() {
        var text = '';
        for(var name in queue) {
            text += options.prefix + name +' '+ queue[name].value +' '+ queue[name].timestamp +'\n'
        }
        return text
    }

    function send(done) {
        if(Object.keys(queue).length !== 0) {
            var queueString = getQueueAsPlainText();
            var socket = net.createConnection(options.port, options.host, function () {
                socket.write(queueString);
                socket.end();
            });
            socket.on('error', function (e) {
                console.log("Graphite connection failed: " + e.code);
            });

            queue = {};
        }

        if (typeof(done) == "function") {
            done();
        }
    }

    return init()
}

module.exports = {
    createClient: function (options) {
        return new GraphiteClient(options)
    }
};
<|endoftext|>


<commit_before>(function($){
  //Helper Functions
  function _slicesToArray(r,c){
    var arr=[],b=0;
    for(var i = 0; i < r; i++) {
      arr[i] = new Array(c);
      for(var j = 0; j < c; j++) {
          arr[i][j] = b;
          b++;
      }
    }
    return arr;
  }

  //End Helper Functions

  var namespace=$.fn.wipeImages,
  wipeFactory=function(el,opts){
    var _this=this;
    _this.el=el;
    _this.config=namespace.config;
    _this.images=namespace.images.srcs;
    _this.isGrouped=false;
    _this.prefixes=["ms","moz","webkit","o"];

    _this.setUpVars=$.extend({
      cols:1,
      rows:1,
      duration:this.config.duration,
      easing:this.config.easing,
      isCss3:false,
      from:{
        opacity:0
      },
      to:{
        opacity:1
      }
    },opts);

    var len=_this.images.length,
    current=namespace.images.current;
    current++;
    if(current > (len-1)){
      current=0;
    }
    _this.setUpVars.img=_this.images[current];
    namespace.images.current=current;

    _this._createSlices();

    _this.slices=_this.el.find("." + this.config.className);
    namespace.config.animating=true;
  }
  wipeFactory.prototype={
    _createSlices:function(){
      var _this=this,el=_this.el,
      className=_this.config.className,
      e_wd=el.width(),e_ht=el.height(),
      setUpVars=_this.setUpVars,
      wd=Math.round(e_wd/setUpVars.cols),
      ht=Math.round(e_ht/setUpVars.rows),from={};

      for(var r = 0; r < setUpVars.rows; r++){
        for(var c= 0; c < setUpVars.cols; c++){
          from=$.extend({
            left:(wd*c) + "px",
            top: (ht*r) + "px",
            height: (ht) + "px",
          },setUpVars.from);
          if(c==setUpVars.cols-1){
            from=$.extend({
              width: (e_wd - (wd*c)) + "px"
            },from);
          }else{
            from=$.extend({
              width: (wd) + "px"
            },from);
          }
          el.append(
            $("
",{
              "class":className,
              css:{
                position: "absolute",
                background: 'url("'+ setUpVars.img +'") no-repeat -'+ ((wd + (c * wd)) - wd) +'px -'+ ((ht + (r * ht)) - ht) +'px'
              }
            }).css(from)
          );

        }
      }
    },
     _animate:function(slice,index,total,buffer,callback){
       var _this=this,
       to=_this.setUpVars.to,
       duration=_this.setUpVars.duration,
       easing=_this.setUpVars.easing;
      (function(slice,index,total,buffer,callback){
        setTimeout(function(){
          if(_this.setUpVars.isCss3){
            _temp={};
            for(var i=0;i<_this.prefixes.length;i++){
              _temp["-"+_this.prefixes[i]+"-transition-property"]="all";
              _temp["-"+_this.prefixes[i]+"-transition-duration"]=duration/1000 + "s";
            }
            if(index==(total-1)){
              setTimeout(callback,duration);
            }
            slice.css(_temp);
            slice.css(to);
          }else{
            slice.animate(to,duration,easing,function(){
              if(index==(total-1)){
                callback();
              }
            })
          }
        },buffer);
      })(slice,index,total,buffer,callback);
    },
    cleanup:function(){
      var _this=this;
      namespace.config.animating=false;
      _this.el.append("");
      if(_this.isGrouped){
        var i,j,l=_this.slices.length;
        for(i=0;i<l;i++){
          var sl=_this.slices[i].length;
          for(j=0;j<sl;j++){
            $(_this.slices[i][j]).remove();
          }
        }
      }else{
        _this.slices.remove();
      }

      _this.el.find(":not(:last-child)").remove();
    },
    setup:function(){},
    play:function(){
      var _this=this,done=0,buffer=0,increment=_this.setUpVars.duration/_this.slices.length,slice;
      if(_this.isGrouped){
        var i,l=_this.groups.length;
        increment=_this.setUpVars.duration/_this.groups.length;
        for(i=0;i<l;i++){
          var grp=_this.groups[i];
          slice=_this.slices.eq(grp.shift());
          while(grp.length > 0){
            slice=slice.add(_this.slices.eq(grp.shift()));
          }
          buffer +=increment;
          _this._animate(slice,
            i,l,buffer,
            function(){_this.cleanup();});
        }
      }else{
        _this.slices.each(function(idx){
          var slice=$(this);
          buffer +=increment;
          _this._animate(slice,
            idx,_this.slices.length,buffer,
            function(){_this.cleanup();});
        });
      }

    },
    run:function(){
      this.setup();
      this.play();
    },

    reverse:function(){
      this.slices=[].reverse.apply(this.slices);
    },
    shuffle:function(){
      var arr=this.slices;
      for(var j, x, i = arr.length; i; j = parseInt(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x);
      this.slices=arr;
    },
    groupCentrally:function(r,c){
      var grouped=[],arr=_slicesToArray(r,c),columnLength,
      isEven=(((columnLength = arr[0].length) % 2) == 0);

      var middle=Math.floor((columnLength-1)/2);
      var group=[];
      for(var i=0;i<r;i++){
        var box=middle + (columnLength*i);
        group.push(box);
        if(isEven){
          group.push(box+1);
        }
      }
      grouped.push(group);
      var numTimes=group[0],k=0;
      for(var j=numTimes-1;j>-1;j--){
        var gr=[];
        k=k+2;
        for(var i=0;i<r;i++){
          gr.push(j+(i*columnLength),j+(i*columnLength)+k+(isEven ? 1 : 0));
        }
        grouped.push(gr);
      }
      return grouped;
    },
    groupDiagonally:function(r,c,rev){
      var grouped=[],arr=_slicesToArray(r,c);

      if(rev){
        for (var i = 1 - r; i < c; i++) {
          var group = [];
          for (var j = 0; j < r; j++) {
            if ((i + j) >= 0 && (i + j) < c) {
              group.push(arr[j][i + j]);
            }
          }
          grouped.push(group);
        }
      }else{
        for (var i = 0; i < r + c - 1; i++) {
          var z1 = (i < c) ? 0 : i - c + 1;
          var z2 = (i < r) ? 0 : i - r + 1;
          var group=[];
          for (var j = i - z2; j >= z1; j--) {
            group.push(arr[j][i - j]);
          }
          grouped.push(group);
        }
      }
      return grouped;
    }
  }

  namespace.wipeFactory=wipeFactory;

  namespace.wipes={
    "default":function(el){
      var wipe=new namespace.wipeFactory(el);
      wipe.run();
    },
    fadeIn:function(el){
      var wipe=new namespace.wipeFactory(el,{
        cols:10,
        rows:20
      });
      wipe.reverse();
      wipe.run();
    }
  };

})(jQuery);
<commit_msg>also support un prefixed css properties <commit_after>(function($){
  //Helper Functions
  function _slicesToArray(r,c){
    var arr=[],b=0;
    for(var i = 0; i < r; i++) {
      arr[i] = new Array(c);
      for(var j = 0; j < c; j++) {
          arr[i][j] = b;
          b++;
      }
    }
    return arr;
  }

  //End Helper Functions

  var namespace=$.fn.wipeImages,
  wipeFactory=function(el,opts){
    var _this=this;
    _this.el=el;
    _this.config=namespace.config;
    _this.images=namespace.images.srcs;
    _this.isGrouped=false;
    _this.prefixes=["ms","moz","webkit","o",""];

    _this.setUpVars=$.extend({
      cols:1,
      rows:1,
      duration:this.config.duration,
      easing:this.config.easing,
      isCss3:false,
      from:{
        opacity:0
      },
      to:{
        opacity:1
      }
    },opts);

    var len=_this.images.length,
    current=namespace.images.current;
    current++;
    if(current > (len-1)){
      current=0;
    }
    _this.setUpVars.img=_this.images[current];
    namespace.images.current=current;

    _this._createSlices();

    _this.slices=_this.el.find("." + this.config.className);
    namespace.config.animating=true;
  }
  wipeFactory.prototype={
    _createSlices:function(){
      var _this=this,el=_this.el,
      className=_this.config.className,
      e_wd=el.width(),e_ht=el.height(),
      setUpVars=_this.setUpVars,
      wd=Math.round(e_wd/setUpVars.cols),
      ht=Math.round(e_ht/setUpVars.rows),from={};

      for(var r = 0; r < setUpVars.rows; r++){
        for(var c= 0; c < setUpVars.cols; c++){
          from=$.extend({
            left:(wd*c) + "px",
            top: (ht*r) + "px",
            height: (ht) + "px",
          },setUpVars.from);
          if(c==setUpVars.cols-1){
            from=$.extend({
              width: (e_wd - (wd*c)) + "px"
            },from);
          }else{
            from=$.extend({
              width: (wd) + "px"
            },from);
          }
          el.append(
            $("
",{
              "class":className,
              css:{
                position: "absolute",
                background: 'url("'+ setUpVars.img +'") no-repeat -'+ ((wd + (c * wd)) - wd) +'px -'+ ((ht + (r * ht)) - ht) +'px'
              }
            }).css(from)
          );

        }
      }
    },
     _animate:function(slice,index,total,buffer,callback){
       var _this=this,
       to=_this.setUpVars.to,
       duration=_this.setUpVars.duration,
       easing=_this.setUpVars.easing;
      (function(slice,index,total,buffer,callback){
        setTimeout(function(){
          if(_this.setUpVars.isCss3){
            _temp={};
            for(var i=0;i<_this.prefixes.length;i++){
              var prfx=_this.prefixes[i],dash=(prfx!=""?"-":"");
              _temp[dash+prfx+dash+"transition-property"]="all";
              _temp[dash+prfx+dash+"transition-duration"]=duration/1000 + "s";
            }
            if(index==(total-1)){
              setTimeout(callback,duration);
            }
            slice.css(_temp);
            slice.css(to);
          }else{
            slice.animate(to,duration,easing,function(){
              if(index==(total-1)){
                callback();
              }
            })
          }
        },buffer);
      })(slice,index,total,buffer,callback);
    },
    cleanup:function(){
      var _this=this;
      namespace.config.animating=false;
      _this.el.append("");
      if(_this.isGrouped){
        var i,j,l=_this.slices.length;
        for(i=0;i<l;i++){
          var sl=_this.slices[i].length;
          for(j=0;j<sl;j++){
            $(_this.slices[i][j]).remove();
          }
        }
      }else{
        _this.slices.remove();
      }

      _this.el.find(":not(:last-child)").remove();
    },
    setup:function(){},
    play:function(){
      var _this=this,done=0,buffer=0,increment=_this.setUpVars.duration/_this.slices.length,slice;
      if(_this.isGrouped){
        var i,l=_this.groups.length;
        increment=_this.setUpVars.duration/_this.groups.length;
        for(i=0;i<l;i++){
          var grp=_this.groups[i];
          slice=_this.slices.eq(grp.shift());
          while(grp.length > 0){
            slice=slice.add(_this.slices.eq(grp.shift()));
          }
          buffer +=increment;
          _this._animate(slice,
            i,l,buffer,
            function(){_this.cleanup();});
        }
      }else{
        _this.slices.each(function(idx){
          var slice=$(this);
          buffer +=increment;
          _this._animate(slice,
            idx,_this.slices.length,buffer,
            function(){_this.cleanup();});
        });
      }

    },
    run:function(){
      this.setup();
      this.play();
    },

    reverse:function(){
      this.slices=[].reverse.apply(this.slices);
    },
    shuffle:function(){
      var arr=this.slices;
      for(var j, x, i = arr.length; i; j = parseInt(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x);
      this.slices=arr;
    },
    groupCentrally:function(r,c){
      var grouped=[],arr=_slicesToArray(r,c),columnLength,
      isEven=(((columnLength = arr[0].length) % 2) == 0);

      var middle=Math.floor((columnLength-1)/2);
      var group=[];
      for(var i=0;i<r;i++){
        var box=middle + (columnLength*i);
        group.push(box);
        if(isEven){
          group.push(box+1);
        }
      }
      grouped.push(group);
      var numTimes=group[0],k=0;
      for(var j=numTimes-1;j>-1;j--){
        var gr=[];
        k=k+2;
        for(var i=0;i<r;i++){
          gr.push(j+(i*columnLength),j+(i*columnLength)+k+(isEven ? 1 : 0));
        }
        grouped.push(gr);
      }
      return grouped;
    },
    groupDiagonally:function(r,c,rev){
      var grouped=[],arr=_slicesToArray(r,c);

      if(rev){
        for (var i = 1 - r; i < c; i++) {
          var group = [];
          for (var j = 0; j < r; j++) {
            if ((i + j) >= 0 && (i + j) < c) {
              group.push(arr[j][i + j]);
            }
          }
          grouped.push(group);
        }
      }else{
        for (var i = 0; i < r + c - 1; i++) {
          var z1 = (i < c) ? 0 : i - c + 1;
          var z2 = (i < r) ? 0 : i - r + 1;
          var group=[];
          for (var j = i - z2; j >= z1; j--) {
            group.push(arr[j][i - j]);
          }
          grouped.push(group);
        }
      }
      return grouped;
    }
  }

  namespace.wipeFactory=wipeFactory;

  namespace.wipes={
    "default":function(el){
      var wipe=new namespace.wipeFactory(el);
      wipe.run();
    },
    fadeIn:function(el){
      var wipe=new namespace.wipeFactory(el,{
        cols:10,
        rows:20
      });
      wipe.reverse();
      wipe.run();
    }
  };

})(jQuery);
<|endoftext|>


<commit_before>// param can be either length (number) or buffer
function createTypedArray(type, param){
  switch(type){
    case 'Uint8Array':
      return new Uint8Array(param);
    case 'Uint8ClampedArray':
      return new Uint8ClampedArray(param);
    case 'Uint16Array':
      return new Uint16Array(param);
    case 'Uint32Array':
      return new Uint32Array(param);
    case 'Int8Array':
      return new Int8Array(param);
    case 'Int16Array':
      return new Int16Array(param);
    case 'Int32Array':
      return new Int32Array(param);
    case 'Float32Array':
      return new Float32Array(param);
    case 'Float64Array':
      return new Float64Array(param);
  }
}

function getMapFactory(){
  if (typeof Map === 'function'){
    return function(){
      /* jshint ignore:start */
      return new Map();
      /* jshint ignore:end */
    };
  } else {
    return function(){
      return Object.create(null);
    };
  }
}

var mapFactory = getMapFactory();

var functionCache = mapFactory();

var operations = {
  map: function (array, f) {
    var i = array.length;
    for ( ; i--; ){
      array[i] = f(array[i]);
    }
    return array.length;
  },
  filter: function (array, f) {
    var l = array.length;
    var i = 0, newLength = 0;
    for ( ; i < l; i += 1){
      var e = array[i];
      if (f(e)) {
        array[newLength++] = e;
      }
    }
    return newLength;
  },
  reduce: function (array, f, seed) {
    var i = 0;
    var l = array.length;
    var reduced = seed;
    for ( ; i < l; i += 1){
      var e = array[i];
      reduced = f(reduced, e);
    }
    array[0] = reduced;
    return 1;
  }
};

module.exports = function(event){
  var pack = event.data;
  var seed = pack.seed;
  var args = pack.args;
  var code = pack.code;
  var cacheKey = args.join(',') + code;
  var f = functionCache[cacheKey];
  if (!f){
    /*jslint evil: true */
    if (undefined === args[1]) {
      f = new Function(args[0], code);
    } else {
      f = new Function(args[0], args[1], code);
    }
    functionCache[cacheKey] = f;
  }

  var array = createTypedArray(pack.elementsType, pack.buffer);

  var newLength = operations[pack.operation](array, f, seed);

  return {
    message: {
      index: pack.index,
      value: array.buffer,
      newLength: newLength
    },
    transferables: [ array.buffer ]
  };
};
<commit_msg>[3.3.2] refactors WebWorker's create function<commit_after>// param can be either length (number) or buffer
function createTypedArray(type, param){
  switch(type){
    case 'Uint8Array':
      return new Uint8Array(param);
    case 'Uint8ClampedArray':
      return new Uint8ClampedArray(param);
    case 'Uint16Array':
      return new Uint16Array(param);
    case 'Uint32Array':
      return new Uint32Array(param);
    case 'Int8Array':
      return new Int8Array(param);
    case 'Int16Array':
      return new Int16Array(param);
    case 'Int32Array':
      return new Int32Array(param);
    case 'Float32Array':
      return new Float32Array(param);
    case 'Float64Array':
      return new Float64Array(param);
  }
}

function getMapFactory(){
  if (typeof Map === 'function'){
    return function(){
      /* jshint ignore:start */
      return new Map();
      /* jshint ignore:end */
    };
  } else {
    return function(){
      return Object.create(null);
    };
  }
}

var mapFactory = getMapFactory();

var functionCache = mapFactory();

var operations = {
  map: function (array, f) {
    var i = array.length;
    for ( ; i--; ){
      array[i] = f(array[i]);
    }
    return array.length;
  },
  filter: function (array, f) {
    var l = array.length;
    var i = 0, newLength = 0;
    for ( ; i < l; i += 1){
      var e = array[i];
      if (f(e)) {
        array[newLength++] = e;
      }
    }
    return newLength;
  },
  reduce: function (array, f, seed) {
    var i = 0;
    var l = array.length;
    var reduced = seed;
    for ( ; i < l; i += 1){
      var e = array[i];
      reduced = f(reduced, e);
    }
    array[0] = reduced;
    return 1;
  }
};

module.exports = function(event){
  var pack = event.data;
  var seed = pack.seed;
  var args = pack.args;
  var code = pack.code;
  var cacheKey = args.join(',') + code;
  var f = functionCache[cacheKey];
  if (!f){
    f = createFunction(args, code);
    functionCache[cacheKey] = f;
  }

  var array = createTypedArray(pack.elementsType, pack.buffer);

  var newLength = operations[pack.operation](array, f, seed);

  return {
    message: {
      index: pack.index,
      value: array.buffer,
      newLength: newLength
    },
    transferables: [ array.buffer ]
  };
};

function createFunction(args, code) {
  if (1 === args.length) {
    /*jslint evil: true */
    return new Function(args[0], code);
  }
  if (2 === args.length) {
    /*jslint evil: true */
    return new Function(args[0], args[1], code);
  }
}<|endoftext|>


<commit_before>const EventEmitter = require('events');
const DHT = require('bittorrent-dht')
const crypto = require('crypto');
const WebTorrent = require('webtorrent')
const ChunkStore = require('memory-chunk-store')

const defaults = {}
defaults.timeout = 60e3 * 10
defaults.maxPending = 200

class Sniffer extends EventEmitter {

  constructor(options) {
    super()

    this.options = Object.assign({}, defaults, options)

    const bt = this.bt = new WebTorrent({
      //maxConns: 1,
      //dht: false,
      tracker: false
      dht: {
        maxTables: 10,
        maxValues: 10,
        maxPeers: 100
      }
    })

    const dht = new DHT({
      maxTables: 10,
      maxValues: 10,
      maxPeers: 100
    });
    this.dht = dht
    const rpc   = this.rpc    = dht._rpc
    const nodes = this.nodes  = rpc.nodes

    this.bt.on('error', (error) => {
      console.error(error.message);
    })

    this.locks = new Set

    dht.on('announce_peer', async (infoHash, peer) => {
      if (this.bt.torrents.length >= this.options.maxPending) {
        this.emit('busy', infoHash, peer)
        return
      }

      this.add(infoHash, peer)
    })

    rpc.on('ping', (olders, newer) => {
      //const [older] = olders
      //rpc.nodes.remove(older.id)
      //for (const older of olders) {
        //rpc.nodes.remove(older.id)
      //}
      rpc.clear()
    })
    dht.on('node', (node) => this.makeNeighbor(node))
  }

  async add(infoHash, peer, magnet) {
    const locks = this.locks
    const lock = infoHash.toString('hex')
    if (locks.has(lock)) {
      return
    }
    locks.add(lock)

    const ignore = await this._ignore(infoHash)
    if (ignore) {
      return locks.delete(lock)
    }

    const torrent = this.bt.add(magnet || infoHash, { store: ChunkStore })

    const timeout = setTimeout(() => {
      if (!this.bt.get(torrent)) {
        return
      }
      this.bt.remove(torrent)
    }, this.options.timeout);

    if (peer) {
      torrent.addPeer(`${peer.host}:${peer.port}`)
    }

    torrent.once('metadata', () => {
      clearTimeout(timeout)
      this.bt.remove(torrent)
      torrent.done = true
      this.emit('metadata', torrent)
    })
    torrent.once('close', () => {
      locks.delete(lock)
    })

    this.emit('torrent', torrent)
  }

  makeNeighbor(node, id) {
    const rpc = this.dht._rpc
    // prevent memleak
    if (rpc.pending.length) {
      return
    }
    const query = {
      t: crypto.randomBytes(4),
      y: 'q',
      q: 'find_node',
      a: {
        id: id || Buffer.concat([node.id.slice(0, 10), rpc.id.slice(10)]),
        target: crypto.randomBytes(20)
      }
    };
    rpc.query(node, query)
  }

  ignore(callback) {
    this._ignore = callback;
  };

  start(...args) {
    this.dht.listen(...args)

    setInterval(() => {
      const rpc = this.dht._rpc
      rpc.bootstrap.forEach((node) => this.makeNeighbor(node, rpc.id))
    }, 10000)
  };

}

Sniffer.defaults = defaults

module.exports = Sniffer;
<commit_msg>Fix typo<commit_after>const EventEmitter = require('events');
const DHT = require('bittorrent-dht')
const crypto = require('crypto');
const WebTorrent = require('webtorrent')
const ChunkStore = require('memory-chunk-store')

const defaults = {}
defaults.timeout = 60e3 * 10
defaults.maxPending = 200

class Sniffer extends EventEmitter {

  constructor(options) {
    super()

    this.options = Object.assign({}, defaults, options)

    const bt = this.bt = new WebTorrent({
      //maxConns: 1,
      //dht: false,
      tracker: false,
      dht: {
        maxTables: 10,
        maxValues: 10,
        maxPeers: 100
      }
    })

    const dht = new DHT({
      maxTables: 10,
      maxValues: 10,
      maxPeers: 100
    });
    this.dht = dht
    const rpc   = this.rpc    = dht._rpc
    const nodes = this.nodes  = rpc.nodes

    this.bt.on('error', (error) => {
      console.error(error.message);
    })

    this.locks = new Set

    dht.on('announce_peer', async (infoHash, peer) => {
      if (this.bt.torrents.length >= this.options.maxPending) {
        this.emit('busy', infoHash, peer)
        return
      }

      this.add(infoHash, peer)
    })

    rpc.on('ping', (olders, newer) => {
      //const [older] = olders
      //rpc.nodes.remove(older.id)
      //for (const older of olders) {
        //rpc.nodes.remove(older.id)
      //}
      rpc.clear()
    })
    dht.on('node', (node) => this.makeNeighbor(node))
  }

  async add(infoHash, peer, magnet) {
    const locks = this.locks
    const lock = infoHash.toString('hex')
    if (locks.has(lock)) {
      return
    }
    locks.add(lock)

    const ignore = await this._ignore(infoHash)
    if (ignore) {
      return locks.delete(lock)
    }

    const torrent = this.bt.add(magnet || infoHash, { store: ChunkStore })

    const timeout = setTimeout(() => {
      if (!this.bt.get(torrent)) {
        return
      }
      this.bt.remove(torrent)
    }, this.options.timeout);

    if (peer) {
      torrent.addPeer(`${peer.host}:${peer.port}`)
    }

    torrent.once('metadata', () => {
      clearTimeout(timeout)
      this.bt.remove(torrent)
      torrent.done = true
      this.emit('metadata', torrent)
    })
    torrent.once('close', () => {
      locks.delete(lock)
    })

    this.emit('torrent', torrent)
  }

  makeNeighbor(node, id) {
    const rpc = this.dht._rpc
    // prevent memleak
    if (rpc.pending.length) {
      return
    }
    const query = {
      t: crypto.randomBytes(4),
      y: 'q',
      q: 'find_node',
      a: {
        id: id || Buffer.concat([node.id.slice(0, 10), rpc.id.slice(10)]),
        target: crypto.randomBytes(20)
      }
    };
    rpc.query(node, query)
  }

  ignore(callback) {
    this._ignore = callback;
  };

  start(...args) {
    this.dht.listen(...args)

    setInterval(() => {
      const rpc = this.dht._rpc
      rpc.bootstrap.forEach((node) => this.makeNeighbor(node, rpc.id))
    }, 10000)
  };

}

Sniffer.defaults = defaults

module.exports = Sniffer;
<|endoftext|>


<commit_before>import * as THREE from 'three'
import { Vector2 as Vec2 } from 'three'
import { Vector3 as Vec3 } from 'three'
import { Face3 as Face3 } from 'three'
import { Mesh } from 'three'

function resizeTexture(pixels, width, height, newWidth, newHeight) {
    let canvas = document.createElement('canvas')
    let ctx = canvas.getContext('2d')
    canvas.width = width
    canvas.height = height

    let nc = document.createElement('canvas')
    let nctx = nc.getContext('2d')
    nc.width = newWidth
    nc.height = newHeight

    let cid = ctx.createImageData(width, height)
    for (let i = 0, size = width * height * 4; i < size; i += 4) {
        cid.data[i] = pixels[i]
        cid.data[i + 1] = pixels[i + 1]
        cid.data[i + 2] = pixels[i + 2]
        cid.data[i + 3] = pixels[i + 3]
    }
    ctx.putImageData(cid, 0, 0)

    nctx.drawImage(canvas, 0, 0, newWidth, newHeight)

    return new Uint8Array(nctx.getImageData(0, 0, newWidth, newHeight).data)
}

const isPowerOfTwo = (n) => ((n & (n - 1)) === 0)

function nextPowerOfTwo(n) {
    --n;
    for (let i = 1; i < 32; i <<= 1) {
        n = n | n >> i;
    }
    return n + 1;
}

function createTexture(data, renderer) {
    let pixels = data.mipmaps[0]
    let w = data.width
    let h = data.height

    if (!isPowerOfTwo(w) || !isPowerOfTwo(h)) {
        let nw = nextPowerOfTwo(w)
        let nh = nextPowerOfTwo(h)
        pixels = resizeTexture(pixels, w, h, nw, nh)
        w = nw
        h = nh
    }

    let texture = new THREE.DataTexture(pixels, w, h, THREE.RGBAFormat)
    texture.premultiplyAlpha = true
    texture.magFilter = THREE.LinearFilter
    texture.minFilter = THREE.LinearMipMapLinearFilter
    texture.anisotropy = renderer.getMaxAnisotropy()
    texture.generateMipmaps = true

    return texture
}

function createMissingTexture() {
    let pixels = new Uint8Array([255, 255, 255, 255,
                                 255, 128,   0, 255,
                                 255, 128,   0, 255,
                                 255, 255, 255, 255])
    let texture = new THREE.DataTexture(pixels, 2, 2, THREE.RGBAFormat)
    texture.magFilter = THREE.NearestFilter;
    texture.minFilter = THREE.NearestFilter;

    return texture
}

const INVISIBLE_TEXTURES = [
        'aaatrigger', 'clip', 'null', 'hint', 'nodraw',
        'invisible', 'skip', 'trigger', 'sky', 'fog']

const createMaterials = (map, renderer) =>
    map.textures.map(data => {
        let texture
        if (data.mipmaps.length > 0) {
            texture = createTexture(data, renderer)
        } else {
            texture = createMissingTexture()
        }

        texture.name = data.name
        texture.wrapS = THREE.RepeatWrapping;
        texture.wrapT = THREE.RepeatWrapping;
        texture.repeat.y = -1;
        texture.needsUpdate = true;

        return new THREE.MeshLambertMaterial({
            map: texture,
            transparent: true,
            alphaTest: 0.5,
            visible: !INVISIBLE_TEXTURES.includes(data.name.toLowerCase())
        })
    })

function createMeshes(map, materials) {
    const INVISIBLE_ENTITIES = [
        'target_cdaudio', 'trigger_auto', 'trigger_autosave',
        'trigger_camera', 'trigger_cdaudio', 'trigger_changelevel',
        'trigger_changetarget', 'trigger_counter', 'trigger_endsection',
        'trigger_gravity', 'trigger_hurt', 'trigger_monsterjump',
        'trigger_multiple', 'trigger_once', 'trigger_push',
        'trigger_relay', 'trigger_teleport', 'trigger_transition',
        'func_bomb_target', 'func_buyzone', 'func_ladder']

    let material = new THREE.MultiMaterial(materials)

    return map.models
        .map(model => {
            let geometry = new THREE.Geometry()

            geometry.vertices = model.vertices
                .map(vertex => new Vec3(vertex[0], vertex[1], vertex[2]))

            geometry.faces = model.faces
                .map((face, i) => {
                    let f = new Face3(face[0], face[1], face[2])
                    f.materialIndex = model.textureIndices[i]
                    return f
                })

            geometry.faceVertexUvs[0] = model.uv
                .map(uv => [
                    new Vec2(uv[0][0], uv[0][1]  * -1),
                    new Vec2(uv[1][0], uv[1][1]  * -1),
                    new Vec2(uv[2][0], uv[2][1]  * -1)
                ])

            let nfuv = []
            let nf = geometry.faces.filter((face, i) => {
                if (INVISIBLE_TEXTURES.includes(material.materials[face.materialIndex].map.name.toLowerCase())) {
                    return false
                } else {
                    nfuv.push(geometry.faceVertexUvs[0][i])
                    return true
                }
            })
            geometry.faces = nf
            geometry.faceVertexUvs[0] = nfuv

            geometry.mergeVertices()

            return new Mesh(geometry, material.clone())
        })
        .map((mesh, i) => {
            let entity = map.entities.find(e => e.model === i)
            if (entity) {
                if (entity.rendermode === 0) {
                    entity.renderamt = 255
                }

                if (entity.rendermode !== 4 && entity.renderamt < 255) {
                    mesh.material.materials.forEach(m => {
                        mesh.renderOrder = 1
                        m.depthWrite = false
                        m.alphaTest = 0.05
                        m.opacity = entity.renderamt / 255
                    })
                }

                if (entity.rendermode === 5) {
                    mesh.material.materials.forEach(m => {
                        m.blending = THREE.AdditiveBlending
                        mesh.renderOrder = 1
                        m.depthWrite = false
                    })
                }

                mesh.visible = !INVISIBLE_ENTITIES.includes(entity.classname)
            }

            return mesh
        })
}

export default class WorldScene {
    constructor(renderer) {
        this.renderer = renderer

        this.scene = new THREE.Scene()
        this.light = new THREE.AmbientLight(0xffffff)
        this.models = new THREE.Scene()

        this.scene.add(this.light)
        this.scene.add(this.models)
    }

    change(map) {
        let models = this.models.children
        models.forEach(model => {
            model.geometry.dispose()
            model.material.materials.forEach(material => {
                material.map.dispose()
                material.dispose()
            })
        })

        this.models.children.length = 0

        let materials = createMaterials(map, this.renderer)
        let meshes = createMeshes(map, materials)
        meshes.forEach(mesh => this.models.add(mesh))
    }

    getMeshes() {
        return this.models.children
    }

    draw(camera) {
        this.renderer.render(this.scene, camera)
    }
}<commit_msg>Disabled transparency on worldspawn entity<commit_after>import * as THREE from 'three'
import { Vector2 as Vec2 } from 'three'
import { Vector3 as Vec3 } from 'three'
import { Face3 as Face3 } from 'three'
import { Mesh } from 'three'

function resizeTexture(pixels, width, height, newWidth, newHeight) {
    let canvas = document.createElement('canvas')
    let ctx = canvas.getContext('2d')
    canvas.width = width
    canvas.height = height

    let nc = document.createElement('canvas')
    let nctx = nc.getContext('2d')
    nc.width = newWidth
    nc.height = newHeight

    let cid = ctx.createImageData(width, height)
    for (let i = 0, size = width * height * 4; i < size; i += 4) {
        cid.data[i] = pixels[i]
        cid.data[i + 1] = pixels[i + 1]
        cid.data[i + 2] = pixels[i + 2]
        cid.data[i + 3] = pixels[i + 3]
    }
    ctx.putImageData(cid, 0, 0)

    nctx.drawImage(canvas, 0, 0, newWidth, newHeight)

    return new Uint8Array(nctx.getImageData(0, 0, newWidth, newHeight).data)
}

const isPowerOfTwo = (n) => ((n & (n - 1)) === 0)

function nextPowerOfTwo(n) {
    --n;
    for (let i = 1; i < 32; i <<= 1) {
        n = n | n >> i;
    }
    return n + 1;
}

function createTexture(data, renderer) {
    let pixels = data.mipmaps[0]
    let w = data.width
    let h = data.height

    if (!isPowerOfTwo(w) || !isPowerOfTwo(h)) {
        let nw = nextPowerOfTwo(w)
        let nh = nextPowerOfTwo(h)
        pixels = resizeTexture(pixels, w, h, nw, nh)
        w = nw
        h = nh
    }

    let texture = new THREE.DataTexture(pixels, w, h, THREE.RGBAFormat)
    texture.premultiplyAlpha = true
    texture.magFilter = THREE.LinearFilter
    texture.minFilter = THREE.LinearMipMapLinearFilter
    texture.anisotropy = renderer.getMaxAnisotropy()
    texture.generateMipmaps = true

    return texture
}

function createMissingTexture() {
    let pixels = new Uint8Array([255, 255, 255, 255,
                                 255, 128,   0, 255,
                                 255, 128,   0, 255,
                                 255, 255, 255, 255])
    let texture = new THREE.DataTexture(pixels, 2, 2, THREE.RGBAFormat)
    texture.magFilter = THREE.NearestFilter;
    texture.minFilter = THREE.NearestFilter;

    return texture
}

const INVISIBLE_TEXTURES = [
        'aaatrigger', 'clip', 'null', 'hint', 'nodraw',
        'invisible', 'skip', 'trigger', 'sky', 'fog']

const createMaterials = (map, renderer) =>
    map.textures.map(data => {
        let texture
        if (data.mipmaps.length > 0) {
            texture = createTexture(data, renderer)
        } else {
            texture = createMissingTexture()
        }

        texture.name = data.name
        texture.wrapS = THREE.RepeatWrapping;
        texture.wrapT = THREE.RepeatWrapping;
        texture.repeat.y = -1;
        texture.needsUpdate = true;

        return new THREE.MeshLambertMaterial({
            map: texture,
            transparent: true,
            alphaTest: 0.5,
            visible: !INVISIBLE_TEXTURES.includes(data.name.toLowerCase())
        })
    })

function createMeshes(map, materials) {
    const INVISIBLE_ENTITIES = [
        'target_cdaudio', 'trigger_auto', 'trigger_autosave',
        'trigger_camera', 'trigger_cdaudio', 'trigger_changelevel',
        'trigger_changetarget', 'trigger_counter', 'trigger_endsection',
        'trigger_gravity', 'trigger_hurt', 'trigger_monsterjump',
        'trigger_multiple', 'trigger_once', 'trigger_push',
        'trigger_relay', 'trigger_teleport', 'trigger_transition',
        'func_bomb_target', 'func_buyzone', 'func_ladder']

    let material = new THREE.MultiMaterial(materials)

    return map.models
        .map(model => {
            let geometry = new THREE.Geometry()

            geometry.vertices = model.vertices
                .map(vertex => new Vec3(vertex[0], vertex[1], vertex[2]))

            geometry.faces = model.faces
                .map((face, i) => {
                    let f = new Face3(face[0], face[1], face[2])
                    f.materialIndex = model.textureIndices[i]
                    return f
                })

            geometry.faceVertexUvs[0] = model.uv
                .map(uv => [
                    new Vec2(uv[0][0], uv[0][1]  * -1),
                    new Vec2(uv[1][0], uv[1][1]  * -1),
                    new Vec2(uv[2][0], uv[2][1]  * -1)
                ])

            let nfuv = []
            let nf = geometry.faces.filter((face, i) => {
                if (INVISIBLE_TEXTURES.includes(material.materials[face.materialIndex].map.name.toLowerCase())) {
                    return false
                } else {
                    nfuv.push(geometry.faceVertexUvs[0][i])
                    return true
                }
            })
            geometry.faces = nf
            geometry.faceVertexUvs[0] = nfuv

            geometry.mergeVertices()

            return new Mesh(geometry, material.clone())
        })
        .map((mesh, i) => {
            if (i === 0) {
                mesh.material.materials.forEach(m => {
                    if (m.map.name.charAt(0) === '{') {
                        let data = m.map.image.data
                        for (let i = 3; i < data.length; i += 4) {
                            data[i] = 255
                        }
                        m.needsUpdate = true
                    }
                })
            } else {
                let entity = map.entities.find(e => e.model === i)
                if (entity) {
                    if (entity.rendermode === 0) {
                        entity.renderamt = 255
                    }

                    if (entity.rendermode !== 4 && entity.renderamt < 255) {
                        mesh.material.materials.forEach(m => {
                            mesh.renderOrder = 1
                            m.depthWrite = false
                            m.alphaTest = 0.05
                            m.opacity = entity.renderamt / 255
                        })
                    }

                    if (entity.rendermode === 5) {
                        mesh.material.materials.forEach(m => {
                            m.blending = THREE.AdditiveBlending
                            mesh.renderOrder = 1
                            m.depthWrite = false
                        })
                    }

                    mesh.visible = !INVISIBLE_ENTITIES.includes(entity.classname)
                }
            }

            return mesh
        })
}

export default class WorldScene {
    constructor(renderer) {
        this.renderer = renderer

        this.scene = new THREE.Scene()
        this.light = new THREE.AmbientLight(0xffffff)
        this.models = new THREE.Scene()

        this.scene.add(this.light)
        this.scene.add(this.models)
    }

    change(map) {
        let models = this.models.children
        models.forEach(model => {
            model.geometry.dispose()
            model.material.materials.forEach(material => {
                material.map.dispose()
                material.dispose()
            })
        })

        this.models.children.length = 0

        let materials = createMaterials(map, this.renderer)
        let meshes = createMeshes(map, materials)
        meshes.forEach(mesh => this.models.add(mesh))
    }

    getMeshes() {
        return this.models.children
    }

    draw(camera) {
        this.renderer.render(this.scene, camera)
    }
}<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var path = require('path');
var zlib = require('zlib');

var semver = require('semver');
var request = require('request');
var tar = require('tar');

var tmp = require('os').tmpdir();

var distBaseUrl = 'https://dl.bintray.com/lovell/sharp/';

var vipsHeaderPath = path.join(__dirname, 'include', 'vips', 'vips.h');

// -- Helpers

// Does this file exist?
var isFile = function(file) {
  var exists = false;
  try {
    exists = fs.statSync(file).isFile();
  } catch (err) {}
  return exists;
};

var unpack = function(tarPath, done) {
  var extractor = tar.Extract({
    path: __dirname
  });
  extractor.on('error', error);
  extractor.on('end', function() {
    if (!isFile(vipsHeaderPath)) {
      error('Could not unpack ' + tarPath);
    }
    if (typeof done === 'function') {
      done();
    }
  });
  fs.createReadStream(tarPath).on('error', error)
    .pipe(zlib.Unzip())
    .pipe(extractor);
};

// Error
var error = function(msg) {
  if (msg instanceof Error) {
    msg = msg.message;
  }
  process.stderr.write('ERROR: ' + msg + '\n');
  process.exit(1);
};

// -- Binary downloaders

module.exports.download_vips = function() {
  // Has vips been installed locally?
  if (!isFile(vipsHeaderPath)) {
    // Ensure Intel 64-bit or ARM
    if (process.arch === 'ia32') {
      error('Intel Architecture 32-bit systems require manual installation - please see http://sharp.dimens.io/en/stable/install/');
    }
    // Ensure glibc >= 2.15
    var lddVersion = process.env.LDD_VERSION;
    if (lddVersion) {
      if (/(glibc|gnu libc)/i.test(lddVersion)) {
        var glibcVersion = lddVersion ? lddVersion.split(/\n/)[0].split(' ').slice(-1)[0].trim() : '';
        if (glibcVersion && semver.lt(glibcVersion + '.0', '2.13.0')) {
          error('glibc version ' + glibcVersion + ' requires manual installation - please see http://sharp.dimens.io/en/stable/install/');
        }
      } else {
        error(lddVersion.split(/\n/)[0] + ' requires manual installation - please see http://sharp.dimens.io/en/stable/install/');
      }
    }
    // Arch/platform-specific .tar.gz
    var platform = (process.arch === 'arm') ? 'arm' : process.platform.substr(0, 3);
    var tarFilename = ['libvips', process.env.npm_package_config_libvips, platform].join('-') + '.tar.gz';
    var tarPath = path.join(__dirname, 'packaging', tarFilename);
    if (isFile(tarPath)) {
      unpack(tarPath);
    } else {
      // Download to per-process temporary file
      tarPath = path.join(tmp, process.pid + '-' + tarFilename);
      var tmpFile = fs.createWriteStream(tarPath).on('finish', function() {
        unpack(tarPath, function() {
          // Attempt to remove temporary file
          try {
            fs.unlinkSync(tarPath);
          } catch (err) {}
        });
      });
      var options = {
        url: distBaseUrl + tarFilename
      };
      if (process.env.npm_config_https_proxy) {
        // Use the NPM-configured HTTPS proxy
        options.proxy = process.env.npm_config_https_proxy;
      }
      request(options).on('response', function(response) {
        if (response.statusCode !== 200) {
          error(distBaseUrl + tarFilename + ' status code ' + response.statusCode);
        }
      }).on('error', function(err) {
        error('Download from ' + distBaseUrl + tarFilename + ' failed: ' + err.message);
      }).pipe(tmpFile);
    }
  }
};

module.exports.use_global_vips = function() {
  var useGlobalVips = false;
  var globalVipsVersion = process.env.GLOBAL_VIPS_VERSION;
  if (globalVipsVersion) {
    useGlobalVips = semver.gte(
      globalVipsVersion,
      process.env.npm_package_config_libvips
    );
  }
  if (process.platform === 'darwin' && !useGlobalVips) {
    if (globalVipsVersion) {
      error(
        'Found libvips ' + globalVipsVersion + ' but require ' + process.env.npm_package_config_libvips +
        '\nPlease upgrade libvips by running: brew update && brew upgrade'
      );
    } else {
      error('Please install libvips by running: brew install homebrew/science/vips --with-webp --with-graphicsmagick');
    }
  }
  process.stdout.write(useGlobalVips ? 'true' : 'false');
};
<commit_msg>Support gyp-based (re)build without npm env vars #412<commit_after>'use strict';

var fs = require('fs');
var path = require('path');
var zlib = require('zlib');

var semver = require('semver');
var request = require('request');
var tar = require('tar');

var tmp = require('os').tmpdir();

var distBaseUrl = 'https://dl.bintray.com/lovell/sharp/';

// Use NPM-provided environment variable where available, falling back to require-based method for Electron
var minimumLibvipsVersion = process.env.npm_package_config_libvips || require('./package.json').config.libvips;

var vipsHeaderPath = path.join(__dirname, 'include', 'vips', 'vips.h');

// -- Helpers

// Does this file exist?
var isFile = function(file) {
  var exists = false;
  try {
    exists = fs.statSync(file).isFile();
  } catch (err) {}
  return exists;
};

var unpack = function(tarPath, done) {
  var extractor = tar.Extract({
    path: __dirname
  });
  extractor.on('error', error);
  extractor.on('end', function() {
    if (!isFile(vipsHeaderPath)) {
      error('Could not unpack ' + tarPath);
    }
    if (typeof done === 'function') {
      done();
    }
  });
  fs.createReadStream(tarPath).on('error', error)
    .pipe(zlib.Unzip())
    .pipe(extractor);
};

// Error
var error = function(msg) {
  if (msg instanceof Error) {
    msg = msg.message;
  }
  process.stderr.write('ERROR: ' + msg + '\n');
  process.exit(1);
};

// -- Binary downloaders

module.exports.download_vips = function() {
  // Has vips been installed locally?
  if (!isFile(vipsHeaderPath)) {
    // Ensure Intel 64-bit or ARM
    if (process.arch === 'ia32') {
      error('Intel Architecture 32-bit systems require manual installation - please see http://sharp.dimens.io/en/stable/install/');
    }
    // Ensure glibc >= 2.15
    var lddVersion = process.env.LDD_VERSION;
    if (lddVersion) {
      if (/(glibc|gnu libc)/i.test(lddVersion)) {
        var glibcVersion = lddVersion ? lddVersion.split(/\n/)[0].split(' ').slice(-1)[0].trim() : '';
        if (glibcVersion && semver.lt(glibcVersion + '.0', '2.13.0')) {
          error('glibc version ' + glibcVersion + ' requires manual installation - please see http://sharp.dimens.io/en/stable/install/');
        }
      } else {
        error(lddVersion.split(/\n/)[0] + ' requires manual installation - please see http://sharp.dimens.io/en/stable/install/');
      }
    }
    // Arch/platform-specific .tar.gz
    var platform = (process.arch === 'arm') ? 'arm' : process.platform.substr(0, 3);
    var tarFilename = ['libvips', minimumLibvipsVersion, platform].join('-') + '.tar.gz';
    var tarPath = path.join(__dirname, 'packaging', tarFilename);
    if (isFile(tarPath)) {
      unpack(tarPath);
    } else {
      // Download to per-process temporary file
      tarPath = path.join(tmp, process.pid + '-' + tarFilename);
      var tmpFile = fs.createWriteStream(tarPath).on('finish', function() {
        unpack(tarPath, function() {
          // Attempt to remove temporary file
          try {
            fs.unlinkSync(tarPath);
          } catch (err) {}
        });
      });
      var options = {
        url: distBaseUrl + tarFilename
      };
      if (process.env.npm_config_https_proxy) {
        // Use the NPM-configured HTTPS proxy
        options.proxy = process.env.npm_config_https_proxy;
      }
      request(options).on('response', function(response) {
        if (response.statusCode !== 200) {
          error(distBaseUrl + tarFilename + ' status code ' + response.statusCode);
        }
      }).on('error', function(err) {
        error('Download from ' + distBaseUrl + tarFilename + ' failed: ' + err.message);
      }).pipe(tmpFile);
    }
  }
};

module.exports.use_global_vips = function() {
  var useGlobalVips = false;
  var globalVipsVersion = process.env.GLOBAL_VIPS_VERSION;
  if (globalVipsVersion) {
    useGlobalVips = semver.gte(
      globalVipsVersion,
      minimumLibvipsVersion
    );
  }
  if (process.platform === 'darwin' && !useGlobalVips) {
    if (globalVipsVersion) {
      error(
        'Found libvips ' + globalVipsVersion + ' but require ' + minimumLibvipsVersion +
        '\nPlease upgrade libvips by running: brew update && brew upgrade'
      );
    } else {
      error('Please install libvips by running: brew install homebrew/science/vips --with-webp --with-graphicsmagick');
    }
  }
  process.stdout.write(useGlobalVips ? 'true' : 'false');
};
<|endoftext|>


<commit_before>/*
jinjup-response
jinjup.com
Copyright (c) 2013-2014 Jon Camuso <jcamuso@exechos.com>
MIT Licensed
*/

// Initialize a jinjup Response
//
// @param	{String}	method
// @param	{Object}	subject
// @param	{Object} || {String}	content
//
function Response(method, subject, content)
{
	var responses = null;
	this.method = method ? method : '';
	this.subject = subject;
	this.content = content ? content : null;

	this.appendResponse = function (response)
	{
		if (response instanceof Response)
		{
			if (!(responses in this))
			{
				this.responses = [];
			}
			if (this.responses === null)
			{
				responses = [];
			}
			responses.push(response);
		}
	}
};

// Initialize a jinjup Response Subject
//
// @param	{String}	space
// @param	{String}	type
// @param	{String}	path
// @param	{String}	name
//
function Subject(space, type, path, name)
{
	this.space = space;
	this.type = type;
	this.path = path;
	if (name)
	{
		this.name = name;
	}
};
var tempSubject = function () { };
tempSubject.prototype = Subject.prototype;

function Element(path)
{
	Subject.call(this, 'dom', 'element', path);
};
Element.prototype = new tempSubject();
Element.prototype.constructor = Subject;

function Attribute(path, name)
{
	Subject.call(this, 'dom', 'element', path, name);
};
Attribute.prototype = new tempSubject();
Attribute.prototype.constructor = Subject;

function Console(path)
{
	Subject.call(this, 'console', 'console', path);
};
Console.prototype = new tempSubject();
Console.prototype.constructor = Subject;

var tempConsole = function () { };
tempConsole.prototype = Console.prototype;

function Log()
{
	Console.call(this, 'log');
};
Log.prototype = new tempConsole();
Log.prototype.constructor = Console;

function Warn()
{
	Console.call(this, 'warn');
};
Warn.prototype = new tempConsole();
Warn.prototype.constructor = Console;

function Info()
{
	Console.call(this, 'info');
};
Info.prototype = new tempConsole();
Info.prototype.constructor = Console;

function Error(path)
{
	Console.call(this, 'error');
};
Error.prototype = new tempConsole();
Error.prototype.constructor = Console;

// Create a new Response
//
exports.createResponse = function (method, subject, content)
{
	return new Response(method, subject, content);
}

// Insert content (element, html or text) into element resolved by target
//
exports.postElement = function (path, content)
{
	return new Response('post', new Element(path), content);
}

// Replace existing element(s) @ path with content
//
exports.putElement = function (path, content)
{
	return new Response('put', new Element(path), content);
}

// Update element(s) set target[attribute] equal to content
//
exports.putAttribute = function (path, name, content)
{
	return new Response('put', new Attribute(path, name), content);
}

// Delete target element
//
exports.deleteElement = function (path)
{
	return new Response('delete', new Element(path));
}

// Delete target element[attribute] attribute
//
exports.deleteAttribute = function (path, name)
{
	return new Response('delete', new Attribute(path, name));
}

exports.postConsole = function (path, content)
{
	return new Response('post', new Console(path), content);
}
exports.postLog = function (content)
{
	return new Response('post', new Log(), content);
}
exports.postError = function (content)
{
	return new Response('post', new Error(), content);
}
exports.postWarn = function (content)
{
	return new Response('post', new Warn(), content);
}
exports.postInfo = function (content)
{
	return new Response('post', new Info(), content);
}

<commit_msg>Fixed bug in Attribute Subject constructor, modified responses to be public.<commit_after>/*
jinjup-response v0.1.0
jinjup.com
Copyright (c) 2013-2014 Jon Camuso <jcamuso@exechos.com>
MIT Licensed
*/

// Initialize a jinjup Response
//
// @param	{String}	method
// @param	{Object}	subject
// @param	{Object} || {String}	content
//
function Response(method, subject, content)
{
	this.responses = null;
	this.method = method ? method : '';
	this.subject = subject;
	this.content = content ? content : null;

	this.appendResponse = function (response)
	{
		if (response instanceof Response)
		{
			if (!this.responses)
			{
				this.responses = [];
			}
			this.responses.push(response);
		}
	}
};

// Initialize a jinjup Response Subject
//
// @param	{String}	space
// @param	{String}	type
// @param	{String}	path
// @param	{String}	name
//
function Subject(space, type, path, name)
{
	this.space = space;
	this.type = type;
	this.path = path;
	if (name)
	{
		this.name = name;
	}
};
var tempSubject = function () { };
tempSubject.prototype = Subject.prototype;

function Element(path)
{
	Subject.call(this, 'dom', 'element', path);
};
Element.prototype = new tempSubject();
Element.prototype.constructor = Subject;

function Attribute(path, name)
{
	Subject.call(this, 'dom', 'attribute', path, name);
};
Attribute.prototype = new tempSubject();
Attribute.prototype.constructor = Subject;

function Console(path)
{
	Subject.call(this, 'console', 'console', path);
};
Console.prototype = new tempSubject();
Console.prototype.constructor = Subject;

var tempConsole = function () { };
tempConsole.prototype = Console.prototype;

function Log()
{
	Console.call(this, 'log');
};
Log.prototype = new tempConsole();
Log.prototype.constructor = Console;

function Warn()
{
	Console.call(this, 'warn');
};
Warn.prototype = new tempConsole();
Warn.prototype.constructor = Console;

function Info()
{
	Console.call(this, 'info');
};
Info.prototype = new tempConsole();
Info.prototype.constructor = Console;

function Error(path)
{
	Console.call(this, 'error');
};
Error.prototype = new tempConsole();
Error.prototype.constructor = Console;

// Create a new Response
//
exports.createResponse = function (method, subject, content)
{
	return new Response(method, subject, content);
}

// Insert content (element, html or text) into element resolved by target
//
exports.postElement = function (path, content)
{
	return new Response('post', new Element(path), content);
}

// Replace existing element(s) @ path with content
//
exports.putElement = function (path, content)
{
	return new Response('put', new Element(path), content);
}

// Update element(s) set target[attribute] equal to content
//
exports.putAttribute = function (path, name, content)
{
	return new Response('put', new Attribute(path, name), content);
}

// Delete target element
//
exports.deleteElement = function (path)
{
	return new Response('delete', new Element(path));
}

// Delete target element[attribute] attribute
//
exports.deleteAttribute = function (path, name)
{
	return new Response('delete', new Attribute(path, name));
}

// Insert information into consol space
//
exports.postConsole = function (path, content)
{
	return new Response('post', new Console(path), content);
}

// Insert content into consol Log
//
exports.postLog = function (content)
{
	return new Response('post', new Log(), content);
}

// Insert content into consol Error
//
exports.postError = function (content)
{
	return new Response('post', new Error(), content);
}

// Insert content into consol Warn
//
exports.postWarn = function (content)
{
	return new Response('post', new Warn(), content);
}

// Insert content into consol Info
//
exports.postInfo = function (content)
{
	return new Response('post', new Info(), content);
}

<|endoftext|>