<commit_before>/* eslint-disable no-console */

import { scheduleJob } from 'node-schedule';
import moment from 'moment';
import cache from 'memory-cache';
import { roles, wxeapi, dailyReportCron,
  auth, getTag, dailyReportPicUrl, host,
  error, info, TAG_LIST,
  getShopBillCacheKey,
  getShopDailyBillsCacheKey, getDeviceBillsCacheKey,
  getSubShopDailyBillsCacheKey } from '../../config';
import * as shopModel from './cachedShop';

const TEN_DAYS = 10 * 24 * 60 * 60 * 1000;

/*
发送账单给微信用户
参数：
  - bill 账单对象
  - to 接收账单的用户对象，例如: { touser: ['na57'] }
  - agentId 整数，用于发送消息的企业号应用Id
 */
const sendBill = async (bill, to, agentId) => {
  try {
    // 生成消息文本
    const article = {
      title: `${bill.shopName}日账单(${bill.accDate})`,
      description: `消费金额：${bill.crAmt}元，共${bill.transCnt}笔。`,
      url: `https://${host}/shop/${bill.shopId}/daily-bill/${bill.accDate}`,
      picurl: dailyReportPicUrl,
    };

    // 2.3. 推送微信通知
    return wxeapi.sendNews(to, agentId, [article]);
  } catch (e) {
    error('sendBill():', e.message);
    error('sendBill():', e.stack);
    return Promise.reject(e);
  }
};

const cacheDailyData = async day => {
  // 1. 缓存指定日期的所有日账单
  const shopBills = await shopModel.fetchShopDailyBills(day, {
    key: getShopDailyBillsCacheKey(day),
    expire: TEN_DAYS,
  });
  // 2. 缓存每个商户的所有数据
  const billPromises = shopBills.map(bill => {
    // 2.1. 缓存每一个商户的日账单
    const pBill = shopModel.fetchDailyBill(bill.shopId, day, {
      key: getShopBillCacheKey(bill.shopId, day),
      expire: TEN_DAYS,
    });

    // 2.2. 缓存每个商户的子商户日账单列表
    const pSubShopBills = shopModel.fetchSubShopDailyBills(bill.shopId, day, {
      key: getSubShopDailyBillsCacheKey(bill.shopId, day),
      expire: TEN_DAYS,
    });

    // 2.3. 缓存每个商户的设备日账单列表
    const pDeviceBills = shopModel.fetchDeviceDailyBills(bill.shopId, day, {
      key: getDeviceBillsCacheKey(bill.shopId, day),
      expire: TEN_DAYS,
    });
    return Promise.all([pBill, pSubShopBills, pDeviceBills]);
  });
  await Promise.all(billPromises);
};

const reportDailyShopBill = async () => {
  try {
    // 0. 从远程获取tag列表，并缓存
    const tags = await wxeapi.getTagList();
    cache.put(TAG_LIST, tags, TEN_DAYS);
    info('tags count: ', tags.length);

    const yestoday = moment().subtract(1, 'days').format('YYYYMMDD');
    // 1. 获取商户账单列表
    const shopBills = await shopModel.fetchShopDailyBills(yestoday, {
      key: getShopDailyBillsCacheKey(yestoday),
      expire: TEN_DAYS,
    });

    // 2. 循环每个商户账单
    const result = shopBills.map(bill => {
      try {
        // 2.2. 找出tagId
        const tagname = getTag(roles.shopManager, bill.shopName);
        const tag = tags.find(t => t.tagname === tagname);
        if (!tag) {
          info('tagname is not exists: ', tagname);
          return Promise.resolve({});
        }

        // 2.3. 推送微信通知
        return sendBill(bill, { totag: `${tag.tagid}` }, auth.wxent.agentId);
      } catch (e) {
        error('exception occured when send bill: ', bill);
        error(e.message);
        error(e.stack);
        return null;
      }
    });
    return Promise.all(result);
  } catch (e) {
    error('exception occured when reportDailyShopBill()');
    error(e);
    throw e;
  }
};

scheduleJob(dailyReportCron, async () => {
  info('start to daily report. date:', Date.now());
  const result = await reportDailyShopBill();
  info('daily report is done.', {
    发送成功: result.filter(r => r.errcode === 0).length,
    发送失败: result.filter(r => r.errcode !== 0).length,
    未发送: result.filter(r => r === {}).length,
  });
});
info('start the reportDaliy job.');

scheduleJob('0 30 * * * *', () => {
  console.log('cache size:', cache.size());
});
info('start to cache size report job.');

scheduleJob('0 0 6 * * *', async () => {
  console.time('缓存数据');
  try {
    const yestoday = moment().subtract(1, 'days').format('YYYYMMDD');
    await cacheDailyData(yestoday);
    console.log(cache.size());
  } catch (e) {
    error('缓存数据出错', e.message);
    error(e.stack);
  } finally {
    console.timeEnd('缓存数据');
  }
  info('完成上一日所有数据缓存');
});
<commit_msg>统一账单报表页面<commit_after>/* eslint-disable no-console */

import { scheduleJob } from 'node-schedule';
import moment from 'moment';
import cache from 'memory-cache';
import { roles, wxeapi, dailyReportCron,
  auth, getTag, dailyReportPicUrl, host,
  error, info, TAG_LIST,
  getShopBillCacheKey,
  getShopDailyBillsCacheKey, getDeviceBillsCacheKey,
  getSubShopDailyBillsCacheKey } from '../../config';
import * as shopModel from './cachedShop';

const TEN_DAYS = 10 * 24 * 60 * 60 * 1000;

/*
发送账单给微信用户
参数：
  - bill 账单对象
  - to 接收账单的用户对象，例如: { touser: ['na57'] }
  - agentId 整数，用于发送消息的企业号应用Id
 */
const sendBill = async (bill, to, agentId) => {
  try {
    // 生成消息文本
    const article = {
      title: `${bill.shopName}日账单(${bill.accDate})`,
      description: `消费金额：${bill.crAmt}元，共${bill.transCnt}笔。`,
      url: `https://${host}/shop/${bill.shopId}/report/${bill.accDate}`,
      picurl: dailyReportPicUrl,
    };

    // 2.3. 推送微信通知
    return wxeapi.sendNews(to, agentId, [article]);
  } catch (e) {
    error('sendBill():', e.message);
    error('sendBill():', e.stack);
    return Promise.reject(e);
  }
};

const cacheDailyData = async day => {
  // 1. 缓存指定日期的所有日账单
  const shopBills = await shopModel.fetchShopDailyBills(day, {
    key: getShopDailyBillsCacheKey(day),
    expire: TEN_DAYS,
  });
  // 2. 缓存每个商户的所有数据
  const billPromises = shopBills.map(bill => {
    // 2.1. 缓存每一个商户的日账单
    const pBill = shopModel.fetchDailyBill(bill.shopId, day, {
      key: getShopBillCacheKey(bill.shopId, day),
      expire: TEN_DAYS,
    });

    // 2.2. 缓存每个商户的子商户日账单列表
    const pSubShopBills = shopModel.fetchSubShopDailyBills(bill.shopId, day, {
      key: getSubShopDailyBillsCacheKey(bill.shopId, day),
      expire: TEN_DAYS,
    });

    // 2.3. 缓存每个商户的设备日账单列表
    const pDeviceBills = shopModel.fetchDeviceDailyBills(bill.shopId, day, {
      key: getDeviceBillsCacheKey(bill.shopId, day),
      expire: TEN_DAYS,
    });
    return Promise.all([pBill, pSubShopBills, pDeviceBills]);
  });
  await Promise.all(billPromises);
};

const reportDailyShopBill = async () => {
  try {
    // 0. 从远程获取tag列表，并缓存
    const tags = await wxeapi.getTagList();
    cache.put(TAG_LIST, tags, TEN_DAYS);
    info('tags count: ', tags.length);

    const yestoday = moment().subtract(1, 'days').format('YYYYMMDD');
    // 1. 获取商户账单列表
    const shopBills = await shopModel.fetchShopDailyBills(yestoday, {
      key: getShopDailyBillsCacheKey(yestoday),
      expire: TEN_DAYS,
    });

    // 2. 循环每个商户账单
    const result = shopBills.map(bill => {
      try {
        // 2.2. 找出tagId
        const tagname = getTag(roles.shopManager, bill.shopName);
        const tag = tags.find(t => t.tagname === tagname);
        if (!tag) {
          info('tagname is not exists: ', tagname);
          return Promise.resolve({});
        }

        // 2.3. 推送微信通知
        return sendBill(bill, { totag: `${tag.tagid}` }, auth.wxent.agentId);
      } catch (e) {
        error('exception occured when send bill: ', bill);
        error(e.message);
        error(e.stack);
        return null;
      }
    });
    return Promise.all(result);
  } catch (e) {
    error('exception occured when reportDailyShopBill()');
    error(e);
    throw e;
  }
};

scheduleJob(dailyReportCron, async () => {
  info('start to daily report. date:', Date.now());
  const result = await reportDailyShopBill();
  info('daily report is done.', {
    发送成功: result.filter(r => r.errcode === 0).length,
    发送失败: result.filter(r => r.errcode !== 0).length,
    未发送: result.filter(r => r === {}).length,
  });
});
info('start the reportDaliy job.');

scheduleJob('0 30 * * * *', () => {
  console.log('cache size:', cache.size());
});
info('start to cache size report job.');

scheduleJob('0 0 6 * * *', async () => {
  console.time('缓存数据');
  try {
    const yestoday = moment().subtract(1, 'days').format('YYYYMMDD');
    await cacheDailyData(yestoday);
    console.log(cache.size());
  } catch (e) {
    error('缓存数据出错', e.message);
    error(e.stack);
  } finally {
    console.timeEnd('缓存数据');
  }
  info('完成上一日所有数据缓存');
});
<|endoftext|>


<commit_before>var fs = require('fs');
var Path = require('path');
var debug = require('debug')('express-dom');
var Pool = require('./pool');
var URL = require('url');
var BufferList = require('bl');
var pify = require('pify');
var clone = require('clone');

var pool;
var dom = module.exports = function() {
	if (!pool) {
		pool = new Pool(dom.pool, dom); // do not use instance options
		dom.acquire = pool.acquire.bind(pool);
		dom.release = pool.release.bind(pool);
	}
	var h = new Handler(Array.from(arguments));
	return h.chainable;
};

dom.plugins = require('./plugins');
dom.helpers = require('./helpers');

dom.pool = {
	max: 8,
	destroyTimeout: 600000,
	idleTimeout: 180000
};

dom.settings = {
	helpers: [
		dom.helpers.view
	],
	prepare: {
		plugins: [
			dom.plugins.hide,
			dom.plugins.noreq,
			dom.plugins.html
		]
	},
	load: {
		plugins: [
			dom.plugins.hide,
			dom.plugins.nomedia,
			dom.plugins.prerender,
			dom.plugins.redirect,
			dom.plugins.referrer,
			dom.plugins.html
		]
	},
	console: process.env.NODE_ENV != "production",
	stall: 15000,
	allow: "same-origin",
	navigation: false,
	develop: !!process.env.DEVELOP
};

function Handler(args) {
	var h = this;
	var view = args[0];
	if (typeof view != "function") args.shift();
	else view = null;
	h.view = view;
	debug("new handler", view);
	h.settings = {
		helpers: args.concat(dom.settings.helpers)
	};

	h.chainable = h.middleware.bind(h);
	h.chainable.prepare = function(opts) {
		h.settings.prepare = initOpts(opts, dom.settings.prepare, Array.from(arguments));
		return h.chainable;
	};
	h.chainable.load = function(opts) {
		if (dom.settings.develop) {
			console.warn("develop mode is ON");
			var args = Array.from(arguments);
			if (typeof args[0] != "function") args.shift();
			console.info("Rewiring", args.length, "appended load plugins");
			if (args.length) {
				if (!h.settings.prepare) h.chainable.prepare({});
				while (args.length) h.settings.prepare.plugins.unshift(args.pop());
			}
		} else {
			h.settings.load = initOpts(opts, dom.settings.load, Array.from(arguments));
		}
		return h.chainable;
	};
}

function initOpts(opts, defaults, args) {
	if (typeof opts == "function") opts = null;
	else args.shift();

	opts = Object.assign({
		filters: [],
		plugins: [],
		scripts: []
	}, dom.settings, defaults, opts);
	var plugins = opts.plugins;
	if (typeof plugins == "function") plugins = [plugins];
	opts.plugins = args.concat(plugins || defaults.plugins);

	return opts;
}

Handler.prototype.middleware = function(req, res, next) {
	var h = this;
	// per request settings
	var loc = URL.parse(
		(req.get('X-Forwarded-Proto') || req.protocol) + '://' + req.headers.host
	);
	var settings = Object.assign({
		location: {
			protocol: loc.protocol,
			hostname: loc.hostname,
			port: loc.port,
			pathname: req.path,
			query: req.query
		},
		view: h.view
	}, h.settings);

	var p = Promise.resolve();
	settings.helpers.forEach(function(helper) {
		p = p.then(function() {
			return helper(h, settings, req, res);
		}).then(function() {
			if (res.statusCode != 200) return Promise.reject(res.statusCode);
		});
	});
	p.then(function() {
		debug('view loaded for', settings.location.pathname);
		if (!settings.prepare) return;
		return h.runMethod('prepare', settings, req, res);
	}).then(function() {
		if (!settings.load) return;
		return h.runMethod('load', settings, req, res);
	}).then(function() {
		var data = settings.input;
		// hopefully free faster that memory
		delete settings.input;
		if (!res.get('Content-Type')) {
			res.set('Content-Type', "text/html");
		}
		var status = res.statusCode;
		if (data === false) {
			debug("data handled by plugin");
			return;
		}
		if (!data) {
			if (!settings.prepare && !settings.load) {
				return res.sendStatus(501);
			} else {
				return res.sendStatus(404);
			}
		}
		var isPath = true, isStream = false;
		if (Buffer.isBuffer(data)) {
			isPath = false;
		} else if (typeof data.pipe == "function") {
			isPath = false;
			isStream = true;
		} else if (typeof data != "string") {
			data = data.toString();
		}
		if (isPath && data.startsWith('<')) {
			isPath = false;
		}
		if (isPath) {
			res.sendFile(data);
		} else {
			if (status) res.status(status);
			if (isStream) {
				data.pipe(res);
			} else {
				res.send(data);
			}
		}
	}).catch(next);
};

Handler.prototype.runMethod = function(method, settings, request, response) {
	var h = this;
	return pify(dom.acquire)().then(function(page) {
		var hsings = settings[method];
		var plugins = hsings.plugins;
		var psings = Object.assign({}, hsings, settings);
		delete psings.plugins;
		var p = Promise.resolve();
		plugins.forEach(function(plugin) {
			p = p.then(function() {
				return plugin(page, psings, request, response);
			}).then(function() {
				if (response.statusCode != 200) return Promise.reject(response.statusCode);
			});
		});
		return p.then(function() {
			var ip = pify(function(cb) {
				// it would be nice if page.when was returning a promise,
				// but it returns page for listener chainability
				page.when('idle', function(wcb) {
					debug("release idle page", method, page.uri);
					page.pingTime = Date.now();
					wcb();
					dom.release(page, function(err) {
						if (err) console.error("dom.release", err);
					}); // no need to wait for the release
					cb();
				});
			})();
			settings.location = psings.location;
			settings.input = psings.input;
			var url = URL.format(settings.location);
			debug(method, url);
			psings.content = settings.input;
			page[method](url, psings);
			return ip;
		}).then(function() {
			if (psings.output) settings.input = psings.output;
		});
	});
};

<commit_msg>Defaults, per-mw, per-request settings are separated<commit_after>var fs = require('fs');
var Path = require('path');
var debug = require('debug')('express-dom');
var Pool = require('./pool');
var URL = require('url');
var BufferList = require('bl');
var pify = require('pify');
var clone = require('clone');

var pool;
var dom = module.exports = function() {
	if (!pool) {
		pool = new Pool(dom.pool, dom); // do not use instance options
		dom.acquire = pool.acquire.bind(pool);
		dom.release = pool.release.bind(pool);
	}
	var h = new Handler(Array.from(arguments));
	return h.chainable;
};

dom.plugins = require('./plugins');
dom.helpers = require('./helpers');

dom.pool = {
	max: 8,
	destroyTimeout: 600000,
	idleTimeout: 180000
};

dom.settings = {
	helpers: [
		dom.helpers.view
	],
	prepare: {
		plugins: [
			dom.plugins.hide,
			dom.plugins.noreq,
			dom.plugins.html
		]
	},
	load: {
		plugins: [
			dom.plugins.hide,
			dom.plugins.nomedia,
			dom.plugins.prerender,
			dom.plugins.redirect,
			dom.plugins.referrer,
			dom.plugins.html
		]
	},
	console: process.env.NODE_ENV != "production",
	stall: 15000,
	allow: "same-origin",
	navigation: false,
	develop: !!process.env.DEVELOP
};

function Handler(args) {
	var h = this;
	var view = args[0];
	if (typeof view != "function") args.shift();
	else view = null;
	h.view = view;
	debug("new handler", view);
	h.settings = emptySettings(dom.settings);
	h.settings.helpers = args.concat(dom.settings.helpers);
	h.settings.prepare = emptySettings(dom.settings, true);
	h.settings.load = emptySettings(dom.settings, true);

	h.chainable = h.middleware.bind(h);
	h.chainable.prepare = function(opts) {
		initOpts(h.settings.prepare, opts, Array.from(arguments));
		return h.chainable;
	};
	h.chainable.load = function(opts) {
		if (dom.settings.develop) {
			console.warn("develop mode is ON");
			var args = Array.from(arguments);
			if (typeof args[0] != "function") args.shift();
			console.info("Rewiring", args.length, "appended load plugins");
			h.chainable.prepare.apply(this, args);
		} else {
			initOpts(h.settings.load, opts, Array.from(arguments));
		}
		return h.chainable;
	};
}

function initOpts(settings, opts, args) {
	if (typeof opts == "function") opts = null;
	else args.shift();
	Object.assign(settings, opts);
	var plugins = settings.plugins;
	if (typeof plugins == "function") plugins = [plugins];
	settings.plugins = args.concat(plugins);
}

Handler.prototype.middleware = function(req, res, next) {
	var h = this;
	// per request settings
	var loc = URL.parse(
		(req.get('X-Forwarded-Proto') || req.protocol) + '://' + req.headers.host
	);
	var settings = clone(h.settings);
	settings.location = {
		protocol: loc.protocol,
		hostname: loc.hostname,
		port: loc.port,
		pathname: req.path,
		query: req.query
	};
	settings.view = h.view;

	var p = Promise.resolve();
	// ensure helpers can call prepare/load that won't affect h.settings
	var rh = {
		settings: settings,
		load: h.chainable.load.bind(rh),
		prepare: h.chainable.prepare.bind(rh)
	};
	settings.helpers.forEach(function(helper) {
		p = p.then(function() {
			return helper(rh, settings, req, res);
		}).then(function() {
			if (res.statusCode != 200) return Promise.reject(res.statusCode);
		});
	});
	p.then(function() {
		debug('view loaded for', settings.location.pathname);
		if (settings.prepare.plugins.length == 0) return;
		return h.runMethod('prepare', settings, req, res);
	}).then(function() {
		if (settings.load.plugins.length == 0) return;
		return h.runMethod('load', settings, req, res);
	}).then(function() {
		var data = settings.input;
		// hopefully free faster that memory
		delete settings.input;
		if (!res.get('Content-Type')) {
			res.set('Content-Type', "text/html");
		}
		var status = res.statusCode;
		if (data === false) {
			debug("data handled by plugin");
			return;
		}
		if (!data) {
			if (!settings.prepare && !settings.load) {
				return res.sendStatus(501);
			} else {
				return res.sendStatus(404);
			}
		}
		var isPath = true, isStream = false;
		if (Buffer.isBuffer(data)) {
			isPath = false;
		} else if (typeof data.pipe == "function") {
			isPath = false;
			isStream = true;
		} else if (typeof data != "string") {
			data = data.toString();
		}
		if (isPath && data.startsWith('<')) {
			isPath = false;
		}
		if (isPath) {
			res.sendFile(data);
		} else {
			if (status) res.status(status);
			if (isStream) {
				data.pipe(res);
			} else {
				res.send(data);
			}
		}
	}).catch(next);
};

Handler.prototype.runMethod = function(method, settings, request, response) {
	var h = this;
	return pify(dom.acquire)().then(function(page) {
		var mSettings = settings[method];
		var plugins = mSettings.plugins;
		var p = Promise.resolve();
		plugins.forEach(function(plugin) {
			p = p.then(function() {
				return plugin(page, mSettings, request, response);
			}).then(function() {
				if (response.statusCode != 200) return Promise.reject(response.statusCode);
			});
		});
		return p.then(function() {
			var ip = pify(function(cb) {
				// it would be nice if page.when was returning a promise,
				// but it returns page for listener chainability
				page.when('idle', function(wcb) {
					debug("release idle page", method, page.uri);
					page.pingTime = Date.now();
					wcb();
					dom.release(page, function(err) {
						if (err) console.error("dom.release", err);
					}); // no need to wait for the release
					cb();
				});
			})();
			settings.location = mSettings.location;
			settings.input = mSettings.input;
			var url = URL.format(settings.location);
			debug(method, url);
			page[method](url, Objet.assign({content: settings.input}, mSettings);
			return ip;
		}).then(function() {
			if (mSettings.output) settings.input = mSettings.output;
		});
	});
};

function emptySettings(defaults, withArrays) {
	// use defaults but not .load, .prepare sub global settings
	var obj = Object.assign({}, defaults);
	delete obj.load;
	delete obj.prepare;
	obj = clone(obj);
	if (withArrays) {
		if (!obj.filters) obj.filters = [];
		if (!obj.plugins) obj.plugins = [];
		if (!obj.scripts) obj.scripts = [];
	}
	return obj;
}
<|endoftext|>


<commit_before>'use strict';

var forEachChild = function(node, f) {
    for (var child = node.firstChild;
	 child !== null;
	 child = child.next) {
	f(child);
    }
};

var forEachChildWithRemove = function(node, f) {
    for (var child = node.firstChild, next = child.next;
	 child !== null;
	 child = next, next = child ? child.next : null) {
	f(child);
    }
};

var RollingHash = function() {
    this.hash = 0;
};

RollingHash.prototype.updateWithString = function(s) {
    for (var i = 0; i < s.length; i++) {
	this.updateWithInteger(s.charCodeAt(i));
    }
};

RollingHash.prototype.updateWithInteger = function(s) {
    // 'x >>> 0' <=> ToUint32(x), see ECMA262
    this.hash = (17 * this.hash + s) >>> 0;
};

RollingHash.prototype.digest = function(s) {
    return this.hash;
};

var calcAttrHash = function(node) {
    var hasher = new RollingHash;
    var attrs = [
	node.type,
	node.literal,
	node.destination,
	node.title,
	node.info,
	node.level,
	node.type != 'List' ? null : node.listType,
	node.type != 'List' ? null : node.listTight,
	node.type != 'List' ? null : node.listStart,
	node.type != 'List' ? null : node.listDelimiter
    ];
    hasher.updateWithString(JSON.stringify(attrs));
    return node.attrHashCode = hasher.digest();
};

var calcChildrenHash = function(node) {
    var hasher = new RollingHash;
    forEachChild(node, (child) => {
	hasher.updateWithInteger(calcHash(child));
    });
    return node.childrenHashCode = hasher.digest();
};

var calcHash = function(node) {
    var hasher = new RollingHash;
    hasher.updateWithInteger(calcAttrHash(node));
    hasher.updateWithInteger(calcChildrenHash(node));
    return node.hashCode = hasher.digest();
};

var Creator = function() {
    this.tree = null;
    this.creators = {
	Text: (node) => {
	    return document.createTextNode('');
	},
	Softbreak: (node) => {
	    return document.createTextNode('\n');
	},
	Hardbreak: (node) => {
	    return document.createElement('br');
	},
	Emph: (node) => {
	    return document.createElement('em');
	},
	Strong: (node) => {
	    return document.createElement('strong');
	},
	Html: (node) => {
	    console.warn('raw html is not supported');
	    return document.createTextNode('');
	},
	Link: (node) => {
	    return document.createElement('a');
	},
	Image: (node) => {
	    return document.createElement('image');
	},
	Code: (node) => {
	    return document.createElement('code');
	},
	Document: (node) => {
	    return document.createElement('div');
	},
	Paragraph: (node) => {
	    return document.createElement('p');
	},
	BlockQuote: (node) => {
	    return document.createElement('blockquote');
	},
	Item: (node) => {
	    return document.createElement('li');
	},
	List: (node) => {
	    return document.createElement(
		node.listType == 'Bullet' ? 'ul' : 'ol');
	},
	Header: (node) => {
	    return document.createElement('h' + node.level);
	},
	CodeBlock: (node) => {
	    var text = document.createTextNode('');
	    var code = document.createElement('code');
	    var pre = document.createElement('pre');
	    code.appendChild(text);
	    pre.appendChild(code);
	    return pre;
	},
	HtmlBlock: (node) => {
	    return document.createElement('div');
	},
	HorizontalRule: (node) => {
	    return document.createElement('hr');
	}
    };
    this.onUpdate = {
	Text: (node) => {
	    node.dom.textContent = node.literal;
	},
	Html: (node) => {
	    console.warn('raw html is not supported');
	    node.dom.textContent = node.literal;
	},
	Link: (node) => {
	    node.dom.setAttribute('href', node.destination);
	    if (node.title) {
		node.dom.setAttribute('title', node.title);
	    }
	},
	Image: (node) => {
	    node.dom.setAttribute('src', node.destination);
	    if (node.title) {
		node.dom.setAttribute('title', node.title);
	    }
	},
	Code: (node) => {
	    node.dom.textContent = node.literal;
	},
	List: (node) => {
	    if (node.listStart != null &&
		node.listStart != 1) {
		node.dom.setAttribute(
		    'start',
		    node.listStart.toString());
	    }
	},
	CodeBlock: (node) => {
	    node.dom.textContent = node.literal;
	},
	HtmlBlock: (node) => {
	    console.warn('raw html block is not supported');
	    node.dom.textContent = node.literal;
	}
    };
    this.specialRules = {
	Image: (node, dom) => {
	    var buf = [];
	    forEachChild(node, (child) => {
		buf.push(this.create(child).textContent);
	    });
	    dom.setAttribute('alt', buf.join(''));
	}
    };
};

Creator.prototype.create = function(node) {
    var dom = node.dom = this.creators[node.type](node);
    if (this.onUpdate[node.type]) {
	this.onUpdate[node.type](node, dom);
    }
    if (this.specialRules[node.type]) {
	this.specialRules[node.type](node, dom);
    } else {
	forEachChild(node, (child) => {
	    node.dom.appendChild(this.create(child));
	});
    }
    return dom;
};

Creator.prototype._update = function(node1, node2) {
    if (node1.hashCode == node2.hashCode) {
	throw 'hashCode must be difference';
    }
    var dom = node2.dom = node1.dom;
    if (node1.attrHashCode != node2.attrHashCode) {
	if (node1.type != node2.type
	    || (node1.type == 'List'
		&& node1.listType != node2.listType)
	    || (node1.type == 'Header'
		&& node1.level != node2.level)) {
	    node2.dom = this.create(node2);
	    return node2.dom;
	}
	if (this.onUpdate[node2.type]) {
	    this.onUpdate[node2.type](node2, node1.dom);
	}
    }
    if (node1.childrenHashCode != node2.childrenHashCode) {
	if (this.specialRules[node2.type]) {
	    this.specialRules[node2.type](node2, dom);
	} else {
	    this._updateChildren(node1, node2);
	}
    }
    return dom;
};

Creator.prototype._updateChildren = function(node1, node2) {
    var dom = node2.dom;
    var c1l = node1.firstChild, c2l = node2.firstChild,
	c1l_next, c2l_next;
    while (c1l != null && c2l != null
	   && c1l.hashCode == c2l.hashCode) {
	c1l_next = c1l.next, c2l_next = c2l.next;
	c2l.insertBefore(c1l);
	c2l.unlink();
	c1l = c1l_next, c2l = c2l_next;
    }
    c1l = (c1l != null ? c1l.prev : node1.lastChild);
    c2l = (c2l != null ? c2l.prev : node2.lastChild);
    var c1r = node1.lastChild, c2r = node2.lastChild,
	c1r_prev, c2r_prev;
    while (c1l != c1r && c2l != c2r &&
	   c1r.hashCode == c2r.hashCode) {
	c1r_prev = c1r.prev, c2r_prev = c2r.prev;
	c2r.insertAfter(c1r);
	c2r.unlink();
	c1r = c1r_prev, c2r = c2r_prev;
    }
    while (c1l != c1r && c2l != c2r) {
	c1r_prev = c1r.prev, c2r_prev = c2r.prev;
	if (c1r.hashCode != c2r.hashCode) {
	    this._update(c1r, c2r);
	    if (c2r.dom != c1r.dom) {
		dom.replaceChild(c2r.dom, c1r.dom);
	    }
	} else {
	    c2r.insertAfter(c1r);
	    c2r.unlink();
	}
	c1r = c1r_prev, c2r = c2r_prev;
    }
    while (c2l != c2r) {
	this.create(c2r);
	if (c2l == null) {
	    dom.insertBefore(c2r.dom, dom.firstChild);
	} else {
	    dom.insertBefore(c2r.dom, c2l.dom.nextSibling);
	}
	c2r = c2r.prev;
    }
    while (c1l != c1r) {
	dom.removeChild(c1r.dom);
	c1r = c1r.prev;
    }
};

Creator.prototype.update = function(tree) {
    if (this.tree != null && this.tree.hashCode == null) {
	calcHash(this.tree);
    }
    console.time('hash');
    calcHash(tree);
    console.timeEnd('hash');
    if (this.tree == null) {
	this.create(tree);
    } else if (this.tree.hashCode == tree.hashCode) {
	tree = this.tree;
    } else {
	this._update(this.tree, tree);
    }
    this.tree = tree;
    return this.tree.dom;
};
module.exports = Creator;
<commit_msg>tab to space(4)<commit_after>'use strict';

var forEachChild = function(node, f) {
    for (var child = node.firstChild;
         child !== null;
         child = child.next) {
        f(child);
    }
};

var forEachChildWithRemove = function(node, f) {
    for (var child = node.firstChild, next = child.next;
         child !== null;
         child = next, next = child ? child.next : null) {
        f(child);
    }
};

var RollingHash = function() {
    this.hash = 0;
};

RollingHash.prototype.updateWithString = function(s) {
    for (var i = 0; i < s.length; i++) {
        this.updateWithInteger(s.charCodeAt(i));
    }
};

RollingHash.prototype.updateWithInteger = function(s) {
    // 'x >>> 0' <=> ToUint32(x), see ECMA262
    this.hash = (17 * this.hash + s) >>> 0;
};

RollingHash.prototype.digest = function(s) {
    return this.hash;
};

var calcAttrHash = function(node) {
    var hasher = new RollingHash;
    var attrs = [
        node.type,
        node.literal,
        node.destination,
        node.title,
        node.info,
        node.level,
        node.type != 'List' ? null : node.listType,
        node.type != 'List' ? null : node.listTight,
        node.type != 'List' ? null : node.listStart,
        node.type != 'List' ? null : node.listDelimiter
    ];
    hasher.updateWithString(JSON.stringify(attrs));
    return node.attrHashCode = hasher.digest();
};

var calcChildrenHash = function(node) {
    var hasher = new RollingHash;
    forEachChild(node, (child) => {
        hasher.updateWithInteger(calcHash(child));
    });
    return node.childrenHashCode = hasher.digest();
};

var calcHash = function(node) {
    var hasher = new RollingHash;
    hasher.updateWithInteger(calcAttrHash(node));
    hasher.updateWithInteger(calcChildrenHash(node));
    return node.hashCode = hasher.digest();
};

var Creator = function() {
    this.tree = null;
    this.creators = {
        Text: (node) => {
            return document.createTextNode('');
        },
        Softbreak: (node) => {
            return document.createTextNode('\n');
        },
        Hardbreak: (node) => {
            return document.createElement('br');
        },
        Emph: (node) => {
            return document.createElement('em');
        },
        Strong: (node) => {
            return document.createElement('strong');
        },
        Html: (node) => {
            console.warn('raw html is not supported');
            return document.createTextNode('');
        },
        Link: (node) => {
            return document.createElement('a');
        },
        Image: (node) => {
            return document.createElement('image');
        },
        Code: (node) => {
            return document.createElement('code');
        },
        Document: (node) => {
            return document.createElement('div');
        },
        Paragraph: (node) => {
            return document.createElement('p');
        },
        BlockQuote: (node) => {
            return document.createElement('blockquote');
        },
        Item: (node) => {
            return document.createElement('li');
        },
        List: (node) => {
            return document.createElement(
                node.listType == 'Bullet' ? 'ul' : 'ol');
        },
        Header: (node) => {
            return document.createElement('h' + node.level);
        },
        CodeBlock: (node) => {
            var text = document.createTextNode('');
            var code = document.createElement('code');
            var pre = document.createElement('pre');
            code.appendChild(text);
            pre.appendChild(code);
            return pre;
        },
        HtmlBlock: (node) => {
            return document.createElement('div');
        },
        HorizontalRule: (node) => {
            return document.createElement('hr');
        }
    };
    this.onUpdate = {
        Text: (node) => {
            node.dom.textContent = node.literal;
        },
        Html: (node) => {
            console.warn('raw html is not supported');
            node.dom.textContent = node.literal;
        },
        Link: (node) => {
            node.dom.setAttribute('href', node.destination);
            if (node.title) {
                node.dom.setAttribute('title', node.title);
            }
        },
        Image: (node) => {
            node.dom.setAttribute('src', node.destination);
            if (node.title) {
                node.dom.setAttribute('title', node.title);
            }
        },
        Code: (node) => {
            node.dom.textContent = node.literal;
        },
        List: (node) => {
            if (node.listStart != null &&
                node.listStart != 1) {
                node.dom.setAttribute(
                    'start',
                    node.listStart.toString());
            }
        },
        CodeBlock: (node) => {
            node.dom.textContent = node.literal;
        },
        HtmlBlock: (node) => {
            console.warn('raw html block is not supported');
            node.dom.textContent = node.literal;
        }
    };
    this.specialRules = {
        Image: (node, dom) => {
            var buf = [];
            forEachChild(node, (child) => {
                buf.push(this.create(child).textContent);
            });
            dom.setAttribute('alt', buf.join(''));
        }
    };
};

Creator.prototype.create = function(node) {
    var dom = node.dom = this.creators[node.type](node);
    if (this.onUpdate[node.type]) {
        this.onUpdate[node.type](node, dom);
    }
    if (this.specialRules[node.type]) {
        this.specialRules[node.type](node, dom);
    } else {
        forEachChild(node, (child) => {
            node.dom.appendChild(this.create(child));
        });
    }
    return dom;
};

Creator.prototype._update = function(node1, node2) {
    if (node1.hashCode == node2.hashCode) {
        throw 'hashCode must be difference';
    }
    var dom = node2.dom = node1.dom;
    if (node1.attrHashCode != node2.attrHashCode) {
        if (node1.type != node2.type
            || (node1.type == 'List'
                && node1.listType != node2.listType)
            || (node1.type == 'Header'
                && node1.level != node2.level)) {
            node2.dom = this.create(node2);
            return node2.dom;
        }
        if (this.onUpdate[node2.type]) {
            this.onUpdate[node2.type](node2, node1.dom);
        }
    }
    if (node1.childrenHashCode != node2.childrenHashCode) {
        if (this.specialRules[node2.type]) {
            this.specialRules[node2.type](node2, dom);
        } else {
            this._updateChildren(node1, node2);
        }
    }
    return dom;
};

Creator.prototype._updateChildren = function(node1, node2) {
    var dom = node2.dom;
    var c1l = node1.firstChild, c2l = node2.firstChild,
        c1l_next, c2l_next;
    while (c1l != null && c2l != null
           && c1l.hashCode == c2l.hashCode) {
        c1l_next = c1l.next, c2l_next = c2l.next;
        c2l.insertBefore(c1l);
        c2l.unlink();
        c1l = c1l_next, c2l = c2l_next;
    }
    c1l = (c1l != null ? c1l.prev : node1.lastChild);
    c2l = (c2l != null ? c2l.prev : node2.lastChild);
    var c1r = node1.lastChild, c2r = node2.lastChild,
        c1r_prev, c2r_prev;
    while (c1l != c1r && c2l != c2r &&
           c1r.hashCode == c2r.hashCode) {
        c1r_prev = c1r.prev, c2r_prev = c2r.prev;
        c2r.insertAfter(c1r);
        c2r.unlink();
        c1r = c1r_prev, c2r = c2r_prev;
    }
    while (c1l != c1r && c2l != c2r) {
        c1r_prev = c1r.prev, c2r_prev = c2r.prev;
        if (c1r.hashCode != c2r.hashCode) {
            this._update(c1r, c2r);
            if (c2r.dom != c1r.dom) {
                dom.replaceChild(c2r.dom, c1r.dom);
            }
        } else {
            c2r.insertAfter(c1r);
            c2r.unlink();
        }
        c1r = c1r_prev, c2r = c2r_prev;
    }
    while (c2l != c2r) {
        this.create(c2r);
        if (c2l == null) {
            dom.insertBefore(c2r.dom, dom.firstChild);
        } else {
            dom.insertBefore(c2r.dom, c2l.dom.nextSibling);
        }
        c2r = c2r.prev;
    }
    while (c1l != c1r) {
        dom.removeChild(c1r.dom);
        c1r = c1r.prev;
    }
};

Creator.prototype.update = function(tree) {
    if (this.tree != null && this.tree.hashCode == null) {
        calcHash(this.tree);
    }
    console.time('hash');
    calcHash(tree);
    console.timeEnd('hash');
    if (this.tree == null) {
        this.create(tree);
    } else if (this.tree.hashCode == tree.hashCode) {
        tree = this.tree;
    } else {
        this._update(this.tree, tree);
    }
    this.tree = tree;
    return this.tree.dom;
};
module.exports = Creator;
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import * as Common from '../common/common.js';

/**
 * @unrestricted
 */
import {InspectorFrontendHostInstance} from './InspectorFrontendHost.js';

export class UserMetrics {
  constructor() {
    this._panelChangedSinceLaunch = false;
    this._firedLaunchHistogram = false;
    this._launchPanelName = '';
  }

  /**
   * @param {string} panelName
   */
  panelShown(panelName) {
    const code = PanelCodes[panelName] || 0;
    const size = Object.keys(PanelCodes).length + 1;
    InspectorFrontendHostInstance.recordEnumeratedHistogram('DevTools.PanelShown', code, size);
    Common.EventTarget.fireEvent('DevTools.PanelShown', {value: code});
    // Store that the user has changed the panel so we know launch histograms should not be fired.
    this._panelChangedSinceLaunch = true;
  }

  /**
   * @param {string} drawerId
   */
  drawerShown(drawerId) {
    this.panelShown('drawer-' + drawerId);
  }

  /**
   * @param {string} settingsViewId
   */
  settingsPanelShown(settingsViewId) {
    this.panelShown('settings-' + settingsViewId);
  }

  /**
   * @param {!Action} action
   */
  actionTaken(action) {
    const size = Object.keys(Action).length + 1;
    InspectorFrontendHostInstance.recordEnumeratedHistogram('DevTools.ActionTaken', action, size);
    Common.EventTarget.fireEvent('DevTools.ActionTaken', {value: action});
  }

  /**
   * @param {string} panelName
   * @param {string} histogramName
   * @suppressGlobalPropertiesCheck
   */
  panelLoaded(panelName, histogramName) {
    if (this._firedLaunchHistogram || panelName !== this._launchPanelName) {
      return;
    }

    this._firedLaunchHistogram = true;
    // Use rAF and setTimeout to ensure the marker is fired after layout and rendering.
    // This will give the most accurate representation of the tool being ready for a user.
    requestAnimationFrame(() => {
      setTimeout(() => {
        // Mark the load time so that we can pinpoint it more easily in a trace.
        performance.mark(histogramName);
        // If the user has switched panel before we finished loading, ignore the histogram,
        // since the launch timings will have been affected and are no longer valid.
        if (this._panelChangedSinceLaunch) {
          return;
        }
        // This fires the event for the appropriate launch histogram.
        // The duration is measured as the time elapsed since the time origin of the document.
        InspectorFrontendHostInstance.recordPerformanceHistogram(histogramName, performance.now());
        Common.EventTarget.fireEvent('DevTools.PanelLoaded', {value: {panelName, histogramName}});
      }, 0);
    });
  }

  /**
   * @param {?string} panelName
   */
  setLaunchPanel(panelName) {
    // Store the panel name that we should use for the launch histogram.
    // Other calls to panelLoaded will be ignored if the name does not match the one set here.
    this._launchPanelName = /** @type {string} */ (panelName);
  }

  /**
   * @param {string} actionId
   */
  keyboardShortcutFired(actionId) {
    const size = Object.keys(KeyboardShortcutAction).length + 1;
    const action = KeyboardShortcutAction[actionId] || KeyboardShortcutAction.OtherShortcut;
    InspectorFrontendHostInstance.recordEnumeratedHistogram('DevTools.KeyboardShortcutFired', action, size);
    Common.EventTarget.fireEvent('DevTools.KeyboardShortcutFired', {value: action});
  }

  /**
   * @param {!IssueOpener} issueOpener
   */
  issuesPanelOpenedFrom(issueOpener) {
    const size = Object.keys(IssueOpener).length + 1;
    InspectorFrontendHostInstance.recordEnumeratedHistogram('DevTools.IssuesPanelOpenedFrom', issueOpener, size);
    Common.EventTarget.fireEvent('DevTools.IssuesPanelOpenedFrom', {value: issueOpener});
  }
}

// Codes below are used to collect UMA histograms in the Chromium port.
// Do not change the values below, additional actions are needed on the Chromium side
// in order to add more codes.

/** @enum {number} */
export const Action = {
  WindowDocked: 1,
  WindowUndocked: 2,
  ScriptsBreakpointSet: 3,
  TimelineStarted: 4,
  ProfilesCPUProfileTaken: 5,
  ProfilesHeapProfileTaken: 6,
  // Keep key around because length of object is important. See Host.UserMetrics.actionTaken.
  'LegacyAuditsStarted-deprecated': 7,
  ConsoleEvaluated: 8,
  FileSavedInWorkspace: 9,
  DeviceModeEnabled: 10,
  AnimationsPlaybackRateChanged: 11,
  RevisionApplied: 12,
  FileSystemDirectoryContentReceived: 13,
  StyleRuleEdited: 14,
  CommandEvaluatedInConsolePanel: 15,
  DOMPropertiesExpanded: 16,
  ResizedViewInResponsiveMode: 17,
  TimelinePageReloadStarted: 18,
  ConnectToNodeJSFromFrontend: 19,
  ConnectToNodeJSDirectly: 20,
  CpuThrottlingEnabled: 21,
  CpuProfileNodeFocused: 22,
  CpuProfileNodeExcluded: 23,
  SelectFileFromFilePicker: 24,
  SelectCommandFromCommandMenu: 25,
  ChangeInspectedNodeInElementsPanel: 26,
  StyleRuleCopied: 27,
  CoverageStarted: 28,
  LighthouseStarted: 29,
  LighthouseFinished: 30,
  ShowedThirdPartyBadges: 31,
  LighthouseViewTrace: 32,
  FilmStripStartedRecording: 33,
  CoverageReportFiltered: 34,
  CoverageStartedPerBlock: 35,
  SettingsOpenedFromGear: 36,
  SettingsOpenedFromMenu: 37,
  SettingsOpenedFromCommandMenu: 38
};

/** @type {!Object<string, number>} */
export const PanelCodes = {
  elements: 1,
  resources: 2,
  network: 3,
  sources: 4,
  timeline: 5,
  heap_profiler: 6,
  // Keep key around because length of object is important. See Host.UserMetrics.panelShown.
  'legacy-audits-deprecated': 7,
  console: 8,
  layers: 9,
  'drawer-console-view': 10,
  'drawer-animations': 11,
  'drawer-network.config': 12,
  'drawer-rendering': 13,
  'drawer-sensors': 14,
  'drawer-sources.search': 15,
  security: 16,
  js_profiler: 17,
  lighthouse: 18,
  'drawer-coverage': 19,
  'drawer-protocol-monitor': 20,
  'drawer-remote-devices': 21,
  'drawer-web-audio': 22,
  'drawer-changes.changes': 23,
  'drawer-performance.monitor': 24,
  'drawer-release-note': 25,
  'drawer-live_heap_profile': 26,
  'drawer-sources.quick': 27,
  'drawer-network.blocked-urls': 28,
  'settings-preferences': 29,
  'settings-workspace': 30,
  'settings-experiments': 31,
  'settings-blackbox': 32,
  'settings-devices': 33,
  'settings-throttling-conditions': 34,
  'settings-emulation-geolocations': 35,
  'settings-shortcuts': 36,
  'drawer-issues-pane': 37
};

/** @type {!Object<string, number>} */
export const KeyboardShortcutAction = {
  OtherShortcut: 0,
  'commandMenu.show': 1,
  'console.clear': 2,
  'console.show': 3,
  'debugger.step': 4,
  'debugger.step-into': 5,
  'debugger.step-out': 6,
  'debugger.step-over': 7,
  'debugger.toggle-breakpoint': 8,
  'debugger.toggle-breakpoint-enabled': 9,
  'debugger.toggle-pause': 10,
  'elements.edit-as-html': 11,
  'elements.hide-element': 12,
  'elements.redo': 13,
  'elements.toggle-element-search': 14,
  'elements.undo': 15,
  'main.search-in-panel.find': 16,
  'main.toggle-drawer': 17,
  'network.hide-request-details': 18,
  'network.search': 19,
  'network.toggle-recording': 20,
  'quickOpen.show': 21,
  'settings.show': 22,
  'sources.search': 23,
};

/** @enum {number} */
export const IssueOpener = {
  ConsoleInfoBar: 0,
  LearnMoreLinkCOEP: 1,
  StatusBarIssuesCounter: 2,
  HamburgerMenu: 3,
  Adorner: 4
};
<commit_msg>Add experimental shortcuts tab to PanelCodes<commit_after>/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import * as Common from '../common/common.js';

/**
 * @unrestricted
 */
import {InspectorFrontendHostInstance} from './InspectorFrontendHost.js';

export class UserMetrics {
  constructor() {
    this._panelChangedSinceLaunch = false;
    this._firedLaunchHistogram = false;
    this._launchPanelName = '';
  }

  /**
   * @param {string} panelName
   */
  panelShown(panelName) {
    const code = PanelCodes[panelName] || 0;
    const size = Object.keys(PanelCodes).length + 1;
    InspectorFrontendHostInstance.recordEnumeratedHistogram('DevTools.PanelShown', code, size);
    Common.EventTarget.fireEvent('DevTools.PanelShown', {value: code});
    // Store that the user has changed the panel so we know launch histograms should not be fired.
    this._panelChangedSinceLaunch = true;
  }

  /**
   * @param {string} drawerId
   */
  drawerShown(drawerId) {
    this.panelShown('drawer-' + drawerId);
  }

  /**
   * @param {string} settingsViewId
   */
  settingsPanelShown(settingsViewId) {
    this.panelShown('settings-' + settingsViewId);
  }

  /**
   * @param {!Action} action
   */
  actionTaken(action) {
    const size = Object.keys(Action).length + 1;
    InspectorFrontendHostInstance.recordEnumeratedHistogram('DevTools.ActionTaken', action, size);
    Common.EventTarget.fireEvent('DevTools.ActionTaken', {value: action});
  }

  /**
   * @param {string} panelName
   * @param {string} histogramName
   * @suppressGlobalPropertiesCheck
   */
  panelLoaded(panelName, histogramName) {
    if (this._firedLaunchHistogram || panelName !== this._launchPanelName) {
      return;
    }

    this._firedLaunchHistogram = true;
    // Use rAF and setTimeout to ensure the marker is fired after layout and rendering.
    // This will give the most accurate representation of the tool being ready for a user.
    requestAnimationFrame(() => {
      setTimeout(() => {
        // Mark the load time so that we can pinpoint it more easily in a trace.
        performance.mark(histogramName);
        // If the user has switched panel before we finished loading, ignore the histogram,
        // since the launch timings will have been affected and are no longer valid.
        if (this._panelChangedSinceLaunch) {
          return;
        }
        // This fires the event for the appropriate launch histogram.
        // The duration is measured as the time elapsed since the time origin of the document.
        InspectorFrontendHostInstance.recordPerformanceHistogram(histogramName, performance.now());
        Common.EventTarget.fireEvent('DevTools.PanelLoaded', {value: {panelName, histogramName}});
      }, 0);
    });
  }

  /**
   * @param {?string} panelName
   */
  setLaunchPanel(panelName) {
    // Store the panel name that we should use for the launch histogram.
    // Other calls to panelLoaded will be ignored if the name does not match the one set here.
    this._launchPanelName = /** @type {string} */ (panelName);
  }

  /**
   * @param {string} actionId
   */
  keyboardShortcutFired(actionId) {
    const size = Object.keys(KeyboardShortcutAction).length + 1;
    const action = KeyboardShortcutAction[actionId] || KeyboardShortcutAction.OtherShortcut;
    InspectorFrontendHostInstance.recordEnumeratedHistogram('DevTools.KeyboardShortcutFired', action, size);
    Common.EventTarget.fireEvent('DevTools.KeyboardShortcutFired', {value: action});
  }

  /**
   * @param {!IssueOpener} issueOpener
   */
  issuesPanelOpenedFrom(issueOpener) {
    const size = Object.keys(IssueOpener).length + 1;
    InspectorFrontendHostInstance.recordEnumeratedHistogram('DevTools.IssuesPanelOpenedFrom', issueOpener, size);
    Common.EventTarget.fireEvent('DevTools.IssuesPanelOpenedFrom', {value: issueOpener});
  }
}

// Codes below are used to collect UMA histograms in the Chromium port.
// Do not change the values below, additional actions are needed on the Chromium side
// in order to add more codes.

/** @enum {number} */
export const Action = {
  WindowDocked: 1,
  WindowUndocked: 2,
  ScriptsBreakpointSet: 3,
  TimelineStarted: 4,
  ProfilesCPUProfileTaken: 5,
  ProfilesHeapProfileTaken: 6,
  // Keep key around because length of object is important. See Host.UserMetrics.actionTaken.
  'LegacyAuditsStarted-deprecated': 7,
  ConsoleEvaluated: 8,
  FileSavedInWorkspace: 9,
  DeviceModeEnabled: 10,
  AnimationsPlaybackRateChanged: 11,
  RevisionApplied: 12,
  FileSystemDirectoryContentReceived: 13,
  StyleRuleEdited: 14,
  CommandEvaluatedInConsolePanel: 15,
  DOMPropertiesExpanded: 16,
  ResizedViewInResponsiveMode: 17,
  TimelinePageReloadStarted: 18,
  ConnectToNodeJSFromFrontend: 19,
  ConnectToNodeJSDirectly: 20,
  CpuThrottlingEnabled: 21,
  CpuProfileNodeFocused: 22,
  CpuProfileNodeExcluded: 23,
  SelectFileFromFilePicker: 24,
  SelectCommandFromCommandMenu: 25,
  ChangeInspectedNodeInElementsPanel: 26,
  StyleRuleCopied: 27,
  CoverageStarted: 28,
  LighthouseStarted: 29,
  LighthouseFinished: 30,
  ShowedThirdPartyBadges: 31,
  LighthouseViewTrace: 32,
  FilmStripStartedRecording: 33,
  CoverageReportFiltered: 34,
  CoverageStartedPerBlock: 35,
  SettingsOpenedFromGear: 36,
  SettingsOpenedFromMenu: 37,
  SettingsOpenedFromCommandMenu: 38
};

/** @type {!Object<string, number>} */
export const PanelCodes = {
  elements: 1,
  resources: 2,
  network: 3,
  sources: 4,
  timeline: 5,
  heap_profiler: 6,
  // Keep key around because length of object is important. See Host.UserMetrics.panelShown.
  'legacy-audits-deprecated': 7,
  console: 8,
  layers: 9,
  'drawer-console-view': 10,
  'drawer-animations': 11,
  'drawer-network.config': 12,
  'drawer-rendering': 13,
  'drawer-sensors': 14,
  'drawer-sources.search': 15,
  security: 16,
  js_profiler: 17,
  lighthouse: 18,
  'drawer-coverage': 19,
  'drawer-protocol-monitor': 20,
  'drawer-remote-devices': 21,
  'drawer-web-audio': 22,
  'drawer-changes.changes': 23,
  'drawer-performance.monitor': 24,
  'drawer-release-note': 25,
  'drawer-live_heap_profile': 26,
  'drawer-sources.quick': 27,
  'drawer-network.blocked-urls': 28,
  'settings-preferences': 29,
  'settings-workspace': 30,
  'settings-experiments': 31,
  'settings-blackbox': 32,
  'settings-devices': 33,
  'settings-throttling-conditions': 34,
  'settings-emulation-geolocations': 35,
  'settings-shortcuts': 36,
  'drawer-issues-pane': 37,
  'settings-keybinds': 38
};

/** @type {!Object<string, number>} */
export const KeyboardShortcutAction = {
  OtherShortcut: 0,
  'commandMenu.show': 1,
  'console.clear': 2,
  'console.show': 3,
  'debugger.step': 4,
  'debugger.step-into': 5,
  'debugger.step-out': 6,
  'debugger.step-over': 7,
  'debugger.toggle-breakpoint': 8,
  'debugger.toggle-breakpoint-enabled': 9,
  'debugger.toggle-pause': 10,
  'elements.edit-as-html': 11,
  'elements.hide-element': 12,
  'elements.redo': 13,
  'elements.toggle-element-search': 14,
  'elements.undo': 15,
  'main.search-in-panel.find': 16,
  'main.toggle-drawer': 17,
  'network.hide-request-details': 18,
  'network.search': 19,
  'network.toggle-recording': 20,
  'quickOpen.show': 21,
  'settings.show': 22,
  'sources.search': 23,
};

/** @enum {number} */
export const IssueOpener = {
  ConsoleInfoBar: 0,
  LearnMoreLinkCOEP: 1,
  StatusBarIssuesCounter: 2,
  HamburgerMenu: 3,
  Adorner: 4
};
<|endoftext|>


<commit_before>'use strict';

const changeCase = require('change-case');
const http = require('http');
const Koa = require('koa');
const auth = require('koa-basic-auth');
const bodyParser = require('koa-bodyparser');
const Router = require('koa-router');
const logger = require('winston');

const basicAuthCustom401 = require('../web/middleware/basicAuthCustom401');
const generateRequestId = require('../web/middleware/generateRequestId');
const BlinkApp = require('./BlinkApp');
const ApiWebController = require('../web/controllers/ApiWebController');
const ToolsWebController = require('../web/controllers/ToolsWebController');
const WebHooksWebController = require('../web/controllers/WebHooksWebController');

class BlinkWebApp extends BlinkApp {
  constructor(config) {
    super(config);
    this.web = {};

    // Dynamically create and assign controllers.
    this.web.controllers = this.initControllers([
      ApiWebController,
      ToolsWebController,
      WebHooksWebController,
    ]);

    // Define routing.
    this.web.router = this.initRouter();

    // Configure web sever.
    this.web.app = this.initWebApp();
  }

  initRouter() {
    // Define controller shortcuts for convenience.
    const {
      apiWebController,
      toolsWebController,
      webHooksWebController,
    } = this.web.controllers;

    const router = new Router();
    router.get('root', '/', apiWebController.welcome);
    router.get('api.v1', '/api/v1', apiWebController.v1);
    router.get('api.index', '/api', apiWebController.index);
    router.get('api.v1', '/api/v1', apiWebController.v1);
    router.get('api.v1.tools', '/api/v1/tools', toolsWebController.index);
    router.post('api.v1.tools.fetch', '/api/v1/tools/fetch', toolsWebController.fetch);
    router.get('api.v1.webhooks', '/api/v1/webhooks', webHooksWebController.index);
    router.post('api.v1.webhooks.customerio', '/api/v1/webhooks/customerio', webHooksWebController.customerio);
    return router;
  }

  initControllers(controllerClasses) {
    const controllerMapping = {};
    controllerClasses.forEach((controllerClass, i) => {
      // Construct new controller.
      const controller = new controllerClasses[i](this);
      // Use camelcased controller name as a map key.
      const mappingKey = changeCase.camelCase(controllerClass.name);
      // Add worker to mapping
      controllerMapping[mappingKey] = controller;
    });
    return controllerMapping;
  }

  initWebApp() {
    const app = new Koa();

    // Setup web app env from local config.
    // https://github.com/koajs/koa/blob/master/docs/api/index.md#settings
    app.env = this.config.app.env;

    // Web proxy
    // https://github.com/koajs/koa/blob/master/docs/api/index.md#settings
    app.proxy = this.config.web.proxy;

    // -------- Setup web middleware --------
    // Parse incoming request bodies in a middleware before your handlers,
    // available under the req.body property.
    app.use(bodyParser());

    // Generate unique request id.
    app.use(generateRequestId);

    // Basic Authentication:
    // Custom 401 handling.
    // https://github.com/koajs/basic-auth#example
    app.use(basicAuthCustom401);
    // Enable auth.
    app.use(auth({
      name: this.config.app.auth.name,
      pass: this.config.app.auth.password,
    }));

    // Inject Koa Router routes and allowed methods.
    app.use(this.web.router.routes());
    app.use(this.web.router.allowedMethods());
    return app;
  }

  async start() {
    await super.start();
    // Start HTTP server
    this.web.server = http.createServer(this.web.app.callback());
    this.web.server.listen(
      this.config.web.bind_port,
      this.config.web.bind_address,
      () => {
        const address = this.web.server.address();
        // TODO: Make sure random port setting gets overriden with actual resolved port.
        logger.info(
          `Blink Web is listening on http://${this.config.web.hostname}:${address.port} env:${this.config.app.env}`
        );
      }
    );
    // TODO: HTTPS?
  }

  async stop() {
    await super.stop();
    const address = this.web.server.address();
    this.web.server.close(() => {
      logger.info(`Blink Web is stopped http://${this.config.web.hostname}:${address.port} env:${this.config.app.env}.`);
    });
  }

}

module.exports = BlinkWebApp;
<commit_msg>Log web start and stop<commit_after>'use strict';

const changeCase = require('change-case');
const http = require('http');
const Koa = require('koa');
const auth = require('koa-basic-auth');
const bodyParser = require('koa-bodyparser');
const Router = require('koa-router');
const logger = require('winston');

const basicAuthCustom401 = require('../web/middleware/basicAuthCustom401');
const generateRequestId = require('../web/middleware/generateRequestId');
const BlinkApp = require('./BlinkApp');
const ApiWebController = require('../web/controllers/ApiWebController');
const ToolsWebController = require('../web/controllers/ToolsWebController');
const WebHooksWebController = require('../web/controllers/WebHooksWebController');

class BlinkWebApp extends BlinkApp {
  constructor(config) {
    super(config);
    this.web = {};

    // Dynamically create and assign controllers.
    this.web.controllers = this.initControllers([
      ApiWebController,
      ToolsWebController,
      WebHooksWebController,
    ]);

    // Define routing.
    this.web.router = this.initRouter();

    // Configure web sever.
    this.web.app = this.initWebApp();
  }

  initRouter() {
    // Define controller shortcuts for convenience.
    const {
      apiWebController,
      toolsWebController,
      webHooksWebController,
    } = this.web.controllers;

    const router = new Router();
    router.get('root', '/', apiWebController.welcome);
    router.get('api.v1', '/api/v1', apiWebController.v1);
    router.get('api.index', '/api', apiWebController.index);
    router.get('api.v1', '/api/v1', apiWebController.v1);
    router.get('api.v1.tools', '/api/v1/tools', toolsWebController.index);
    router.post('api.v1.tools.fetch', '/api/v1/tools/fetch', toolsWebController.fetch);
    router.get('api.v1.webhooks', '/api/v1/webhooks', webHooksWebController.index);
    router.post('api.v1.webhooks.customerio', '/api/v1/webhooks/customerio', webHooksWebController.customerio);
    return router;
  }

  initControllers(controllerClasses) {
    const controllerMapping = {};
    controllerClasses.forEach((controllerClass, i) => {
      // Construct new controller.
      const controller = new controllerClasses[i](this);
      // Use camelcased controller name as a map key.
      const mappingKey = changeCase.camelCase(controllerClass.name);
      // Add worker to mapping
      controllerMapping[mappingKey] = controller;
    });
    return controllerMapping;
  }

  initWebApp() {
    const app = new Koa();

    // Setup web app env from local config.
    // https://github.com/koajs/koa/blob/master/docs/api/index.md#settings
    app.env = this.config.app.env;

    // Web proxy
    // https://github.com/koajs/koa/blob/master/docs/api/index.md#settings
    app.proxy = this.config.web.proxy;

    // -------- Setup web middleware --------
    // Parse incoming request bodies in a middleware before your handlers,
    // available under the req.body property.
    app.use(bodyParser());

    // Generate unique request id.
    app.use(generateRequestId);

    // Basic Authentication:
    // Custom 401 handling.
    // https://github.com/koajs/basic-auth#example
    app.use(basicAuthCustom401);
    // Enable auth.
    app.use(auth({
      name: this.config.app.auth.name,
      pass: this.config.app.auth.password,
    }));

    // Inject Koa Router routes and allowed methods.
    app.use(this.web.router.routes());
    app.use(this.web.router.allowedMethods());
    return app;
  }

  async start() {
    await super.start();
    // Start HTTP server
    this.web.server = http.createServer(this.web.app.callback());
    this.web.server.listen(
      this.config.web.bind_port,
      this.config.web.bind_address,
      () => {
        const address = this.web.server.address();
        // TODO: Make sure random port setting gets overriden with actual resolved port.

        // TODO: log process name
        const meta = {
          host: this.config.web.hostname,
          protocol: 'http',
          env: this.config.app.env,
          port: address.port,
          code: 'web_started',
        };

        const readableUrl = `http://${this.config.web.hostname}:${address.port}`;
        logger.info(`Blink Web is listening on ${readableUrl}`, meta);
      }
    );
    // TODO: HTTPS?
  }

  async stop() {
    await super.stop();
    const address = this.web.server.address();
    this.web.server.close(() => {

      // TODO: log process name
      const meta = {
        host: this.config.web.hostname,
        protocol: 'http',
        env: this.config.app.env,
        port: address.port,
        code: 'web_stopped',
      };

      logger.info(`Blink Web is stopped`, meta);
    });
  }

}

module.exports = BlinkWebApp;
<|endoftext|>


<commit_before>'use strict';

var path = require('path'),
    Til = require('./til'),
    dunConfig = require('./config/dun_info');

/**
 * DUN files contain information for arranging the squares of a TIL file.
 * Multiple DUN files can be pieced together to form entire levels.
 * For example, the 'town' level is a combination of 4 DUN files.
 *
 * In addition, DUN files also provide information regarding dungeon
 * monsters and object ids.
 */
function DunFile(startCoord, pillarData, dunName) {
    this.startCol = startCoord[0];
    this.startRow = startCoord[1];
    this.pillarData = pillarData;
    this.fileName = dunName;

    this.colCount = this.pillarData.length;
    this.rowCount = (this.colCount > 0) ? this.pillarData[0].length : 0;
}

function getStartCoord(dunName) {
    var startCoord = dunConfig[dunName];
    if (typeof startCoord == 'undefined') {
        console.error('Unhandled DUN file: ' + dunName);
        return [0, 0];
    }

    return startCoord;
}

function _load(buffer, dunPath, tilFile) {
    var offset = 0;
    var colCount = buffer.readUInt16LE(offset);
    var rowCount = buffer.readUInt16LE(offset += 2);

    // Pre-allocate.
    var pillarData = new Array(colCount * 2);
    for (var i = 0; i < pillarData.length; i++) {
        pillarData[i] = new Array(rowCount * 2);
    }

    // Parse pillar data.
    var row = 0;
    for (i = 0; i < rowCount; i++) {
        var col = 0;
        for (var j = 0; j < colCount; j++) {
            var squareIndexPlus1 = buffer.readUInt16LE(offset += 2);
            if (squareIndexPlus1 !== 0) {
                var square = tilFile.squares[squareIndexPlus1 - 1];

                pillarData[col][row] = square[Til.SQUARE_TOP];
                pillarData[col + 1][row] = square[Til.SQUARE_RIGHT];
                pillarData[col][row + 1] = square[Til.SQUARE_LEFT];
                pillarData[col + 1][row + 1] = square[Til.SQUARE_BOTTOM];
            } else {
                pillarData[col][row] = null;
                pillarData[col + 1][row] = null;
                pillarData[col][row + 1] = null;
                pillarData[col + 1][row + 1] = null;
            }

            col += 2;
        }
        row += 2;
    }

    // levels/towndata/sector1s.dun -> sector1s
    var dunName = path.basename(dunPath, '.dun');
    var startCoord = getStartCoord(dunName);

    return new DunFile(startCoord, pillarData, dunName);
}

module.exports = {
    load: _load
};
<commit_msg>Add 'unpack' operation to DUN file to remove dependency on TIL for loading.<commit_after>'use strict';

var path = require('path'),
    Til = require('./til'),
    dunConfig = require('./config/dun_info');

/**
 * DUN files contain information for arranging the squares of a TIL file.
 * Multiple DUN files can be pieced together to form entire levels.
 * For example, the 'town' level is a combination of 4 DUN files.
 *
 * In addition, DUN files also provide information regarding dungeon
 * monsters and object ids.
 */
function DunFile(startCoord, rawPillarData, dunName) {
    this.startCol = startCoord[0];
    this.startRow = startCoord[1];
    this.fileName = dunName;

    this.rawPillarData = rawPillarData;
    this.rawColCount = this.rawPillarData.length;
    this.rawRowCount = (this.rawColCount > 0) ? this.rawPillarData[0].length : 0;

    this.pillarData = null;     // Initialized during unpack operation.
    this.colCount = this.rawColCount * 2;
    this.rowCount = this.rawRowCount * 2;
}

/**
 * Unpacks the pillar data of the DUN file using the TIL file to perform
 * square index lookups. DUN file can be used without unpacking, but
 * this operation will convert it to an easier to use format.
 */
DunFile.prototype.unpack = function(tilFile) {
    // Already unpacked?
    if (this.pillarData !== null) {
        return;
    }

    // Pre-allocate.
    this.pillarData = new Array(this.colCount);
    for (var i = 0; i < this.pillarData.length; i++) {
        this.pillarData[i] = new Array(this.rowCount);
    }

    // Parse pillar data.
    var row = 0;
    for (i = 0; i < this.rawRowCount; i++) {
        var col = 0;
        for (var j = 0; j < this.rawColCount; j++) {
            var squareIndexPlus1 = this.rawPillarData[j][i];
            if (squareIndexPlus1 !== 0) {
                var square = tilFile.squares[squareIndexPlus1 - 1];

                this.pillarData[col][row] = square[Til.SQUARE_TOP];
                this.pillarData[col + 1][row] = square[Til.SQUARE_RIGHT];
                this.pillarData[col][row + 1] = square[Til.SQUARE_LEFT];
                this.pillarData[col + 1][row + 1] = square[Til.SQUARE_BOTTOM];
            } else {
                this.pillarData[col][row] = null;
                this.pillarData[col + 1][row] = null;
                this.pillarData[col][row + 1] = null;
                this.pillarData[col + 1][row + 1] = null;
            }

            col += 2;
        }
        row += 2;
    }
};

function getStartCoord(dunName) {
    var startCoord = dunConfig[dunName];
    if (typeof startCoord == 'undefined') {
        console.error('Unhandled DUN file: ' + dunName);
        return [0, 0];
    }

    return startCoord;
}

function _load(buffer, dunPath) {
    var offset = 0;
    var colCount = buffer.readUInt16LE(offset);
    var rowCount = buffer.readUInt16LE(offset += 2);

    // Pre-allocate.
    var rawPillarData = new Array(colCount);
    for (var i = 0; i < rawPillarData.length; i++) {
        rawPillarData[i] = new Array(rowCount);
    }

    // Parse pillar data.
    for (i = 0; i < rowCount; i++) {
        for (var j = 0; j < colCount; j++) {
            rawPillarData[j][i] = buffer.readUInt16LE(offset += 2);
        }
    }

    // levels/towndata/sector1s.dun -> sector1s
    var dunName = path.basename(dunPath, '.dun');
    var startCoord = getStartCoord(dunName);

    return new DunFile(startCoord, rawPillarData, dunName);
}

module.exports = {
    load: _load
};
<|endoftext|>


<commit_before>class Storage {
  constructor() {
    this.token = null
    this.user = null
  }

  doLogin(token, user) {
    this.token = token
    this.user = user
    localStorage.setItem('token', token)
    localStorage.setItem('user', JSON.stringify(user))
  }

  doLogout() {
    this.token = null
    this.user = null
    localStorage.removeItem('token')
    localStorage.removeItem('user')
  }

  getToken() {
    if (!this.token) {
      this.token = localStorage.getItem('token')
    }
    return this.token
  }

  getUser() {
    if (!this.user) {
      this.user = JSON.parse(localStorage.getItem('user'))
    }
    return this.user
  }
}

export default new Storage()
<commit_msg>do not blow up if localStorage JSON.parse fails<commit_after>class Storage {
  constructor() {
    this.token = null
    this.user = null
  }

  doLogin(token, user) {
    this.token = token
    this.user = user
    localStorage.setItem('token', token)
    localStorage.setItem('user', JSON.stringify(user))
  }

  doLogout() {
    this.token = null
    this.user = null
    localStorage.removeItem('token')
    localStorage.removeItem('user')
  }

  getToken() {
    if (!this.token) {
      this.token = localStorage.getItem('token')
    }
    return this.token
  }

  getUser() {
    if (!this.user) {
      try {
        this.user = JSON.parse(localStorage.getItem('user'))
      } catch (e) {
        this.user = null
      }
    }
    return this.user
  }
}

export default new Storage()
<|endoftext|>


<commit_before>import React, {Component} from 'react'
import request from 'superagent'
import { default as Web3 } from 'web3'
import { default as contract } from 'truffle-contract'
import CourtBuyable from '../../build/contracts/BuyableCourt.json'

import '../www/styles/Kleroterion.scss'

const TESTRPC_HOST = 'localhost'
const TESTRPC_PORT = '8545'

class Kleroterion extends Component {

  state = {
    web3: false,
    balance: 0,
    nbDispute: 0,
    disputes: null,
    buyableCourtContract: null,
    disputes: [],
    minJuryToken: 0,
  }

  componentDidMount() {
    setTimeout(() => {
      if (typeof web3 !== 'undefined') {
        // web3 = new Web3(web3.currentProvider);
        this.setState({web3: true})
        var buyableCourtContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"tokens","type":"uint256"}],"name":"activateTokensForArbitration","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"appealOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"atStake","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"disputeID","type":"uint256"},{"name":"voteA","type":"bool"}],"name":"arbitrate","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"},{"name":"r","type":"uint256"},{"name":"t","type":"uint256"}],"name":"drawnTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"penalizationOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"accounts","type":"address[]"},{"name":"disputeIDs","type":"uint256[]"}],"name":"penalizeInactiveJuries","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"activatedJuryTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"disputeID","type":"uint256"},{"name":"voteA","type":"bool"}],"name":"voteRuling","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"disputeID","type":"uint256"},{"name":"appeal","type":"uint256"},{"name":"voteID","type":"uint256"},{"name":"stakeA","type":"bool"}],"name":"getVoteStake","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"r","type":"uint256"}],"name":"createDispute","outputs":[{"name":"disputeID","type":"uint256"}],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"disputeID","type":"uint256"}],"name":"executeTokenRepartition","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"disputes","outputs":[{"name":"arbitratedContract","type":"address"},{"name":"session","type":"uint256"},{"name":"appeals","type":"uint256"},{"name":"r","type":"uint256"},{"name":"voteA","type":"uint256"},{"name":"voteB","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"partAtStakeDivisor","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"arbitralSegmentStart","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"session","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"endLastSession","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"disputeID","type":"uint256"},{"name":"account","type":"address"}],"name":"getHasVoted","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"disputeID","type":"uint256"}],"name":"untrustedExecuteRuling","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"voteOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"activationOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"disputeID","type":"uint256"},{"name":"appeal","type":"uint256"},{"name":"voteID","type":"uint256"}],"name":"getVoteAccount","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"disputeOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"disputeID","type":"uint256"},{"name":"r","type":"uint256"}],"name":"appealRuling","outputs":[],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"tokens","type":"uint256"}],"name":"activateTokensForJury","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"accounts","type":"address[]"},{"name":"disputeIDs","type":"uint256[]"}],"name":"penalizeInactiveArbitrators","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"minArbitralToken","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"activatedArbitrationTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"arbitralSession","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"disputeID","type":"uint256"}],"name":"getAppeals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"jurySegmentStart","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"executionOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"arbitralSegmentPosition","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"nextSession","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"jurySegmentEnd","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"arbitralSegmentEnd","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"buyTokens","outputs":[],"payable":true,"type":"function"},{"constant":true,"inputs":[],"name":"nbDispute","outputs":[{"name":"nb","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"jurySession","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"},{"name":"r","type":"uint256"}],"name":"drawnArbiter","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"blocked","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"jurySegmentPosition","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"minJuryToken","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"accounts","type":"address[]"},{"name":"tokens","type":"uint256[]"}],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}]);
        this.setState({buyableCourtContract})
        this.getMinJuryToken()
        this.getDisputes()
      } else {
        alert("install Metamask or use Mist")
      }
    }, 1000)
  }

  getDisputes = () => {
    this.state.buyableCourtContract
    .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
    .nbDispute({from: web3.eth.accounts[0]}, (res,err) => {
      this.setState({nbDispute: err.toNumber()})
      console.log('nbDispute :', this.state.nbDispute)
      let disputes = [...new Array(err.toNumber()).keys()]
      disputes.forEach(i => {
        this.getDispute(i, (res, errDispute) => {
          console.log('dispute', errDispute)
          this.state.buyableCourtContract
            .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
            .minJuryToken((res, errMinJuryToken) => {
              console.log('errMinJuryToken:', errMinJuryToken.toNumber())
              this.state.buyableCourtContract
                .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
                .drawnTokens(
                  web3.eth.accounts[0],
                  errDispute[3].c[0],
                  2*Math.pow(errDispute[2].c[0]) * errMinJuryToken.toNumber(),
                  {from: web3.eth.accounts[0]},
                  (res, errDisputeActive) => {
                    console.log('active dispute:', errDisputeActive.c[0])
                    this.setState(
                      {
                        disputes: [...this.state.disputes,
                        {
                          dispute: errDispute,
                          active: errDisputeActive.c[0]
                        }]
                      }
                    )
                  }
                )
            })
          })
        })
      })
}

  getDispute = (id, cb) => this.state.buyableCourtContract
    .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
    .disputes(id, {from: web3.eth.accounts[0]}, cb)// add dispute in state

  getDisputeActive = (id, cb) => this.state.buyableCourtContract
    .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
    .disputes(id, {from: web3.eth.accounts[0]}, cb)

  getBalance = () =>
    this.state.buyableCourtContract
    .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
    .balanceOf(web3.eth.accounts[0], {from: web3.eth.accounts[0]}, (res,err) => {
        this.setState({balance: isNaN(err) ? 0 : err.toNumber()/1000000000000000000})
        console.log('balance :', err)
      })

  getMinJuryToken = () => this.state.buyableCourtContract
    .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
    .minJuryToken((res,err) => this.setState({minJuryToken: err.toNumber()}))

  handleChange = field => ({ target: { value } }) => this.setState({ [field]: value })

  render() {
    return (

Kleroterion

Balance : {this.state.balance}

        {this.state.disputes.map(
          (obj, index) =>
            (

address: {obj.dispute[0]}

active: {obj.active ? 'true' : 'false'}

            )
        )}

    )
  }
}

export default Kleroterion
<commit_msg>remove use less dependancy<commit_after>import React, {Component} from 'react'
import request from 'superagent'
import { default as Web3 } from 'web3'
import { default as contract } from 'truffle-contract'

import '../www/styles/Kleroterion.scss'

const TESTRPC_HOST = 'localhost'
const TESTRPC_PORT = '8545'

class Kleroterion extends Component {

  state = {
    web3: false,
    balance: 0,
    nbDispute: 0,
    disputes: null,
    buyableCourtContract: null,
    disputes: [],
    minJuryToken: 0,
  }

  componentDidMount() {
    setTimeout(() => {
      if (typeof web3 !== 'undefined') {
        // web3 = new Web3(web3.currentProvider);
        this.setState({web3: true})
        var buyableCourtContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"tokens","type":"uint256"}],"name":"activateTokensForArbitration","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"appealOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"atStake","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"disputeID","type":"uint256"},{"name":"voteA","type":"bool"}],"name":"arbitrate","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"},{"name":"r","type":"uint256"},{"name":"t","type":"uint256"}],"name":"drawnTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"penalizationOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"accounts","type":"address[]"},{"name":"disputeIDs","type":"uint256[]"}],"name":"penalizeInactiveJuries","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"activatedJuryTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"disputeID","type":"uint256"},{"name":"voteA","type":"bool"}],"name":"voteRuling","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"disputeID","type":"uint256"},{"name":"appeal","type":"uint256"},{"name":"voteID","type":"uint256"},{"name":"stakeA","type":"bool"}],"name":"getVoteStake","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"r","type":"uint256"}],"name":"createDispute","outputs":[{"name":"disputeID","type":"uint256"}],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"disputeID","type":"uint256"}],"name":"executeTokenRepartition","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"disputes","outputs":[{"name":"arbitratedContract","type":"address"},{"name":"session","type":"uint256"},{"name":"appeals","type":"uint256"},{"name":"r","type":"uint256"},{"name":"voteA","type":"uint256"},{"name":"voteB","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"partAtStakeDivisor","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"arbitralSegmentStart","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"session","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"endLastSession","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"disputeID","type":"uint256"},{"name":"account","type":"address"}],"name":"getHasVoted","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"disputeID","type":"uint256"}],"name":"untrustedExecuteRuling","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"voteOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"activationOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"disputeID","type":"uint256"},{"name":"appeal","type":"uint256"},{"name":"voteID","type":"uint256"}],"name":"getVoteAccount","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"disputeOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"disputeID","type":"uint256"},{"name":"r","type":"uint256"}],"name":"appealRuling","outputs":[],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"tokens","type":"uint256"}],"name":"activateTokensForJury","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"accounts","type":"address[]"},{"name":"disputeIDs","type":"uint256[]"}],"name":"penalizeInactiveArbitrators","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"minArbitralToken","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"activatedArbitrationTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"arbitralSession","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"disputeID","type":"uint256"}],"name":"getAppeals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"jurySegmentStart","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"executionOpen","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"arbitralSegmentPosition","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"nextSession","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"jurySegmentEnd","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"arbitralSegmentEnd","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"buyTokens","outputs":[],"payable":true,"type":"function"},{"constant":true,"inputs":[],"name":"nbDispute","outputs":[{"name":"nb","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"jurySession","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"},{"name":"r","type":"uint256"}],"name":"drawnArbiter","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"blocked","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"jurySegmentPosition","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"minJuryToken","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"accounts","type":"address[]"},{"name":"tokens","type":"uint256[]"}],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}]);
        this.setState({buyableCourtContract})
        this.getMinJuryToken()
        this.getDisputes()
      } else {
        alert("install Metamask or use Mist")
      }
    }, 1000)
  }

  getDisputes = () => {
    this.state.buyableCourtContract
    .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
    .nbDispute({from: web3.eth.accounts[0]}, (res,err) => {
      this.setState({nbDispute: err.toNumber()})
      console.log('nbDispute :', this.state.nbDispute)
      let disputes = [...new Array(err.toNumber()).keys()]
      disputes.forEach(i => {
        this.getDispute(i, (res, errDispute) => {
          console.log('dispute', errDispute)
          this.state.buyableCourtContract
            .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
            .minJuryToken((res, errMinJuryToken) => {
              console.log('errMinJuryToken:', errMinJuryToken.toNumber())
              this.state.buyableCourtContract
                .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
                .drawnTokens(
                  web3.eth.accounts[0],
                  errDispute[3].c[0],
                  2*Math.pow(errDispute[2].c[0]) * errMinJuryToken.toNumber(),
                  {from: web3.eth.accounts[0]},
                  (res, errDisputeActive) => {
                    console.log('active dispute:', errDisputeActive.c[0])
                    this.setState(
                      {
                        disputes: [...this.state.disputes,
                        {
                          dispute: errDispute,
                          active: errDisputeActive.c[0]
                        }]
                      }
                    )
                  }
                )
            })
          })
        })
      })
}

  getDispute = (id, cb) => this.state.buyableCourtContract
    .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
    .disputes(id, {from: web3.eth.accounts[0]}, cb)// add dispute in state

  getDisputeActive = (id, cb) => this.state.buyableCourtContract
    .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
    .disputes(id, {from: web3.eth.accounts[0]}, cb)

  getBalance = () =>
    this.state.buyableCourtContract
    .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
    .balanceOf(web3.eth.accounts[0], {from: web3.eth.accounts[0]}, (res,err) => {
        this.setState({balance: isNaN(err) ? 0 : err.toNumber()/1000000000000000000})
        console.log('balance :', err)
      })

  getMinJuryToken = () => this.state.buyableCourtContract
    .at('0xc92aa8aF07aD57d023E8A2FE18175D69dDd6b02f')
    .minJuryToken((res,err) => this.setState({minJuryToken: err.toNumber()}))

  handleChange = field => ({ target: { value } }) => this.setState({ [field]: value })

  render() {
    return (

Kleroterion

Balance : {this.state.balance}

        {this.state.disputes.map(
          (obj, index) =>
            (

address: {obj.dispute[0]}

active: {obj.active ? 'true' : 'false'}

            )
        )}

    )
  }
}

export default Kleroterion
<|endoftext|>