<commit_before>import {
    every, some, partial, isArray, isEqual, isMatch, intersection, union, difference, gt, gte, lt, lte, chain, unique
}
from 'lodash';

/*

Boolean Operators

*/

function $and(...values) {
    console.log('$and', values);
    return every(values);
}

function $or(...values) {
    return some(values);
}

function $not(...values) {
    return !some(values);
}

/*

Set Operators

*/

function $asSet(array) {
    return chain(array).unique(false).value().sort($cmp);
}

function $setEquals(...arrays) {

    var sets = arrays.map($asSet),
        head = sets[0];

    return every(sets, function(obj){
    	console.log('obj eq head?', obj, head);
    	return isEqual(head, obj);
    });
}

function $setIntersection(...arrays) {
    return $asSet(intersection(...arrays));
}

function $setUnion(...arrays) {
    return union(...arrays.map($asSet));
}

function $setDifference(...arrays) {
    return difference(...arrays.map($asSet));
}

function $setIsSubset(subset, superset) {
    return isEqual($asSet(intersection(subset, superset)), $asSet(subset));
}

function $anyElementTrue(values) {
    return $or(...values);
}

function $allElementsTrue(values) {
    return $and(...values);
}

/*

Comparison Operators

*/

function $cmp(value1, value2) {
    console.log('cmp', value1, value2);

    if (isArray(value1) && isArray(value2)) {
    	return 0;
    }

    if ($lt(value1, value2)) {
        return -1;
    } else if ($gt(value1, value2)) {
        return 1;
    }
    return 0;
}

function $eq(value1, value2) {
    console.log('$eq', arguments[0], arguments[1]);
    return isEqual(value1, value2);
}

function $gt(value1, value2) {
    console.log('$gt', arguments[0], arguments[1]);

    if (isArray(value2) && !isArray(value1)) {
        return false;
    } else if (isArray(value1) && !isArray(value2)) {
        return true;
    }

    return gt(value1, value2);
}

function $gte(value1, value2) {
    console.log('$gte', arguments[0], arguments[1]);

    if (isArray(value2) && !isArray(value1)) {
        return false;
    } else if (isArray(value1) && !isArray(value2)) {
        return true;
    }

    return gte(value1, value2);
}

function $lt(value1, value2) {
    console.log('$lt', arguments[0], arguments[1]);

    if (isArray(value2) && !isArray(value1)) {
        return true;
    } else if (isArray(value1) && !isArray(value2)) {
        return false;
    }

    return lt(value1, value2);

}

function $lte(value1, value2) {
    console.log('$lte', arguments[0], arguments[1]);

    if (isArray(value2) && !isArray(value1)) {
        return true;
    } else if (isArray(value1) && !isArray(value2)) {
        return false;
    }

    return lte(value1, value2);

}

function $ne(value1, value2) {
    return !$eq(value1, value2);
}

/*

String Operators

*/

function $substr(string, start, len) {
    return string.slice(start, start + len);
}

export default {
    // Boolean Operators
    $and,
    $or,
    $not,
    // Set Operators
    $setEquals,
    $setIntersection,
    $setUnion,
    $setDifference,
    $setIsSubset,
    $anyElementTrue,
    $allElementsTrue,
    // Comparison Operators
    $cmp,
    $gt,
    $gte,
    $lt,
    $lte,
    $ne,
    // String Operators
    $substr

}
<commit_msg>fix(operators): Remove debugging function<commit_after>import {
    every, some, partial, isArray, isEqual, isMatch, intersection, union, difference, gt, gte, lt, lte, chain, unique
}
from 'lodash';

/*

Boolean Operators

*/

function $and(...values) {
    console.log('$and', values);
    return every(values);
}

function $or(...values) {
    return some(values);
}

function $not(...values) {
    return !some(values);
}

/*

Set Operators

*/

function $asSet(array) {
    return chain(array).unique(false).value().sort($cmp);
}

function $setEquals(...arrays) {

    var sets = arrays.map($asSet),
        head = sets[0];

    return every(sets, partial(isEqual, head));
}

function $setIntersection(...arrays) {
    return $asSet(intersection(...arrays));
}

function $setUnion(...arrays) {
    return union(...arrays.map($asSet));
}

function $setDifference(...arrays) {
    return difference(...arrays.map($asSet));
}

function $setIsSubset(subset, superset) {
    return isEqual($asSet(intersection(subset, superset)), $asSet(subset));
}

function $anyElementTrue(values) {
    return $or(...values);
}

function $allElementsTrue(values) {
    return $and(...values);
}

/*

Comparison Operators

*/

function $cmp(value1, value2) {
    console.log('cmp', value1, value2);

    if (isArray(value1) && isArray(value2)) {
    	return 0;
    }

    if ($lt(value1, value2)) {
        return -1;
    } else if ($gt(value1, value2)) {
        return 1;
    }
    return 0;
}

function $eq(value1, value2) {
    console.log('$eq', arguments[0], arguments[1]);
    return isEqual(value1, value2);
}

function $gt(value1, value2) {
    console.log('$gt', arguments[0], arguments[1]);

    if (isArray(value2) && !isArray(value1)) {
        return false;
    } else if (isArray(value1) && !isArray(value2)) {
        return true;
    }

    return gt(value1, value2);
}

function $gte(value1, value2) {
    console.log('$gte', arguments[0], arguments[1]);

    if (isArray(value2) && !isArray(value1)) {
        return false;
    } else if (isArray(value1) && !isArray(value2)) {
        return true;
    }

    return gte(value1, value2);
}

function $lt(value1, value2) {
    console.log('$lt', arguments[0], arguments[1]);

    if (isArray(value2) && !isArray(value1)) {
        return true;
    } else if (isArray(value1) && !isArray(value2)) {
        return false;
    }

    return lt(value1, value2);

}

function $lte(value1, value2) {
    console.log('$lte', arguments[0], arguments[1]);

    if (isArray(value2) && !isArray(value1)) {
        return true;
    } else if (isArray(value1) && !isArray(value2)) {
        return false;
    }

    return lte(value1, value2);

}

function $ne(value1, value2) {
    return !$eq(value1, value2);
}

/*

String Operators

*/

function $substr(string, start, len) {
    return string.slice(start, start + len);
}

export default {
    // Boolean Operators
    $and,
    $or,
    $not,
    // Set Operators
    $setEquals,
    $setIntersection,
    $setUnion,
    $setDifference,
    $setIsSubset,
    $anyElementTrue,
    $allElementsTrue,
    // Comparison Operators
    $cmp,
    $gt,
    $gte,
    $lt,
    $lte,
    $ne,
    // String Operators
    $substr

}
<|endoftext|>


<commit_before>'use strict'
let Term = require("../term/term.js")
let fns = require("../fns.js")
let tagger = require("./pos/tagger.js")

//a sentence is an array of Term objects, along with their various methods
class Sentence {

  constructor(str) {
    this.str = str || "";
    let terms = str.split(" ")
    this.terms = terms.map(function(s, i) {
      let info = {
        index: i
      }
      return new Term(s, info)
    })
  }

  //Sentence methods:

  //the ending punctuation
  terminator() {
    let allowed = {
      ".": true,
      "!": true,
      "?": true
    }
    let char = this.str.slice(-1) || "";
    if (allowed[char]) {
      return char
    }
    return "."
  }

  //part-of-speech assign each term
  tag() {
    this.terms = tagger(this)
    return this.terms
  }

  //is it a question/statement
  sentence_type() {
    let char = this.terminator()
    let types = {
      "?": "interrogative",
      "!": "exclamative",
      ".": "declarative",
    }
    return types[char] || "declarative";
  }

  //map over Term methods
  normalized() {
    return fns.pluck(this.terms, 'normal').join(" ")
  }
  text() {
    return fns.pluck(this.terms, 'text').join(" ")
  }
  parents() {
    return fns.pluck(this.terms, 'parent')
  }
}

var s = new Sentence("studying")
s.tag()
console.log(s)

module.exports = Sentence
<commit_msg>removed console statement<commit_after>'use strict'
let Term = require("../term/term.js")
let fns = require("../fns.js")
let tagger = require("./pos/tagger.js")

//a sentence is an array of Term objects, along with their various methods
class Sentence {

  constructor(str) {
    this.str = str || "";
    let terms = str.split(" ")
    this.terms = terms.map(function(s, i) {
      let info = {
        index: i
      }
      return new Term(s, info)
    })
  }

  //Sentence methods:

  //the ending punctuation
  terminator() {
    let allowed = {
      ".": true,
      "!": true,
      "?": true
    }
    let char = this.str.slice(-1) || "";
    if (allowed[char]) {
      return char
    }
    return "."
  }

  //part-of-speech assign each term
  tag() {
    this.terms = tagger(this)
    return this.terms
  }

  //is it a question/statement
  sentence_type() {
    let char = this.terminator()
    let types = {
      "?": "interrogative",
      "!": "exclamative",
      ".": "declarative",
    }
    return types[char] || "declarative";
  }

  //map over Term methods
  normalized() {
    return fns.pluck(this.terms, 'normal').join(" ")
  }
  text() {
    return fns.pluck(this.terms, 'text').join(" ")
  }
  parents() {
    return fns.pluck(this.terms, 'parent')
  }
}

module.exports = Sentence
<|endoftext|>


<commit_before>import _ from "lodash";
import fs from "fs-extra";
import fsPath from "path";
import Promise from "bluebird";
import express from "express";
import compression from "compression";
import webpack from "webpack";
import webpackMiddleware from "webpack-dev-middleware";
import webpackHotMiddleware from "webpack-hot-middleware";
import * as config from "../webpack-config";
import serverMethods from "./server-methods";
import bdd from "../shared/bdd";

const parseSpecs = (paths) => {
    bdd.register();
    paths.forEach(path => { require(path); });
    bdd.unregister();
  };

export const readFileSync = (path) => {
  if (fs.existsSync(path)) {
    return fs.readFileSync(path).toString()
  }
};

/**
 * Middleware for running the UIHarness server.
 * @param {object} options: Configuration settings.
 *                          If a {string/array} is passed, that value is set as the `entry`
 *
 *                          - basePath: The base URL path. Default "/".
 *                          - entry: A string or array of strings to entry points of files
 *                                   to pass to WebPack to build for the client.
 *                          - port: The port to run on (default:8080).
 *                          - env:  The environment to run in ("development" / "production").
 *
 * @param callback: Invoked when the JS has been bundled.
 */
export const middleware = (options = {}, callback) => {
  // Convert string or array options into the "entry" path.
  options = _.isString(options) || _.isArray(options) ? { entry: options } : options;
  const PORT = options.port || 8080;
  const ENV = options.env || process.env.NODE_ENV || "development"
  const IS_PRODUCTION = ENV === "production";
  const router = express.Router();

  // Get the webpack configuration settings.
  const webpackConfig = config.browser({ port: PORT, env: ENV });
  router.use(express.static(fsPath.join(__dirname, "../../public"), { maxage: "60 days" }))
  if (IS_PRODUCTION) {
    router.use(compression());
  }

  // Prepare entry paths for the WebPack bundle.
  let entry = options.entry || [];
  if (!_.isArray(entry)) { entry = [entry]; }
  entry = entry.map(path => _.startsWith(path, ".") ? fsPath.resolve(path) : path);
  entry.forEach(path => {
      // Ensure a specific index entry file if a folder was given.
      // NB: Not having an entry file can cause build-errors in WebPack.
      if (!path.endsWith(".js")) { path += "/index.js"; }
      webpackConfig.entry.push(path);
  });

  // Initialize the [describe/it] statements.
  parseSpecs(entry);

  // Prepare webpack JS.
  if (IS_PRODUCTION) {
    // Compile and minify webpack JS for production.
    console.log("webpack bundling...");
    webpack(webpackConfig, (err, stats) => {
      console.log("...webpack bundled into '/public/'.");
      if (err) { throw err; }
      if (_.isFunction(callback)) { callback(router); }
    });

  } else {
    // Create the WebPack compiler and "hot-reloading" dev server.
    const compiler = webpack(webpackConfig);
    router.use(webpackMiddleware(compiler, config.devServer({ port: PORT })));
    router.use(webpackHotMiddleware(compiler));
    if (_.isFunction(callback)) { callback(router); }
  }

  // Initialize the server-methods.
  router.use(serverMethods.middleware);

  // Finish up.
  return router;
};

/**
 * Starts the UIHarness within a development server.
 * @param {object} options: Configuration settings.
 *                          If a {string/array} is passed, that value is set as the `entry`
 *
 *                          - basePath: The base URL path. Default "/".
 *                          - entry: A string or array of strings to entry points of files
 *                                   to pass to WebPack to build for the client.
 *                          - port: The port to run on (default:8080).
 *                          - env:  The environment to run in ("development" / "production").
 *
 * @param callback: Invoked when the server has started.
 */
export const start = (options = {}, callback) => {
  const BASE_PATH = options.basePath || "/";
  const PORT = options.port || 8080;
  const ENV = options.env || process.env.NODE_ENV || "development"

  console.log("");
  console.log(`Starting (${ ENV })...`);

  const startListening = () => {
      app.listen(PORT, () => {
            console.log("");
            console.log("UIHarness:");
            console.log(" - port:", PORT);
            console.log(" - env: ", ENV);
            console.log("");
            if (_.isFunction(callback)) { callback(); }
      });
    };

  const app = express();
  app.use(BASE_PATH, middleware(options, () => { startListening(); }));
};

/**
 * Creates default project structure (if not present)
 * and starts the server.
 */
export const init = (options = {}, callback) => {

  // Ensure the specs folder exists.
  const specsPath = fsPath.resolve("./specs/index.js");
  if (!fs.existsSync(specsPath)) {
    // const sourcePath = fsPath.join(__dirname, "../../src/templates/init-index.js");
    const js = "";
    fs.outputFileSync(specsPath, js);
  }

  // Prepare the entry path.
  let entry = options.entry;
  if (!_.isArray(entry)) { entry = [entry]; }
  entry = _.chain(entry).compact(entry).flatten(entry).value();
  entry.push("./specs");
  options.entry = entry;

  // Start the server.
  start(options, callback);
};
<commit_msg>Change default port<commit_after>import R from "ramda";
import _ from "lodash";
import fs from "fs-extra";
import fsPath from "path";
import Promise from "bluebird";
import express from "express";
import compression from "compression";
import webpack from "webpack";
import webpackMiddleware from "webpack-dev-middleware";
import webpackHotMiddleware from "webpack-hot-middleware";
import * as config from "../webpack-config";
import serverMethods from "./server-methods";
import bdd from "../shared/bdd";

const DEFAULT_PORT = 3030;

const parseSpecs = (paths) => {
    bdd.register();
    paths.forEach(path => { require(path); });
    bdd.unregister();
  };

export const readFileSync = (path) => {
  if (fs.existsSync(path)) {
    return fs.readFileSync(path).toString()
  }
};

/**
 * Middleware for running the UIHarness server.
 * @param {object} options: Configuration settings.
 *                          If a {string/array} is passed, that value is set as the `entry`
 *
 *                          - basePath: The base URL path. Default "/".
 *                          - entry: A string or array of strings to entry points of files
 *                                   to pass to WebPack to build for the client.
 *                          - port: The port to run on (default:3030).
 *                          - env:  The environment to run in ("development" / "production").
 *
 * @param callback: Invoked when the JS has been bundled.
 */
export const middleware = (options = {}, callback) => {
  // Convert string or array options into the "entry" path.
  options = _.isString(options) || _.isArray(options) ? { entry: options } : options;
  const PORT = options.port || DEFAULT_PORT;
  const ENV = options.env || process.env.NODE_ENV || "development"
  const IS_PRODUCTION = ENV === "production";
  const router = express.Router();

  // Get the webpack configuration settings.
  const webpackConfig = config.browser({ port: PORT, env: ENV });
  router.use(express.static(fsPath.join(__dirname, "../../public"), { maxage: "60 days" }))
  if (IS_PRODUCTION) {
    router.use(compression());
  }

  // Prepare entry paths for the WebPack bundle.
  let entry = options.entry || [];
  if (!_.isArray(entry)) { entry = [entry]; }
  if (entry.length === 0 && fs.existsSync(fsPath.resolve("./specs"))) { entry.push("./specs"); }
  entry = entry.map(path => _.startsWith(path, ".") ? fsPath.resolve(path) : path);
  entry.forEach(path => {
      // Ensure a specific index entry file if a folder was given.
      // NB: Not having an entry file can cause build-errors in WebPack.
      if (!path.endsWith(".js")) { path += "/index.js"; }
      webpackConfig.entry.push(path);
  });

  // Initialize the [describe/it] statements.
  parseSpecs(entry);

  // Prepare webpack JS.
  if (IS_PRODUCTION) {
    // Compile and minify webpack JS for production.
    console.log("webpack bundling...");
    webpack(webpackConfig, (err, stats) => {
      console.log("...webpack bundled into '/public/'.");
      if (err) { throw err; }
      if (_.isFunction(callback)) { callback(router); }
    });

  } else {
    // Create the WebPack compiler and "hot-reloading" dev server.
    const compiler = webpack(webpackConfig);
    router.use(webpackMiddleware(compiler, config.devServer({ port: PORT })));
    router.use(webpackHotMiddleware(compiler));
    if (_.isFunction(callback)) { callback(router); }
  }

  // Initialize the server-methods.
  router.use(serverMethods.middleware);

  // Finish up.
  return router;
};

/**
 * Starts the UIHarness within a development server.
 * @param {object} options: Configuration settings.
 *                          If a {string/array} is passed, that value is set as the `entry`
 *
 *                          - basePath: The base URL path. Default "/".
 *                          - entry: A string or array of strings to entry points of files
 *                                   to pass to WebPack to build for the client.
 *                          - port: The port to run on (default:3030).
 *                          - env:  The environment to run in ("development" / "production").
 *
 * @param callback: Invoked when the server has started.
 */
export const start = (options = {}, callback) => {
  const BASE_PATH = options.basePath || "/";
  const PORT = options.port || DEFAULT_PORT;
  const ENV = options.env || process.env.NODE_ENV || "development"

  console.log("");
  console.log(`Starting (${ ENV })...`);

  const startListening = () => {
      app.listen(PORT, () => {
            console.log("");
            console.log("UIHarness:");
            console.log(" - port:", PORT);
            console.log(" - env: ", ENV);
            console.log("");
            if (_.isFunction(callback)) { callback(); }
      });
    };

  const app = express();
  app.use(BASE_PATH, middleware(options, () => { startListening(); }));
};

/**
 * Creates default project structure (if not present)
 * and starts the server.
 */
export const init = (options = {}, callback) => {

  // Ensure the specs folder exists.
  const specsPath = fsPath.resolve("./specs/index.js");
  if (!fs.existsSync(specsPath)) {
    const js = "";
    fs.outputFileSync(specsPath, js);
  }

  // Prepare the entry path.
  let entry = options.entry;
  if (!_.isArray(entry)) { entry = [entry]; }
  entry = _.chain(entry).compact(entry).flatten(entry).value();
  entry.push("./specs");
  options.entry = entry;

  // Start the server.
  start(options, callback);
};
<|endoftext|>


<commit_before>import configs from '../../../configs/project/server';
import bodyParser from '../middlewares/bodyParser';
import authRequired from '../middlewares/authRequired';
import fileUpload from '../middlewares/fileUpload';
import userController from '../controllers/user';
import formValidationController from '../controllers/formValidation';
import localeController from '../controllers/locale';
import todoController from '../controllers/todo';

export default ({ app }) => {
  app.post('/api/user', bodyParser.json, userController.create);
  app.post('/api/user/login', bodyParser.json, userController.login);
  app.get('/api/user/logout', userController.logout);
  app.get('/api/user/me', authRequired, userController.show);
  app.put('/api/user/me', authRequired, bodyParser.json, userController.update);
  if (configs.firebase) {
    let firebaseController = require('../controllers/firebase').default;
    app.get('/api/user/me/firebase/token',
      authRequired, firebaseController.readToken);
  }
  app.post('/api/user/me/avatar',
    authRequired,
    fileUpload.disk({
      destination: 'user/{userId}',
      filename: 'avatar.jpg',
    }).single('avatar'),
    userController.uploadAvatar);
  app.post('/api/forms/register/fields/email/validation',
    bodyParser.json,
    formValidationController.register.email
  );
  app.get('/api/locale/:locale', localeController.show);
  app.post('/api/todo', bodyParser.json, todoController.create);
  app.get('/api/todo', todoController.list);
  app.delete('/api/todo/:id', todoController.remove);
};
<commit_msg>Add comment on api routes<commit_after>import configs from '../../../configs/project/server';
import bodyParser from '../middlewares/bodyParser';
import authRequired from '../middlewares/authRequired';
import fileUpload from '../middlewares/fileUpload';
import userController from '../controllers/user';
import formValidationController from '../controllers/formValidation';
import localeController from '../controllers/locale';
import todoController from '../controllers/todo';

export default ({ app }) => {
  // user
  app.post('/api/user', bodyParser.json, userController.create);
  app.post('/api/user/login', bodyParser.json, userController.login);
  app.get('/api/user/logout', userController.logout);
  app.get('/api/user/me', authRequired, userController.show);
  app.put('/api/user/me', authRequired, bodyParser.json, userController.update);
  if (configs.firebase) {
    let firebaseController = require('../controllers/firebase').default;
    app.get('/api/user/me/firebase/token',
      authRequired, firebaseController.readToken);
  }
  app.post('/api/user/me/avatar',
    authRequired,
    fileUpload.disk({
      destination: 'user/{userId}',
      filename: 'avatar.jpg',
    }).single('avatar'),
    userController.uploadAvatar);

  // form
  app.post('/api/forms/register/fields/email/validation',
    bodyParser.json,
    formValidationController.register.email
  );

  // locale
  app.get('/api/locale/:locale', localeController.show);

  // todo
  app.post('/api/todo', bodyParser.json, todoController.create);
  app.get('/api/todo', todoController.list);
  app.delete('/api/todo/:id', todoController.remove);
};
<|endoftext|>


<commit_before>import fetchProducts from './fetch-products';

export const CURRENT_REQUEST = Symbol('CURRENT_REQUEST');
export const LAST_REQUEST_PAGE = Symbol('LAST_REQUEST_PAGE');
export const LAST_RESPONSE_META = Symbol('LAST_RESPONSE_META');
export const PRODUCTS = Symbol('PRODUCTS');

const productsService = {
  [CURRENT_REQUEST]: null,
  [LAST_REQUEST_PAGE]: 0,
  [LAST_RESPONSE_META]: null,
  [PRODUCTS]: new Map(),
};

export default productsService;

/**
 * Get products' ordered IDs.
 *
 * @returns {string[]}
 */
export const getIds = () => Array.from(productsService[PRODUCTS].keys());

/**
 * Get product's index by ID.
 *
 * @param {string} id
 * @param {string[]} [ids] Collection of ordered IDs to iterate through.
 * Defaults to the products map's IDs.
 * @returns {number}
 */
export const getProductIndex = (id, ids) => (
  (!Array.isArray(ids) ? getIds() : ids).indexOf(id)
);

/**
 * Get next product's ID.
 *
 * @param {string} id
 * @returns {string} Next product's ID
 */
export const getNextProductId = (id) => {
  const ids = getIds();
  const index = ids.indexOf(id);

  return index >= 0 ? ids[index + 1] : undefined;
};

/**
 * Get previous product's ID.
 *
 * @param {string} id
 * @returns {string} Previous product's ID
 */
export const getPreviousProductId = (id) => {
  const ids = getIds();
  const index = ids.indexOf(id);

  return index >= 0 ? ids[index - 1] : undefined;
};

export const getProduct = (id) => {
  const product = productsService[PRODUCTS].get(id);

  if (!product) {
    return product;
  }

  // TODO: Account for bad id/key index lookups?
  const ids = getIds();
  const idKeyIndex = getProductIndex(id, ids);

  return Object.assign(
    {
      nextProductId: ids[idKeyIndex + 1],
      previousProductId: ids[idKeyIndex - 1],
    },
    product
  );
};

export const getProducts = () => Array.from(productsService[PRODUCTS].values());

export const hasLoadedAllProducts = () => !!(
  productsService[LAST_RESPONSE_META] &&
  productsService[PRODUCTS].size &&
  productsService[LAST_RESPONSE_META].totalProducts <=
    productsService[PRODUCTS].size
);

const SCRIPTS_PATTERN = /<script.*?>.*?<\/script.*?>/gi;

/**
 * Sanitize product values.
 *
 * This removes `<script>...</script>` tags in a product's value to prevent
 * injection attacks when the values are injected into WebViews.
 *
 * @todo Strip `style` and `img` tags to prevent potential phishing/counters
 *
 * @param {Object} product
 * @returns {Object} Sanitized product
 */
export const sanitizeProduct = product => Object.keys(product).reduce(
  (memo, key) => {
    const value = product[key];
    /* eslint-disable no-param-reassign */
    memo[key] = typeof value === 'string' ?
      value.replace(SCRIPTS_PATTERN, '') :
      value;
    /* eslint-enable no-param-reassign */
    return memo;
  },
  {}
);

/**
 * Load the next page of products.
 *
 * @returns {Promise<Array,Error>}
 */
export const loadProducts = () => {
  if (productsService[CURRENT_REQUEST]) {
    return productsService[CURRENT_REQUEST];
  } else if (hasLoadedAllProducts()) {
    return Promise.resolve([]);
  }

  productsService[CURRENT_REQUEST] = fetchProducts(
    productsService[LAST_REQUEST_PAGE] + 1,
    30
  )
    .then(({ pageNumber, products, totalProducts }) => {
      productsService[LAST_RESPONSE_META] = { pageNumber, totalProducts };
      productsService[CURRENT_REQUEST] = null;
      productsService[LAST_REQUEST_PAGE] += 1;

      products.forEach((product) => {
        // TODO: Optimize by only sanitizing loaded products' attributes
        productsService[PRODUCTS].set(
          product.productId,
          sanitizeProduct(product)
        );
      });

      return products;
    });

  return productsService[CURRENT_REQUEST];
};

<commit_msg>Fix undefined `Symbol` error on Android.<commit_after>import fetchProducts from './fetch-products';

export const CURRENT_REQUEST = 'CURRENT_REQUEST';
export const LAST_REQUEST_PAGE = 'LAST_REQUEST_PAGE';
export const LAST_RESPONSE_META = 'LAST_RESPONSE_META';
export const PRODUCTS = 'PRODUCTS';

const productsService = {
  [CURRENT_REQUEST]: null,
  [LAST_REQUEST_PAGE]: 0,
  [LAST_RESPONSE_META]: null,
  [PRODUCTS]: new Map(),
};

export default productsService;

/**
 * Get products' ordered IDs.
 *
 * @returns {string[]}
 */
export const getIds = () => Array.from(productsService[PRODUCTS].keys());

/**
 * Get product's index by ID.
 *
 * @param {string} id
 * @param {string[]} [ids] Collection of ordered IDs to iterate through.
 * Defaults to the products map's IDs.
 * @returns {number}
 */
export const getProductIndex = (id, ids) => (
  (!Array.isArray(ids) ? getIds() : ids).indexOf(id)
);

/**
 * Get next product's ID.
 *
 * @param {string} id
 * @returns {string} Next product's ID
 */
export const getNextProductId = (id) => {
  const ids = getIds();
  const index = ids.indexOf(id);

  return index >= 0 ? ids[index + 1] : undefined;
};

/**
 * Get previous product's ID.
 *
 * @param {string} id
 * @returns {string} Previous product's ID
 */
export const getPreviousProductId = (id) => {
  const ids = getIds();
  const index = ids.indexOf(id);

  return index >= 0 ? ids[index - 1] : undefined;
};

export const getProduct = (id) => {
  const product = productsService[PRODUCTS].get(id);

  if (!product) {
    return product;
  }

  // TODO: Account for bad id/key index lookups?
  const ids = getIds();
  const idKeyIndex = getProductIndex(id, ids);

  return Object.assign(
    {
      nextProductId: ids[idKeyIndex + 1],
      previousProductId: ids[idKeyIndex - 1],
    },
    product
  );
};

export const getProducts = () => Array.from(productsService[PRODUCTS].values());

export const hasLoadedAllProducts = () => !!(
  productsService[LAST_RESPONSE_META] &&
  productsService[PRODUCTS].size &&
  productsService[LAST_RESPONSE_META].totalProducts <=
    productsService[PRODUCTS].size
);

const SCRIPTS_PATTERN = /<script.*?>.*?<\/script.*?>/gi;

/**
 * Sanitize product values.
 *
 * This removes `<script>...</script>` tags in a product's value to prevent
 * injection attacks when the values are injected into WebViews.
 *
 * @todo Strip `style` and `img` tags to prevent potential phishing/counters
 *
 * @param {Object} product
 * @returns {Object} Sanitized product
 */
export const sanitizeProduct = product => Object.keys(product).reduce(
  (memo, key) => {
    const value = product[key];
    /* eslint-disable no-param-reassign */
    memo[key] = typeof value === 'string' ?
      value.replace(SCRIPTS_PATTERN, '') :
      value;
    /* eslint-enable no-param-reassign */
    return memo;
  },
  {}
);

/**
 * Load the next page of products.
 *
 * @returns {Promise<Array,Error>}
 */
export const loadProducts = () => {
  if (productsService[CURRENT_REQUEST]) {
    return productsService[CURRENT_REQUEST];
  } else if (hasLoadedAllProducts()) {
    return Promise.resolve([]);
  }

  productsService[CURRENT_REQUEST] = fetchProducts(
    productsService[LAST_REQUEST_PAGE] + 1,
    30
  )
    .then(({ pageNumber, products, totalProducts }) => {
      productsService[LAST_RESPONSE_META] = { pageNumber, totalProducts };
      productsService[CURRENT_REQUEST] = null;
      productsService[LAST_REQUEST_PAGE] += 1;

      products.forEach((product) => {
        // TODO: Optimize by only sanitizing loaded products' attributes
        productsService[PRODUCTS].set(
          product.productId,
          sanitizeProduct(product)
        );
      });

      return products;
    });

  return productsService[CURRENT_REQUEST];
};

<|endoftext|>


<commit_before>'use strict';

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var winston = require('winston');
var morgan = require('morgan');
var fs = require('fs');

/** Setup loggers **/

var logsDir = './logs',
  accessDir = logsDir + '/access',
  errorsDir = logsDir + '/errors';

if (!fs.existsSync(logsDir)) {

  fs.mkdirSync(logsDir);
  fs.mkdirSync(accessDir);
  fs.mkdirSync(errorsDir);

}
if (!fs.existsSync(accessDir)) {

  fs.mkdirSync(accessDir);

}
if (!fs.existsSync(errorsDir)) {

  fs.mkdirSync(errorsDir);

}

require('winston-daily-rotate-file');
winston.loggers.add('access', {
  dailyRotateFile: {
    level: 'debug',
    filename: 'logs/access/.log',
    datePattern: 'yyyy-MM',
    prepend: true,
    timestamp: true
  }
});

winston.loggers.add('console', {
  console: {
    level: 'debug',
    colorize: true,
    timestamp: true,
    handleExceptions: true,
    humanReadableUnhandledException: true
  },
  dailyRotateFile: {
    level: 'debug',
    filename: 'logs/errors/.log',
    datePattern: 'yyyy-MM',
    prepend: true,
    timestamp: true,
    handleExceptions: true,
    humanReadableUnhandledException: true
  }
});

global.logger = winston.loggers.get('console');
let accessLogger = winston.loggers.get('access');

accessLogger.stream = {

  write: function (message) {

    accessLogger.info(message);

  }

};

require('dotenv').config();

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'twig');

// uncomment after placing your favicon in /public
// app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));

/** We use morgan as express middleware to link winston and express **/
app.use(morgan('combined', { stream: accessLogger.stream }));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use('/static', express.static(path.join(__dirname, 'public')));

/**
 * Garage
 */
var garage = require('./routes/garage/garage');

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

/**
 * Yard
 */
var index = require('./routes/yard/index');
var login = require('./routes/yard/auth/login');
var logout = require('./routes/yard/auth/logout');
var join = require('./routes/yard/auth/join');
var websites = require('./routes/yard/websites');

app.use('/', index);
app.use('/websites', websites);
app.use('/login', login);
app.use('/logout', logout);
app.use('/join', join);

/**
 * Catcher
 */
var catcher = require('./routes/catcher/catcher');

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

// catch 404 and forward to error handler
app.use(function (req, res, next) {

  var err = new Error('Not Found');

  err.status = 404;
  next(err);

});

// error handler
app.use(function (err, req, res, next) {

  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = process.env.ENVIRONMENT === 'DEVELOPMENT' ? err : {};

  // render the error page
  res.status(err.status || 500);

  let errorPageData;

  if (err.status === 404) {

    errorPageData = {
      title: '404',
      message : 'Page not found'
    };

  } else {

    errorPageData = {
      title: ':(',
      message : 'Sorry, dude. Looks like some of our services is busy.'
    };

  }

  res.render('yard/errors/error', errorPageData);

});

module.exports = app;
<commit_msg>Comments<commit_after>'use strict';

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

require('dotenv').config();

/** * Loggers ***/
/* Main logger */
var winston = require('winston');

/* Allow rotate log files by date */
require('winston-daily-rotate-file');

/* Express middleware logger */
var morgan = require('morgan');
/** */

/* File system */
var fs = require('fs');

/** Setup loggers **/

var logsDir = './logs',
  accessDir = logsDir + '/access',
  errorsDir = logsDir + '/errors';

if (!fs.existsSync(logsDir)) {

  fs.mkdirSync(logsDir);
  fs.mkdirSync(accessDir);
  fs.mkdirSync(errorsDir);

}
if (!fs.existsSync(accessDir)) {

  fs.mkdirSync(accessDir);

}
if (!fs.existsSync(errorsDir)) {

  fs.mkdirSync(errorsDir);

}

/* HTTP requests logger */
winston.loggers.add('access', {
  dailyRotateFile: {
    level: 'debug',
    filename: 'logs/access/.log',
    datePattern: 'yyyy-MM',
    prepend: true,
    timestamp: true
  }
});

/* Global logger */
winston.loggers.add('console', {
  console: {
    level: 'debug',
    colorize: true,
    timestamp: true,
    handleExceptions: true,
    humanReadableUnhandledException: true
  },
  dailyRotateFile: {
    level: 'debug',
    filename: 'logs/errors/.log',
    datePattern: 'yyyy-MM',
    prepend: true,
    timestamp: true,
    handleExceptions: true,
    humanReadableUnhandledException: true
  }
});

/**
  * @usage logger.log(level, message)
  *        logger[level](message)
  */
global.logger = winston.loggers.get('console');

let accessLogger = winston.loggers.get('access');

accessLogger.stream = {

  write: function (message) {

    accessLogger.info(message);

  }

};

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'twig');

// uncomment after placing your favicon in /public
// app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));

/** We use morgan as express middleware to link winston and express **/
app.use(morgan('combined', { stream: accessLogger.stream }));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use('/static', express.static(path.join(__dirname, 'public')));

/**
 * Garage
 */
var garage = require('./routes/garage/garage');

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

/**
 * Yard
 */
var index = require('./routes/yard/index');
var login = require('./routes/yard/auth/login');
var logout = require('./routes/yard/auth/logout');
var join = require('./routes/yard/auth/join');
var websites = require('./routes/yard/websites');

app.use('/', index);
app.use('/websites', websites);
app.use('/login', login);
app.use('/logout', logout);
app.use('/join', join);

/**
 * Catcher
 */
var catcher = require('./routes/catcher/catcher');

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

// catch 404 and forward to error handler
app.use(function (req, res, next) {

  var err = new Error('Not Found');

  err.status = 404;
  next(err);

});

// error handler
app.use(function (err, req, res, next) {

  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = process.env.ENVIRONMENT === 'DEVELOPMENT' ? err : {};

  // render the error page
  res.status(err.status || 500);

  let errorPageData;

  if (err.status === 404) {

    errorPageData = {
      title: '404',
      message : 'Page not found'
    };

  } else {

    errorPageData = {
      title: ':(',
      message : 'Sorry, dude. Looks like some of our services is busy.'
    };

  }

  res.render('yard/errors/error', errorPageData);

});

module.exports = app;
<|endoftext|>


<commit_before>'use strict'
var Web3 = require('web3')
var EventManager = require('../eventManager')
var EthJSVM = require('ethereumjs-vm')
var ethUtil = require('ethereumjs-util')
var StateManager = require('ethereumjs-vm/lib/stateManager')
var Web3VMProvider = require('../web3Provider/web3VmProvider')

var rlp = ethUtil.rlp

var injectedProvider

var web3
if (typeof window !== 'undefined' && typeof window.web3 !== 'undefined') {
  injectedProvider = window.web3.currentProvider
  web3 = new Web3(injectedProvider)
} else {
  web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'))
}

var blankWeb3 = new Web3()

/*
  extend vm state manager and instanciate VM
*/

class StateManagerCommonStorageDump extends StateManager {
  constructor (arg) {
    super(arg)
    this.keyHashes = {}
  }

  putContractStorage (address, key, value, cb) {
    this.keyHashes[ethUtil.sha3(key).toString('hex')] = ethUtil.bufferToHex(key)
    super.putContractStorage(address, key, value, cb)
  }

  dumpStorage (address, cb) {
    var self = this
    this._getStorageTrie(address, function (err, trie) {
      if (err) {
        return cb(err)
      }
      var storage = {}
      var stream = trie.createReadStream()
      stream.on('data', function (val) {
        var value = rlp.decode(val.value)
        storage['0x' + val.key.toString('hex')] = {
          key: self.keyHashes[val.key.toString('hex')],
          value: '0x' + value.toString('hex')
        }
      })
      stream.on('end', function () {
        cb(storage)
      })
    })
  }
}

var stateManager = new StateManagerCommonStorageDump({})
var vm = new EthJSVM({
  enableHomestead: true,
  activatePrecompiles: true
})

// FIXME: move state manager in EthJSVM ctr
vm.stateManager = stateManager
vm.blockchain = stateManager.blockchain
vm.trie = stateManager.trie
vm.stateManager.checkpoint()

var web3VM = new Web3VMProvider()
web3VM.setVM(vm)

var mainNetGenesisHash = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3'

/*
  trigger contextChanged, web3EndpointChanged
*/
function ExecutionContext () {
  var self = this
  this.event = new EventManager()

  var executionContext = null

  this.blockGasLimitDefault = 4300000
  this.blockGasLimit = this.blockGasLimitDefault

  this.init = function (config) {
    if (config.get('settings/always-use-vm')) {
      executionContext = 'vm'
    } else {
      executionContext = injectedProvider ? 'injected' : 'vm'
    }
  }

  this.getProvider = function () {
    return executionContext
  }

  this.isVM = function () {
    return executionContext === 'vm'
  }

  this.web3 = function () {
    return this.isVM() ? web3VM : web3
  }

  this.detectNetwork = function (callback) {
    if (this.isVM()) {
      callback(null, { id: '-', name: 'VM' })
    } else {
      this.web3().version.getNetwork((err, id) => {
        var name = null
        if (err) name = 'Unknown'
        // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
        else if (id === '1') name = 'Main'
        else if (id === '2') name = 'Morden (deprecated)'
        else if (id === '3') name = 'Ropsten'
        else if (id === '4') name = 'Rinkeby'
        else if (id === '42') name = 'Kovan'
        else name = 'Custom'

        if (id === '1') {
          this.web3().eth.getBlock(0, (error, block) => {
            if (error) console.log('cant query first block')
            if (block && block.hash !== mainNetGenesisHash) name = 'Custom'
            callback(err, { id, name })
          })
        } else {
          callback(err, { id, name })
        }
      })
    }
  }

  this.internalWeb3 = function () {
    return web3
  }

  this.blankWeb3 = function () {
    return blankWeb3
  }

  this.vm = function () {
    return vm
  }

  this.setContext = function (context, endPointUrl, confirmCb, infoCb) {
    executionContext = context
    this.executionContextChange(context, endPointUrl, confirmCb, infoCb)
  }

  this.executionContextChange = function (context, endPointUrl, confirmCb, infoCb, cb) {
    if (!cb) cb = () => {}

    if (context === 'vm') {
      executionContext = context
      vm.stateManager.revert(function () {
        vm.stateManager.checkpoint()
      })
      self.event.trigger('contextChanged', ['vm'])
      return cb()
    }

    if (context === 'injected') {
      if (injectedProvider === undefined) {
        var alertMsg = 'No injected Web3 provider found. '
        alertMsg += 'Make sure your provider (e.g. MetaMask) is active and running '
        alertMsg += '(when recently activated you may have to reload the page).'
        infoCb(alertMsg)
        return cb()
      } else {
        executionContext = context
        web3.setProvider(injectedProvider)
        self.event.trigger('contextChanged', ['injected'])
        return cb()
      }
    }

    if (context === 'web3') {
      confirmCb(cb)
    }
  }

  this.currentblockGasLimit = function () {
    return this.blockGasLimit
  }

  this.stopListenOnLastBlock = function () {
    if (this.listenOnLastBlockId) clearInterval(this.listenOnLastBlockId)
    this.listenOnLastBlockId = null
  }

  this.listenOnLastBlock = function () {
    this.listenOnLastBlockId = setInterval(() => {
      if (this.getProvider() !== 'vm') {
        web3.eth.getBlock('latest', (err, block) => {
          if (!err) {
            // we can't use the blockGasLimit cause the next blocks could have a lower limit : https://github.com/ethereum/remix/issues/506
            this.blockGasLimit = (block && block.gasLimit) ? Math.floor(block.gasLimit - (5 * block.gasLimit) / 1024) : this.blockGasLimitDefault
          } else {
            this.blockGasLimit = this.blockGasLimitDefault
          }
        }, 15000)
      }
    })
  }

  // TODO: not used here anymore and needs to be moved
  function setProviderFromEndpoint (endpoint, context, cb) {
    var oldProvider = web3.currentProvider

    if (endpoint === 'ipc') {
      web3.setProvider(new web3.providers.IpcProvider())
    } else {
      web3.setProvider(new web3.providers.HttpProvider(endpoint))
    }
    if (web3.isConnected()) {
      executionContext = context
      self.event.trigger('contextChanged', ['web3'])
      self.event.trigger('web3EndpointChanged')
      cb()
    } else {
      web3.setProvider(oldProvider)
      var alertMsg = 'Not possible to connect to the Web3 provider. '
      alertMsg += 'Make sure the provider is running and a connection is open (via IPC or RPC).'
      cb(alertMsg)
    }
  }
  this.setProviderFromEndpoint = setProviderFromEndpoint
}

module.exports = new ExecutionContext()
<commit_msg>fix getBlock/SsetInterval && update block gas limit when provider change<commit_after>'use strict'
var Web3 = require('web3')
var EventManager = require('../eventManager')
var EthJSVM = require('ethereumjs-vm')
var ethUtil = require('ethereumjs-util')
var StateManager = require('ethereumjs-vm/lib/stateManager')
var Web3VMProvider = require('../web3Provider/web3VmProvider')

var rlp = ethUtil.rlp

var injectedProvider

var web3
if (typeof window !== 'undefined' && typeof window.web3 !== 'undefined') {
  injectedProvider = window.web3.currentProvider
  web3 = new Web3(injectedProvider)
} else {
  web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'))
}

var blankWeb3 = new Web3()

/*
  extend vm state manager and instanciate VM
*/

class StateManagerCommonStorageDump extends StateManager {
  constructor (arg) {
    super(arg)
    this.keyHashes = {}
  }

  putContractStorage (address, key, value, cb) {
    this.keyHashes[ethUtil.sha3(key).toString('hex')] = ethUtil.bufferToHex(key)
    super.putContractStorage(address, key, value, cb)
  }

  dumpStorage (address, cb) {
    var self = this
    this._getStorageTrie(address, function (err, trie) {
      if (err) {
        return cb(err)
      }
      var storage = {}
      var stream = trie.createReadStream()
      stream.on('data', function (val) {
        var value = rlp.decode(val.value)
        storage['0x' + val.key.toString('hex')] = {
          key: self.keyHashes[val.key.toString('hex')],
          value: '0x' + value.toString('hex')
        }
      })
      stream.on('end', function () {
        cb(storage)
      })
    })
  }
}

var stateManager = new StateManagerCommonStorageDump({})
var vm = new EthJSVM({
  enableHomestead: true,
  activatePrecompiles: true
})

// FIXME: move state manager in EthJSVM ctr
vm.stateManager = stateManager
vm.blockchain = stateManager.blockchain
vm.trie = stateManager.trie
vm.stateManager.checkpoint()

var web3VM = new Web3VMProvider()
web3VM.setVM(vm)

var mainNetGenesisHash = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3'

/*
  trigger contextChanged, web3EndpointChanged
*/
function ExecutionContext () {
  var self = this
  this.event = new EventManager()

  var executionContext = null

  this.blockGasLimitDefault = 4300000
  this.blockGasLimit = this.blockGasLimitDefault

  this.init = function (config) {
    if (config.get('settings/always-use-vm')) {
      executionContext = 'vm'
    } else {
      executionContext = injectedProvider ? 'injected' : 'vm'
    }
  }

  this.getProvider = function () {
    return executionContext
  }

  this.isVM = function () {
    return executionContext === 'vm'
  }

  this.web3 = function () {
    return this.isVM() ? web3VM : web3
  }

  this.detectNetwork = function (callback) {
    if (this.isVM()) {
      callback(null, { id: '-', name: 'VM' })
    } else {
      this.web3().version.getNetwork((err, id) => {
        var name = null
        if (err) name = 'Unknown'
        // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
        else if (id === '1') name = 'Main'
        else if (id === '2') name = 'Morden (deprecated)'
        else if (id === '3') name = 'Ropsten'
        else if (id === '4') name = 'Rinkeby'
        else if (id === '42') name = 'Kovan'
        else name = 'Custom'

        if (id === '1') {
          this.web3().eth.getBlock(0, (error, block) => {
            if (error) console.log('cant query first block')
            if (block && block.hash !== mainNetGenesisHash) name = 'Custom'
            callback(err, { id, name })
          })
        } else {
          callback(err, { id, name })
        }
      })
    }
  }

  this.internalWeb3 = function () {
    return web3
  }

  this.blankWeb3 = function () {
    return blankWeb3
  }

  this.vm = function () {
    return vm
  }

  this.setContext = function (context, endPointUrl, confirmCb, infoCb) {
    executionContext = context
    this.executionContextChange(context, endPointUrl, confirmCb, infoCb)
  }

  this.executionContextChange = function (context, endPointUrl, confirmCb, infoCb, cb) {
    if (!cb) cb = () => {}

    if (context === 'vm') {
      executionContext = context
      vm.stateManager.revert(function () {
        vm.stateManager.checkpoint()
      })
      self.event.trigger('contextChanged', ['vm'])
      return cb()
    }

    if (context === 'injected') {
      if (injectedProvider === undefined) {
        var alertMsg = 'No injected Web3 provider found. '
        alertMsg += 'Make sure your provider (e.g. MetaMask) is active and running '
        alertMsg += '(when recently activated you may have to reload the page).'
        infoCb(alertMsg)
        return cb()
      } else {
        executionContext = context
        web3.setProvider(injectedProvider)
        self._updateBlockGasLimit()
        self.event.trigger('contextChanged', ['injected'])
        return cb()
      }
    }

    if (context === 'web3') {
      confirmCb(cb)
    }
  }

  this.currentblockGasLimit = function () {
    return this.blockGasLimit
  }

  this.stopListenOnLastBlock = function () {
    if (this.listenOnLastBlockId) clearInterval(this.listenOnLastBlockId)
    this.listenOnLastBlockId = null
  }

  this._updateBlockGasLimit = function () {
    if (this.getProvider() !== 'vm') {
      web3.eth.getBlock('latest', (err, block) => {
        if (!err) {
          // we can't use the blockGasLimit cause the next blocks could have a lower limit : https://github.com/ethereum/remix/issues/506
          this.blockGasLimit = (block && block.gasLimit) ? Math.floor(block.gasLimit - (5 * block.gasLimit) / 1024) : this.blockGasLimitDefault
        } else {
          this.blockGasLimit = this.blockGasLimitDefault
        }
      })
    }
  }

  this.listenOnLastBlock = function () {
    this.listenOnLastBlockId = setInterval(() => {
      this._updateBlockGasLimit()
    }, 15000)
  }

  // TODO: not used here anymore and needs to be moved
  function setProviderFromEndpoint (endpoint, context, cb) {
    var oldProvider = web3.currentProvider

    if (endpoint === 'ipc') {
      web3.setProvider(new web3.providers.IpcProvider())
    } else {
      web3.setProvider(new web3.providers.HttpProvider(endpoint))
    }
    if (web3.isConnected()) {
      executionContext = context
      self._updateBlockGasLimit()
      self.event.trigger('contextChanged', ['web3'])
      self.event.trigger('web3EndpointChanged')
      cb()
    } else {
      web3.setProvider(oldProvider)
      var alertMsg = 'Not possible to connect to the Web3 provider. '
      alertMsg += 'Make sure the provider is running and a connection is open (via IPC or RPC).'
      cb(alertMsg)
    }
  }
  this.setProviderFromEndpoint = setProviderFromEndpoint
}

module.exports = new ExecutionContext()
<|endoftext|>


<commit_before>/**
 * Created by sokolski adrien on 17/03/2017.
 */

let instance = null;

class Deadpool {
  constructor() {

    if (!instance) {
      instance = this;
      this.energyLevel = 0;
      this.helpTransform = 5;
      this.poneyFarm = [];
      this.poneyNumber = 0;
      this.unicornNumber = 0;
    }
    setInterval(() => {
      this.poneyNumber = this.poneyFarm.length;
      if (this.poneyNumber > 1) {
        this.feeedUnicorn(Math.floor(Math.random() * this.poneyNumber));

      }
    }, 2000);
    setInterval(() => {
      if (this.energyLevel > 20) {
        console.log('Deadpool ' + 'do something Deadpool');
        this;
        energyLevel -= 20;
      }
    }, 1000 * this.helpTransform);

    return
    instance;
  }

  transformToUnicorn() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        this.countNumberUnicorn()
          .then(() => this.transformToUnicorn2())
          .then(() => resolve())
          .catch(() => reject());
      });
    }, 500);
  }

  countNumberUnicorn() {
    return new Promise(resolve => {
      this.x = 0;
      this.poneyNumber = this.poneyFarm.length;
      for (let i = 0; i < this.poneyNumber; i++) {
        if (this.poneyFarm[i].isUnicorn) {
          this.x++;
        }
      }
      this.unicornNumber = this.x;
      resolve();
    });
  }

  transformToUnicorn2() {
  return new Promise((resolve, reject)=>{
    if(Math.random()>0.1*this.unicornNumber){
      resolve();
    }else{
      reject();
    }
  });
  }

  feedUnicorn() {
    setInterval(() => {
  if (this.poneyFarm[i].isUnicorn){
    this.poneyFarm[i].deadpoolHungry()
      .then(()=>{
      this.energyLevel += 5;
      })
      .then(()=> console.log('Deadpool mange'))
      .catch(()=> console.log('Deadpool mange pas'));
  }
    },500* this.helpTransform);
  }
}
module.export = {Deadpool};<commit_msg>Delete deadpool.js<commit_after><|endoftext|>


<commit_before>/* global $, _, arealist:true, beforeSpace, JAM, phiQ, setup */

arealist = function(){ /* jshint indent:false */

$('#content').html([
'
',
   'Welcome, ',
      setup.UserName,
   '!',
'

',
   '
',
      'Search by areatag:',
      '<input type="text" id="searchAreatag" style="flex-grow: 1;">',
   '
',
'

'
].join(''));
var echoNames = setup.areas.group('EchoArea').names();
if( echoNames.length > 0 ){
   $('#content').append(
   '
' +
   '

' +
      'Area title	' +
      'Msgs	' +
      'New	' +
      'Echotag	' +
   '

');
   echoNames = _(echoNames).sortBy(function(value){ // stable sort
      return value.toLowerCase();
   });
   var currAreaSep = 0;
   var $currTBody = $('

').appendTo('#areaList');
   _(echoNames).each(function(echoName){
      while(
         currAreaSep < setup.areaSeparators.length &&
         setup.areaSeparators[currAreaSep].sepName.toLowerCase() <
         echoName.toLowerCase()
      ){
         $currTBody = $('

').appendTo('#areaList');
         $('
' +
            _.escapeHTML(setup.areaSeparators[currAreaSep].sepDesc) +
         '
').appendTo($currTBody);
         currAreaSep++;
      }
      var arrDesc = /-d "([^"]+?)"/.exec(
         setup.areas.group('EchoArea').first(echoName)
      );
      var echoDesc;
      if( arrDesc === null ){
         echoDesc = echoName;
      } else {
         echoDesc = arrDesc[1];
      }
      $('
' +
         ''+_.escapeHTML(echoDesc)+'	' +
         '	' +
         '	' +
         ''+_.escapeHTML(echoName)+'	' +
      '
').appendTo($currTBody).data({
         'echopath': beforeSpace(
            setup.areas.group('EchoArea').first(echoName)
         )
      });
   });
   $('#areaList .msgnum').each(function(){
      var $cell = $(this);
      phiQ.push(function(){
         var echobase = JAM( $cell.closest('tr').data('echopath') );
         echobase.readJDX(function(err){
            if( err ){
               $cell.html('FAIL');
               phiQ.singleNext();
               return;
            }
            $cell.html( echobase.size() );
            phiQ.singleNext();
         });
      });
   });
   $('#areaList .msgnew').each(function(){
      var $cell = $(this);
      phiQ.push(function(){
         var echobase = JAM( $cell.closest('tr').data('echopath') );
         echobase.readJLR(function(err){
            if( err ){
               $cell.html('FAIL');
               phiQ.singleNext();
               return;
            }
            if( echobase.lastreads.length !== 1 ){
               $cell.html('MUD');
               phiQ.singleNext();
               return;
            }
            echobase.readJDX(function(err){
               if( err ){
                  $cell.html('FAIL');
                  phiQ.singleNext();
                  return;
               }
               echobase.readFixedHeaderInfoStruct(function(err, data){
                  if( err ){
                     $cell.html('FAIL');
                     phiQ.singleNext();
                     return;
                  }
                  var nextIDX = echobase.size() - 1;
                  while( nextIDX > 0 ){
                     if(
                        echobase.indexStructure[nextIDX].MessageNum0 +
                        data.basemsgnum ===
                        echobase.lastreads[0].LastRead
                     ){
                        $cell.html(echobase.size() - 1 - nextIDX);
                        phiQ.singleNext();
                        return;
                     } else nextIDX--;
                  }
                  $cell.html('FAIL');
                  phiQ.singleNext();
                  return;
               });
            });
         });
      });
   });
   phiQ.singleStep();
}

};<commit_msg>make echoName available in addition to _.escapeHTML(echoName)<commit_after>/* global $, _, arealist:true, beforeSpace, JAM, phiQ, setup */

arealist = function(){ /* jshint indent:false */

$('#content').html([
'
',
   'Welcome, ',
      setup.UserName,
   '!',
'

',
   '
',
      'Search by areatag:',
      '<input type="text" id="searchAreatag" style="flex-grow: 1;">',
   '
',
'

'
].join(''));
var echoNames = setup.areas.group('EchoArea').names();
if( echoNames.length > 0 ){
   $('#content').append(
   '
' +
   '

' +
      'Area title	' +
      'Msgs	' +
      'New	' +
      'Echotag	' +
   '

');
   echoNames = _(echoNames).sortBy(function(value){ // stable sort
      return value.toLowerCase();
   });
   var currAreaSep = 0;
   var $currTBody = $('

').appendTo('#areaList');
   _(echoNames).each(function(echoName){
      while(
         currAreaSep < setup.areaSeparators.length &&
         setup.areaSeparators[currAreaSep].sepName.toLowerCase() <
         echoName.toLowerCase()
      ){
         $currTBody = $('

').appendTo('#areaList');
         $('
' +
            _.escapeHTML(setup.areaSeparators[currAreaSep].sepDesc) +
         '
').appendTo($currTBody);
         currAreaSep++;
      }
      var arrDesc = /-d "([^"]+?)"/.exec(
         setup.areas.group('EchoArea').first(echoName)
      );
      var echoDesc;
      if( arrDesc === null ){
         echoDesc = echoName;
      } else {
         echoDesc = arrDesc[1];
      }
      $('
' +
         ''+_.escapeHTML(echoDesc)+'	' +
         '	' +
         '	' +
         ''+_.escapeHTML(echoName)+'	' +
      '
').appendTo($currTBody).data({
         'echotag': echoName,
         'echopath': beforeSpace(
            setup.areas.group('EchoArea').first(echoName)
         )
      });
   });
   $('#areaList .msgnum').each(function(){
      var $cell = $(this);
      phiQ.push(function(){
         var echobase = JAM( $cell.closest('tr').data('echopath') );
         echobase.readJDX(function(err){
            if( err ){
               $cell.html('FAIL');
               phiQ.singleNext();
               return;
            }
            $cell.html( echobase.size() );
            phiQ.singleNext();
         });
      });
   });
   $('#areaList .msgnew').each(function(){
      var $cell = $(this);
      phiQ.push(function(){
         var echobase = JAM( $cell.closest('tr').data('echopath') );
         echobase.readJLR(function(err){
            if( err ){
               $cell.html('FAIL');
               phiQ.singleNext();
               return;
            }
            if( echobase.lastreads.length !== 1 ){
               $cell.html('MUD');
               phiQ.singleNext();
               return;
            }
            echobase.readJDX(function(err){
               if( err ){
                  $cell.html('FAIL');
                  phiQ.singleNext();
                  return;
               }
               echobase.readFixedHeaderInfoStruct(function(err, data){
                  if( err ){
                     $cell.html('FAIL');
                     phiQ.singleNext();
                     return;
                  }
                  var nextIDX = echobase.size() - 1;
                  while( nextIDX > 0 ){
                     if(
                        echobase.indexStructure[nextIDX].MessageNum0 +
                        data.basemsgnum ===
                        echobase.lastreads[0].LastRead
                     ){
                        $cell.html(echobase.size() - 1 - nextIDX);
                        phiQ.singleNext();
                        return;
                     } else nextIDX--;
                  }
                  $cell.html('FAIL');
                  phiQ.singleNext();
                  return;
               });
            });
         });
      });
   });
   phiQ.singleStep();
}

};<|endoftext|>


<commit_before>// Create a new .js file with the appropriate methods to help modify your source data to help render it to the DOM:
// Use good Object Oriented code: Create a constructor function for projects or source data.
// Leave as little in the window (global) namespace as possible: attach functions to objects, etc.
// Use jQuery to clone the example markup for each project, as you add additional content.
// Your "Project" prototype should have a .toHtml() function that adds new data to the DOM.

var blogsArr = [];

// constructor that will take in the blogEntries object array
function Blog (arr) {
  this.title = arr.title;
  this.date = arr.date;
  this.tag = arr.tag;
  this.link = arr.link;
  this.body = arr.body;
}

Blog.prototype.toHtml = function() {
  // find the beginning of the DOM node and all its children where you will fill in the html
  var $newBlog = $('article.blog-template').clone();
  // change the attribute 'data-tag' to match the passed-in object
  $newBlog.attr('data-tag', this.tag);
  // find() the elements in the clone and fill in the rest of the current template clone with properties from this particular Blog instance
  $newBlog.find('.title').html(this.title);
  $newBlog.find('a').html(this.date);
  $newBlog.find('a').attr('href', this.link);
  $newBlog.find('.blog-body').html(this.body);

  // remove the class from the clone which is saying in css to not display
  $newBlog.removeAttr('class');

  return $newBlog;
};

// sorts blog entries by date but the date value needs yyyy-mm-dd notation
// blogEntries.sort(function(curElem, nextElem) {
//   return (new Date(nextElem.publishedOn)) - (new Date(curElem.publishedOn));
// });

blogEntries.forEach(function(ele) {
  blogsArr.push(new Blog(ele));
});

blogsArr.forEach(function(a) {
  $('#blog-content').append(a.toHtml());
});
<commit_msg>added comments<commit_after>// Create a new .js file with the appropriate methods to help modify your source data to help render it to the DOM:
// Use good Object Oriented code: Create a constructor function for projects or source data.
// Leave as little in the window (global) namespace as possible: attach functions to objects, etc.
// Use jQuery to clone the example markup for each project, as you add additional content.
// Your "Project" prototype should have a .toHtml() function that adds new data to the DOM.

var blogsArr = [];

// constructor that will take in the blogEntries object array
function Blog (arr) {
  this.title = arr.title;
  this.date = arr.date;
  this.tag = arr.tag;
  this.link = arr.link;
  this.body = arr.body;
}

Blog.prototype.toHtml = function() {
  // find the beginning of the DOM node and all its children where you will fill in the html
  var $newBlog = $('article.blog-template').clone();
  // change the attribute 'data-tag' to match the passed-in object
  $newBlog.attr('data-tag', this.tag);
  // find() the elements in the clone and fill in the rest of the current template clone with properties from this particular Blog instance
  $newBlog.find('.title').html(this.title);
  $newBlog.find('a').html(this.date);
  $newBlog.find('a').attr('href', this.link);
  $newBlog.find('.blog-body').html(this.body);

  // remove the class from the clone which is saying in css to not display
  $newBlog.removeAttr('class');

  return $newBlog;
};

// sorts blog entries by date but the date value needs yyyy-mm-dd notation
// blogEntries.sort(function(curElem, nextElem) {
//   return (new Date(nextElem.publishedOn)) - (new Date(curElem.publishedOn));
// });

// for each element of the blogEntries object array, push a new blog object into the var blogsArr. The new blog object has the needed toHtml function
blogEntries.forEach(function(ele) {
  blogsArr.push(new Blog(ele));
});

// for each object in the blogsArr, run the toHtml function and append the object to the id'ed section
blogsArr.forEach(function(a) {
  $('#blog-content').append(a.toHtml());
});
<|endoftext|>


<commit_before>/* eslint-disable react/prefer-stateless-function */
import React, { PropTypes } from 'react';
import { View, Text } from 'react-native';
import { Icon } from 'react-native-elements';
import { Actions, Scene } from 'react-native-router-flux';
import Home from '../containers/home/Home';
import AppConfig from '../constants/config';
import AppSizes from '../theme/sizes';
import AppStyles from '../theme/styles';
import AppColors from '../theme/colors';
import Community from '../containers/community/Community';
import UserCenter from '../containers/user-center/UserCenter';
import Discover from '../containers/discover/Discover';
import RoadmapList from '../containers/discover/roadmap-list/RoadmapList';
import RoadmapDetail from '../containers/discover/roadmap-detail/RoadmapDetail';
import ProjectList from '../containers/discover/project-list/ProjectList';
import ToolBoxList from '../containers/discover/toolbox-list/ToolBoxList';
import ArticleList from '../containers/discover/article-list/ArticleList';
import ExamList from '../containers/discover/exam-list/ExamList';
import Solution from '../containers/discover/solution/Solution';
import ThoughtworksBooks from '../containers/discover/thoughtworks-books/ThoughtworksBooks';
import RecommendBooks from '../containers/discover/recommend-books/RecommendBooks';
import RecommendArticles from '../containers/discover/recommend-articles/RecommendArticles';
import TodoLists from '../containers/discover/todo-lists/TodoLists';
import ChapterList from '../containers/discover/chapter-list/ChapterList';
import SkillTree from '../containers/skill-tree/SkillTree';
import SkillDetailView from '../containers/skill-tree/SkillDetailView';
import ComingSoonView from '../containers/ComingSoonView';
import GrowthWebView from '../containers/GrowthWebView';

const navbarPropsTabs = {
  ...AppConfig.navbarProps,
  sceneStyle: {
    ...AppConfig.navbarProps.sceneStyle,
    paddingBottom: AppSizes.tabbarHeight,
  },
};

class TabIcon extends React.Component {
  render() {
    return (
      <View>
        <Icon name={this.props.iconName} type={this.props.iconType} color={this.props.selected ? AppColors.brand.primary : '#767676'} />
        <Text style={{ color: this.props.selected ? AppColors.brand.primary : '#767676' }}>{this.props.title}</Text>
      </View>
    );
  }
}

TabIcon.propTypes = {
  title: PropTypes.string.isRequired,
  selected: PropTypes.bool,
  iconName: PropTypes.string.isRequired,
  iconType: PropTypes.string.isRequired };

TabIcon.defaultProps = { title: 'Home', selected: false, iconName: 'home', iconType: 'ionicon' };

export default Actions.create(
  <Scene key="root" {...AppConfig.navbarProps}>
    <Scene key="tabs" initial={'tabBar'} tabs tabBarIconContainerStyle={AppStyles.tabbar} pressOpacity={0.95}>
      <Scene
        {...navbarPropsTabs}
        key={'home'}
        title={'Growth'}
        iconName={'md-home'}
        iconType={'ionicon'}
        rightTitle={'购买纸质版'}
        onRight={() => Actions.comingSoon()}
        rightButtonTextStyle={AppStyles.navbarTitle}
        icon={TabIcon}
        component={Home}
      />
      <Scene
        {...navbarPropsTabs}
        key={'discover'}
        title={'探索'}
        iconName={'md-compass'}
        iconType={'ionicon'}
        icon={TabIcon}
        component={Discover}
      />
      <Scene
        {...navbarPropsTabs}
        key={'skillTree'}
        title={'技能树'}
        rightTitle={'获取专业版'}
        onRight={() => Actions.comingSoon()}
        rightButtonTextStyle={AppStyles.navbarTitle}
        iconName={'md-egg'}
        iconType={'ionicon'}
        icon={TabIcon}
        component={SkillTree}
      />
      <Scene
        {...navbarPropsTabs}
        key={'community'}
        title={'社区'}
        iconName={'md-people'}
        iconType={'ionicon'}
        icon={TabIcon}
        component={Community}
      />
      <Scene
        {...navbarPropsTabs}
        key={'userCenter'}
        title={'用户中心'}
        iconName={'md-person'}
        iconType={'ionicon'}
        icon={TabIcon}
        component={UserCenter}
      />
    </Scene>

    <Scene
      {...navbarPropsTabs}
      key={'skillDetail'}
      title={'技能'}
      component={SkillDetailView}
    />

    <Scene
      key={'comingSoon'}
      title={'Coming Soon'}
      component={ComingSoonView}
    />

    <Scene
      key={'roadmapList'}
      title={'学习路线'}
      component={RoadmapList}
    />

    <Scene
      key={'roadmapDetail'}
      component={RoadmapDetail}
    />

    <Scene
      key={'projectList'}
      title={'练手项目'}
      component={ProjectList}
    />

    <Scene
      key={'toolBoxList'}
      title={'工具箱'}
      component={ToolBoxList}
    />

    <Scene
      key={'articleList'}
      title={'文章推荐'}
      component={ArticleList}
    />

    <Scene
      key={'examList'}
      title={'技能测验'}
      component={ExamList}
    />
    <Scene
      key={'solution'}
      title={'解决方案'}
      component={Solution}
    />

    <Scene
      key={'thoughtworksBooks'}
      title={'ThoughtWorks读书路线'}
      component={ThoughtworksBooks}
    />

    <Scene
      key={'recommendBooks'}
      title={'推荐书籍'}
      component={RecommendBooks}
    />

    <Scene
      key={'recommendArticles'}
      title={'推荐文章'}
      component={RecommendArticles}
    />

    <Scene
      key={'todoLists'}
      title={'待办事项'}
      component={TodoLists}
    />

    <Scene
      key={'chapterList'}
      title={'ChapterList'}
      component={ChapterList}
    />
    <Scene
      key={'growthWebView'}
      component={GrowthWebView}
    />

  </Scene>,
);
<commit_msg>[T] navigation: add project detail navigation<commit_after>/* eslint-disable react/prefer-stateless-function */
import React, { PropTypes } from 'react';
import { View, Text } from 'react-native';
import { Icon } from 'react-native-elements';
import { Actions, Scene } from 'react-native-router-flux';
import Home from '../containers/home/Home';
import AppConfig from '../constants/config';
import AppSizes from '../theme/sizes';
import AppStyles from '../theme/styles';
import AppColors from '../theme/colors';
import Community from '../containers/community/Community';
import UserCenter from '../containers/user-center/UserCenter';
import Discover from '../containers/discover/Discover';
import RoadmapList from '../containers/discover/roadmap-list/RoadmapList';
import RoadmapDetail from '../containers/discover/roadmap-detail/RoadmapDetail';
import ProjectList from '../containers/discover/project-list/ProjectList';
import ProjectDetail from '../containers/discover/project-detail/ProjectDetail';
import ToolBoxList from '../containers/discover/toolbox-list/ToolBoxList';
import ArticleList from '../containers/discover/article-list/ArticleList';
import ExamList from '../containers/discover/exam-list/ExamList';
import Solution from '../containers/discover/solution/Solution';
import ThoughtworksBooks from '../containers/discover/thoughtworks-books/ThoughtworksBooks';
import RecommendBooks from '../containers/discover/recommend-books/RecommendBooks';
import RecommendArticles from '../containers/discover/recommend-articles/RecommendArticles';
import TodoLists from '../containers/discover/todo-lists/TodoLists';
import ChapterList from '../containers/discover/chapter-list/ChapterList';
import SkillTree from '../containers/skill-tree/SkillTree';
import SkillDetailView from '../containers/skill-tree/SkillDetailView';
import ComingSoonView from '../containers/ComingSoonView';
import GrowthWebView from '../containers/GrowthWebView';

const navbarPropsTabs = {
  ...AppConfig.navbarProps,
  sceneStyle: {
    ...AppConfig.navbarProps.sceneStyle,
    paddingBottom: AppSizes.tabbarHeight,
  },
};

class TabIcon extends React.Component {
  render() {
    return (
      <View>
        <Icon name={this.props.iconName} type={this.props.iconType} color={this.props.selected ? AppColors.brand.primary : '#767676'} />
        <Text style={{ color: this.props.selected ? AppColors.brand.primary : '#767676' }}>{this.props.title}</Text>
      </View>
    );
  }
}

TabIcon.propTypes = {
  title: PropTypes.string.isRequired,
  selected: PropTypes.bool,
  iconName: PropTypes.string.isRequired,
  iconType: PropTypes.string.isRequired };

TabIcon.defaultProps = { title: 'Home', selected: false, iconName: 'home', iconType: 'ionicon' };

export default Actions.create(
  <Scene key="root" {...AppConfig.navbarProps}>
    <Scene key="tabs" initial={'tabBar'} tabs tabBarIconContainerStyle={AppStyles.tabbar} pressOpacity={0.95}>
      <Scene
        {...navbarPropsTabs}
        key={'home'}
        title={'Growth'}
        iconName={'md-home'}
        iconType={'ionicon'}
        rightTitle={'购买纸质版'}
        onRight={() => Actions.comingSoon()}
        rightButtonTextStyle={AppStyles.navbarTitle}
        icon={TabIcon}
        component={Home}
      />
      <Scene
        {...navbarPropsTabs}
        key={'discover'}
        title={'探索'}
        iconName={'md-compass'}
        iconType={'ionicon'}
        icon={TabIcon}
        component={Discover}
      />
      <Scene
        {...navbarPropsTabs}
        key={'skillTree'}
        title={'技能树'}
        rightTitle={'获取专业版'}
        onRight={() => Actions.comingSoon()}
        rightButtonTextStyle={AppStyles.navbarTitle}
        iconName={'md-egg'}
        iconType={'ionicon'}
        icon={TabIcon}
        component={SkillTree}
      />
      <Scene
        {...navbarPropsTabs}
        key={'community'}
        title={'社区'}
        iconName={'md-people'}
        iconType={'ionicon'}
        icon={TabIcon}
        component={Community}
      />
      <Scene
        {...navbarPropsTabs}
        key={'userCenter'}
        title={'用户中心'}
        iconName={'md-person'}
        iconType={'ionicon'}
        icon={TabIcon}
        component={UserCenter}
      />
    </Scene>

    <Scene
      {...navbarPropsTabs}
      key={'skillDetail'}
      title={'技能'}
      component={SkillDetailView}
    />

    <Scene
      key={'comingSoon'}
      title={'Coming Soon'}
      component={ComingSoonView}
    />

    <Scene
      key={'roadmapList'}
      title={'学习路线'}
      component={RoadmapList}
    />

    <Scene
      key={'roadmapDetail'}
      component={RoadmapDetail}
    />

    <Scene
      key={'projectList'}
      title={'练手项目'}
      component={ProjectList}
    />

    <Scene
      key={'projectDetail'}
      component={ProjectDetail}
    />

    <Scene
      key={'toolBoxList'}
      title={'工具箱'}
      component={ToolBoxList}
    />

    <Scene
      key={'articleList'}
      title={'文章推荐'}
      component={ArticleList}
    />

    <Scene
      key={'examList'}
      title={'技能测验'}
      component={ExamList}
    />
    <Scene
      key={'solution'}
      title={'解决方案'}
      component={Solution}
    />

    <Scene
      key={'thoughtworksBooks'}
      title={'ThoughtWorks读书路线'}
      component={ThoughtworksBooks}
    />

    <Scene
      key={'recommendBooks'}
      title={'推荐书籍'}
      component={RecommendBooks}
    />

    <Scene
      key={'recommendArticles'}
      title={'推荐文章'}
      component={RecommendArticles}
    />

    <Scene
      key={'todoLists'}
      title={'待办事项'}
      component={TodoLists}
    />

    <Scene
      key={'chapterList'}
      title={'ChapterList'}
      component={ChapterList}
    />
    <Scene
      key={'growthWebView'}
      component={GrowthWebView}
    />

  </Scene>,
);
<|endoftext|>


<commit_before>// adopted from: <https://github.com/jonschlinkert/omit-value>
// Copyright (c) 2015, Jon Schlinkert. (MIT)

var isObject = require('../lang/isPlainObject')
var isString = require('../lang/isString')
var omit     = require('./omit')
var get      = require('./get')
var set      = require('./set')
var assert   = require('assert')

function omitValue (obj, prop, keys) {
  assert(isObject(obj), 'omitValue expects first arg to be an object.')
  assert(isString(prop), 'omitValue expects prop to be a string')

  if (typeof keys === undefined) return omit(obj, prop)

  var val = get(obj, prop)
  set(obj, prop, omit(val, keys))
  return obj
}

module.exports = omitValue
<commit_msg>fix object/omitValue -- undefined should be a string<commit_after>// adopted from: <https://github.com/jonschlinkert/omit-value>
// Copyright (c) 2015, Jon Schlinkert. (MIT)

var isObject = require('../lang/isPlainObject')
var isString = require('../lang/isString')
var omit     = require('./omit')
var get      = require('./get')
var set      = require('./set')
var assert   = require('assert')

function omitValue (obj, prop, keys) {
  assert(isObject(obj), 'omitValue expects first arg to be an object.')
  assert(isString(prop), 'omitValue expects prop to be a string')

  if (typeof keys === 'undefined') return omit(obj, prop)

  var val = get(obj, prop)
  set(obj, prop, omit(val, keys))
  return obj
}

module.exports = omitValue
<|endoftext|>


<commit_before>/**
 * @module ol/layer/Heatmap
 */
import {getChangeEventType} from '../Object.js';
import {createCanvasContext2D} from '../dom.js';
import VectorLayer from './Vector.js';
import {assign} from '../obj.js';
import WebGLPointsLayerRenderer from '../renderer/webgl/PointsLayer.js';

/**
 * @typedef {Object} Options
 * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.
 * @property {number} [opacity=1] Opacity (0, 1).
 * @property {boolean} [visible=true] Visibility.
 * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering.  The layer will not be
 * rendered outside of this extent.
 * @property {number} [zIndex] The z-index for layer rendering.  At rendering time, the layers
 * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed
 * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`
 * method was used.
 * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be
 * visible.
 * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will
 * be visible.
 * @property {Array<string>} [gradient=['#00f', '#0ff', '#0f0', '#ff0', '#f00']] The color gradient
 * of the heatmap, specified as an array of CSS color strings.
 * @property {number} [radius=8] Radius size in pixels.
 * @property {number} [blur=15] Blur size in pixels.
 * @property {string|function(import("../Feature.js").default):number} [weight='weight'] The feature
 * attribute to use for the weight or a function that returns a weight from a feature. Weight values
 * should range from 0 to 1 (and values outside will be clamped to that range).
 * @property {import("../source/Vector.js").default} [source] Source.
 */

/**
 * @enum {string}
 * @private
 */
const Property = {
  BLUR: 'blur',
  GRADIENT: 'gradient',
  RADIUS: 'radius'
};

/**
 * @const
 * @type {Array<string>}
 */
const DEFAULT_GRADIENT = ['#00f', '#0ff', '#0f0', '#ff0', '#f00'];

/**
 * @classdesc
 * Layer for rendering vector data as a heatmap.
 * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}
 * property on the layer object; for example, setting `title: 'My Title'` in the
 * options means that `title` is observable, and has get/set accessors.
 *
 * @fires import("../render/Event.js").RenderEvent
 * @api
 */
class Heatmap extends VectorLayer {
  /**
   * @param {Options=} opt_options Options.
   */
  constructor(opt_options) {
    const options = opt_options ? opt_options : {};

    const baseOptions = assign({}, options);

    delete baseOptions.gradient;
    delete baseOptions.radius;
    delete baseOptions.blur;
    delete baseOptions.weight;
    super(baseOptions);

    /**
     * @private
     * @type {HTMLCanvasElement}
     */
    this.gradient_ = null;

    this.addEventListener(getChangeEventType(Property.GRADIENT), this.handleGradientChanged_);

    this.setGradient(options.gradient ? options.gradient : DEFAULT_GRADIENT);

    this.setBlur(options.blur !== undefined ? options.blur : 15);

    this.setRadius(options.radius !== undefined ? options.radius : 8);

    const weight = options.weight ? options.weight : 'weight';
    if (typeof weight === 'string') {
      this.weightFunction_ = function(feature) {
        return feature.get(weight);
      };
    } else {
      this.weightFunction_ = weight;
    }

    // For performance reasons, don't sort the features before rendering.
    // The render order is not relevant for a heatmap representation.
    this.setRenderOrder(null);
  }

  /**
   * Return the blur size in pixels.
   * @return {number} Blur size in pixels.
   * @api
   * @observable
   */
  getBlur() {
    return /** @type {number} */ (this.get(Property.BLUR));
  }

  /**
   * Return the gradient colors as array of strings.
   * @return {Array<string>} Colors.
   * @api
   * @observable
   */
  getGradient() {
    return /** @type {Array<string>} */ (this.get(Property.GRADIENT));
  }

  /**
   * Return the size of the radius in pixels.
   * @return {number} Radius size in pixel.
   * @api
   * @observable
   */
  getRadius() {
    return /** @type {number} */ (this.get(Property.RADIUS));
  }

  /**
   * @private
   */
  handleGradientChanged_() {
    this.gradient_ = createGradient(this.getGradient());
  }

  /**
   * Set the blur size in pixels.
   * @param {number} blur Blur size in pixels.
   * @api
   * @observable
   */
  setBlur(blur) {
    this.set(Property.BLUR, blur);
  }

  /**
   * Set the gradient colors as array of strings.
   * @param {Array<string>} colors Gradient.
   * @api
   * @observable
   */
  setGradient(colors) {
    this.set(Property.GRADIENT, colors);
  }

  /**
   * Set the size of the radius in pixels.
   * @param {number} radius Radius size in pixel.
   * @api
   * @observable
   */
  setRadius(radius) {
    this.set(Property.RADIUS, radius);
  }

  /**
   * @inheritDoc
   */
  createRenderer() {
    return new WebGLPointsLayerRenderer(this, {
      attributes: [
        {
          name: 'weight',
          callback: this.weightFunction_
        }
      ],
      vertexShader: `
        precision mediump float;
        uniform mat4 u_projectionMatrix;
        uniform mat4 u_offsetScaleMatrix;
        uniform float u_size;
        attribute vec2 a_position;
        attribute float a_index;
        attribute float a_weight;

        varying vec2 v_texCoord;
        varying float v_weight;

        void main(void) {
          mat4 offsetMatrix = u_offsetScaleMatrix;
          float offsetX = a_index == 0.0 || a_index == 3.0 ? -u_size / 2.0 : u_size / 2.0;
          float offsetY = a_index == 0.0 || a_index == 1.0 ? -u_size / 2.0 : u_size / 2.0;
          vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
          gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
          float u = a_index == 0.0 || a_index == 3.0 ? 0.0 : 1.0;
          float v = a_index == 0.0 || a_index == 1.0 ? 0.0 : 1.0;
          v_texCoord = vec2(u, v);
          v_weight = a_weight;
        }`,
      fragmentShader: `
        precision mediump float;
        uniform float u_blurSlope;

        varying vec2 v_texCoord;
        varying float v_weight;

        void main(void) {
          vec2 texCoord = v_texCoord * 2.0 - vec2(1.0, 1.0);
          float sqRadius = texCoord.x * texCoord.x + texCoord.y * texCoord.y;
          float value = (1.0 - sqrt(sqRadius)) * u_blurSlope;
          float alpha = smoothstep(0.0, 1.0, value) * v_weight;
          gl_FragColor = vec4(alpha, alpha, alpha, alpha);
        }`,
      hitVertexShader: `
        precision mediump float;
        uniform mat4 u_projectionMatrix;
        uniform mat4 u_offsetScaleMatrix;
        uniform float u_size;
        attribute vec2 a_position;
        attribute float a_index;
        attribute float a_weight;
        attribute vec4 a_hitColor;

        varying vec2 v_texCoord;
        varying float v_weight;
        varying vec4 v_hitColor;

        void main(void) {
          mat4 offsetMatrix = u_offsetScaleMatrix;
          float offsetX = a_index == 0.0 || a_index == 3.0 ? -u_size / 2.0 : u_size / 2.0;
          float offsetY = a_index == 0.0 || a_index == 1.0 ? -u_size / 2.0 : u_size / 2.0;
          vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
          gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
          float u = a_index == 0.0 || a_index == 3.0 ? 0.0 : 1.0;
          float v = a_index == 0.0 || a_index == 1.0 ? 0.0 : 1.0;
          v_texCoord = vec2(u, v);
          v_hitColor = a_hitColor;
          v_weight = a_weight;
        }`,
      hitFragmentShader: `
        precision mediump float;
        uniform float u_blurSlope;

        varying vec2 v_texCoord;
        varying float v_weight;
        varying vec4 v_hitColor;

        void main(void) {
          vec2 texCoord = v_texCoord * 2.0 - vec2(1.0, 1.0);
          float sqRadius = texCoord.x * texCoord.x + texCoord.y * texCoord.y;
          float value = (1.0 - sqrt(sqRadius)) * u_blurSlope;
          float alpha = smoothstep(0.0, 1.0, value) * v_weight;
          if (alpha < 0.05) {
            discard;
          }

          gl_FragColor = v_hitColor;
        }`,
      uniforms: {
        u_size: function() {
          return (this.get(Property.RADIUS) + this.get(Property.BLUR)) * 2;
        }.bind(this),
        u_blurSlope: function() {
          return this.get(Property.RADIUS) / Math.max(1, this.get(Property.BLUR));
        }.bind(this)
      },
      postProcesses: [
        {
          fragmentShader: `
            precision mediump float;

            uniform sampler2D u_image;
            uniform sampler2D u_gradientTexture;

            varying vec2 v_texCoord;

            void main() {
              vec4 color = texture2D(u_image, v_texCoord);
              gl_FragColor.a = color.a;
              gl_FragColor.rgb = texture2D(u_gradientTexture, vec2(0.5, color.a)).rgb;
              gl_FragColor.rgb *= gl_FragColor.a;
            }`,
          uniforms: {
            u_gradientTexture: this.gradient_
          }
        }
      ]
    });
  }
}

/**
 * @param {Array<string>} colors A list of colored.
 * @return {HTMLCanvasElement} canvas with gradient texture.
 */
function createGradient(colors) {
  const width = 1;
  const height = 256;
  const context = createCanvasContext2D(width, height);

  const gradient = context.createLinearGradient(0, 0, width, height);
  const step = 1 / (colors.length - 1);
  for (let i = 0, ii = colors.length; i < ii; ++i) {
    gradient.addColorStop(i * step, colors[i]);
  }

  context.fillStyle = gradient;
  context.fillRect(0, 0, width, height);

  return context.canvas;
}

export default Heatmap;
<commit_msg>Clamp the weight value between 0 and 1<commit_after>/**
 * @module ol/layer/Heatmap
 */
import {getChangeEventType} from '../Object.js';
import {createCanvasContext2D} from '../dom.js';
import VectorLayer from './Vector.js';
import {clamp} from '../math.js';
import {assign} from '../obj.js';
import WebGLPointsLayerRenderer from '../renderer/webgl/PointsLayer.js';

/**
 * @typedef {Object} Options
 * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.
 * @property {number} [opacity=1] Opacity (0, 1).
 * @property {boolean} [visible=true] Visibility.
 * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering.  The layer will not be
 * rendered outside of this extent.
 * @property {number} [zIndex] The z-index for layer rendering.  At rendering time, the layers
 * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed
 * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`
 * method was used.
 * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be
 * visible.
 * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will
 * be visible.
 * @property {Array<string>} [gradient=['#00f', '#0ff', '#0f0', '#ff0', '#f00']] The color gradient
 * of the heatmap, specified as an array of CSS color strings.
 * @property {number} [radius=8] Radius size in pixels.
 * @property {number} [blur=15] Blur size in pixels.
 * @property {string|function(import("../Feature.js").default):number} [weight='weight'] The feature
 * attribute to use for the weight or a function that returns a weight from a feature. Weight values
 * should range from 0 to 1 (and values outside will be clamped to that range).
 * @property {import("../source/Vector.js").default} [source] Source.
 */

/**
 * @enum {string}
 * @private
 */
const Property = {
  BLUR: 'blur',
  GRADIENT: 'gradient',
  RADIUS: 'radius'
};

/**
 * @const
 * @type {Array<string>}
 */
const DEFAULT_GRADIENT = ['#00f', '#0ff', '#0f0', '#ff0', '#f00'];

/**
 * @classdesc
 * Layer for rendering vector data as a heatmap.
 * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}
 * property on the layer object; for example, setting `title: 'My Title'` in the
 * options means that `title` is observable, and has get/set accessors.
 *
 * @fires import("../render/Event.js").RenderEvent
 * @api
 */
class Heatmap extends VectorLayer {
  /**
   * @param {Options=} opt_options Options.
   */
  constructor(opt_options) {
    const options = opt_options ? opt_options : {};

    const baseOptions = assign({}, options);

    delete baseOptions.gradient;
    delete baseOptions.radius;
    delete baseOptions.blur;
    delete baseOptions.weight;
    super(baseOptions);

    /**
     * @private
     * @type {HTMLCanvasElement}
     */
    this.gradient_ = null;

    this.addEventListener(getChangeEventType(Property.GRADIENT), this.handleGradientChanged_);

    this.setGradient(options.gradient ? options.gradient : DEFAULT_GRADIENT);

    this.setBlur(options.blur !== undefined ? options.blur : 15);

    this.setRadius(options.radius !== undefined ? options.radius : 8);

    const weight = options.weight ? options.weight : 'weight';
    if (typeof weight === 'string') {
      this.weightFunction_ = function(feature) {
        return feature.get(weight);
      };
    } else {
      this.weightFunction_ = weight;
    }

    // For performance reasons, don't sort the features before rendering.
    // The render order is not relevant for a heatmap representation.
    this.setRenderOrder(null);
  }

  /**
   * Return the blur size in pixels.
   * @return {number} Blur size in pixels.
   * @api
   * @observable
   */
  getBlur() {
    return /** @type {number} */ (this.get(Property.BLUR));
  }

  /**
   * Return the gradient colors as array of strings.
   * @return {Array<string>} Colors.
   * @api
   * @observable
   */
  getGradient() {
    return /** @type {Array<string>} */ (this.get(Property.GRADIENT));
  }

  /**
   * Return the size of the radius in pixels.
   * @return {number} Radius size in pixel.
   * @api
   * @observable
   */
  getRadius() {
    return /** @type {number} */ (this.get(Property.RADIUS));
  }

  /**
   * @private
   */
  handleGradientChanged_() {
    this.gradient_ = createGradient(this.getGradient());
  }

  /**
   * Set the blur size in pixels.
   * @param {number} blur Blur size in pixels.
   * @api
   * @observable
   */
  setBlur(blur) {
    this.set(Property.BLUR, blur);
  }

  /**
   * Set the gradient colors as array of strings.
   * @param {Array<string>} colors Gradient.
   * @api
   * @observable
   */
  setGradient(colors) {
    this.set(Property.GRADIENT, colors);
  }

  /**
   * Set the size of the radius in pixels.
   * @param {number} radius Radius size in pixel.
   * @api
   * @observable
   */
  setRadius(radius) {
    this.set(Property.RADIUS, radius);
  }

  /**
   * @inheritDoc
   */
  createRenderer() {
    return new WebGLPointsLayerRenderer(this, {
      attributes: [
        {
          name: 'weight',
          callback: function(feature) {
            const weight = this.weightFunction_(feature);
            return weight !== undefined ? clamp(weight, 0, 1) : 1;
          }.bind(this)
        }
      ],
      vertexShader: `
        precision mediump float;
        uniform mat4 u_projectionMatrix;
        uniform mat4 u_offsetScaleMatrix;
        uniform float u_size;
        attribute vec2 a_position;
        attribute float a_index;
        attribute float a_weight;

        varying vec2 v_texCoord;
        varying float v_weight;

        void main(void) {
          mat4 offsetMatrix = u_offsetScaleMatrix;
          float offsetX = a_index == 0.0 || a_index == 3.0 ? -u_size / 2.0 : u_size / 2.0;
          float offsetY = a_index == 0.0 || a_index == 1.0 ? -u_size / 2.0 : u_size / 2.0;
          vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
          gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
          float u = a_index == 0.0 || a_index == 3.0 ? 0.0 : 1.0;
          float v = a_index == 0.0 || a_index == 1.0 ? 0.0 : 1.0;
          v_texCoord = vec2(u, v);
          v_weight = a_weight;
        }`,
      fragmentShader: `
        precision mediump float;
        uniform float u_blurSlope;

        varying vec2 v_texCoord;
        varying float v_weight;

        void main(void) {
          vec2 texCoord = v_texCoord * 2.0 - vec2(1.0, 1.0);
          float sqRadius = texCoord.x * texCoord.x + texCoord.y * texCoord.y;
          float value = (1.0 - sqrt(sqRadius)) * u_blurSlope;
          float alpha = smoothstep(0.0, 1.0, value) * v_weight;
          gl_FragColor = vec4(alpha, alpha, alpha, alpha);
        }`,
      hitVertexShader: `
        precision mediump float;
        uniform mat4 u_projectionMatrix;
        uniform mat4 u_offsetScaleMatrix;
        uniform float u_size;
        attribute vec2 a_position;
        attribute float a_index;
        attribute float a_weight;
        attribute vec4 a_hitColor;

        varying vec2 v_texCoord;
        varying float v_weight;
        varying vec4 v_hitColor;

        void main(void) {
          mat4 offsetMatrix = u_offsetScaleMatrix;
          float offsetX = a_index == 0.0 || a_index == 3.0 ? -u_size / 2.0 : u_size / 2.0;
          float offsetY = a_index == 0.0 || a_index == 1.0 ? -u_size / 2.0 : u_size / 2.0;
          vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);
          gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
          float u = a_index == 0.0 || a_index == 3.0 ? 0.0 : 1.0;
          float v = a_index == 0.0 || a_index == 1.0 ? 0.0 : 1.0;
          v_texCoord = vec2(u, v);
          v_hitColor = a_hitColor;
          v_weight = a_weight;
        }`,
      hitFragmentShader: `
        precision mediump float;
        uniform float u_blurSlope;

        varying vec2 v_texCoord;
        varying float v_weight;
        varying vec4 v_hitColor;

        void main(void) {
          vec2 texCoord = v_texCoord * 2.0 - vec2(1.0, 1.0);
          float sqRadius = texCoord.x * texCoord.x + texCoord.y * texCoord.y;
          float value = (1.0 - sqrt(sqRadius)) * u_blurSlope;
          float alpha = smoothstep(0.0, 1.0, value) * v_weight;
          if (alpha < 0.05) {
            discard;
          }

          gl_FragColor = v_hitColor;
        }`,
      uniforms: {
        u_size: function() {
          return (this.get(Property.RADIUS) + this.get(Property.BLUR)) * 2;
        }.bind(this),
        u_blurSlope: function() {
          return this.get(Property.RADIUS) / Math.max(1, this.get(Property.BLUR));
        }.bind(this)
      },
      postProcesses: [
        {
          fragmentShader: `
            precision mediump float;

            uniform sampler2D u_image;
            uniform sampler2D u_gradientTexture;

            varying vec2 v_texCoord;

            void main() {
              vec4 color = texture2D(u_image, v_texCoord);
              gl_FragColor.a = color.a;
              gl_FragColor.rgb = texture2D(u_gradientTexture, vec2(0.5, color.a)).rgb;
              gl_FragColor.rgb *= gl_FragColor.a;
            }`,
          uniforms: {
            u_gradientTexture: this.gradient_
          }
        }
      ]
    });
  }
}

/**
 * @param {Array<string>} colors A list of colored.
 * @return {HTMLCanvasElement} canvas with gradient texture.
 */
function createGradient(colors) {
  const width = 1;
  const height = 256;
  const context = createCanvasContext2D(width, height);

  const gradient = context.createLinearGradient(0, 0, width, height);
  const step = 1 / (colors.length - 1);
  for (let i = 0, ii = colors.length; i < ii; ++i) {
    gradient.addColorStop(i * step, colors[i]);
  }

  context.fillStyle = gradient;
  context.fillRect(0, 0, width, height);

  return context.canvas;
}

export default Heatmap;
<|endoftext|>