<commit_before>// ==UserScript==
// @name        JSON generator templates
// @namespace   https://github.com/healarconr
// @description Save JSON Generator templates in the browser local storage for later use
// @include     http://www.json-generator.com/
// @version     1
// @grant       none
// @license     MIT License
// ==/UserScript==
function jsonGeneratorTemplates() {

  var templates;
  var header;
  var controls;
  var templateControls;
  var templateSelect;
  var saveButton;
  var deleteButton;
  var resetButton;

  function main() {
    templates = getTemplates();
    header = getHeader()
    controls = getControls();
    resetButton = getResetButton();

    templateControls = createTemplateControls();

    header.insertBefore(templateControls, controls);

    handleReset();
  }

  function getTemplates() {
    var templates = localStorage.getItem("templates");

    if (templates == null) {
      templates = new Array();
      setTemplates(templates);
    } else {
      templates = JSON.parse(templates);
    }

    return templates;
  }

  function setTemplates(templates) {
    templates = JSON.stringify(templates);
    localStorage.setItem("templates", templates);
  }

  function getEditor() {
    return document.getElementsByClassName("CodeMirror")[0].CodeMirror;
  }

  function getHeader() {
    return document.getElementsByTagName("header")[0];
  }

  function getControls() {
    return document.getElementsByClassName("controls")[0];
  }

  function getResetButton() {
    return document.getElementById("reset-ui");
  }

  function createTemplateControls() {
    var div = document.createElement("div");
    div.style.display = "inline-block";
    div.style.lineHeight = "31px";
    div.style.marginLeft = "7px";
    div.style.marginTop = "4px";

    templateSelect = createTemplateSelect();
    loadTemplateOptions();

    saveButton = createSaveButton();
    deleteButton = createDeleteButton();

    div.appendChild(templateSelect);
    div.appendChild(saveButton);
    div.appendChild(deleteButton);

    return div;
  }

  function createTemplateSelect() {
    var select = document.createElement("select");
    select.id = "templates";
    select.style.color = "#35383B";
    select.style.width = "100px";
    select.style.height = "27px";
    select.style.verticalAlign = "middle";
    select.addEventListener("change", changeTemplate);
    return select;
  }

  function loadTemplateOptions() {
    while (templateSelect.hasChildNodes()) {
      templateSelect.removeChild(templateSelect.lastChild);
    }

    var option = document.createElement("option");
    option.value = null;
    option.disabled = true;
    option.selected = true;
    option.appendChild(document.createTextNode("Templates"));
    templateSelect.appendChild(option);

    for (i in templates) {
      var template = templates[i];
      var option = document.createElement("option");
      option.value = template.content;
      option.appendChild(document.createTextNode(template.name));
      templateSelect.appendChild(option);
    }
  }

  function changeTemplate() {
    getEditor().setValue(templateSelect.value);
    deleteButton.disabled = false;
  }

  function createSaveButton() {
    var button = createButton();
    button.id = "save"
    button.title = "Saves the current template";
    button.appendChild(document.createTextNode("Save"));
    button.addEventListener("click", saveTemplate);
    return button;
  }

  function createButton() {
    var button = document.createElement("button");
    button.style.color = "#35383B";
    button.style.lineHeight = 1;
    button.style.fontSize = "11px";
    button.style.padding = "5px 15px";
    return button;
  }

  function saveTemplate(e) {
    e.preventDefault();

    var overwrite = false;

    if (templateSelect.selectedIndex != 0) {
      overwrite = confirm("Overwrite?");
    }

    if (overwrite) {
      var index = templateSelect.selectedIndex - 1;
      var template = templates[index];
      template.content = getEditor().getValue();
      loadTemplateOptions();
      setTemplates(templates);
    } else {
      var templateName = prompt("Template name", new Date().toLocaleString());

      if (templateName != null) {
        template = {
          "name": templateName,
          "content": getEditor().getValue()
        };

        templates.push(template);
        loadTemplateOptions();
        templateSelect.selectedIndex = templates.length;
        setTemplates(templates);
        deleteButton.disabled = false;
      }
    }
  }

  function createDeleteButton() {
    var button = createButton();
    button.id = "delete"
    button.title = "Deletes the current template";
    button.disabled = true;
    button.appendChild(document.createTextNode("Delete"));
    button.addEventListener("click", deleteTemplate);
    return button;
  }

  function deleteTemplate() {
    if (confirm("Are you sure?")) {
      var index = templateSelect.selectedIndex - 1;
      templates.splice(index, 1);
      setTemplates(templates);
      loadTemplateOptions();
      resetButton.click();
    }
  }

  function handleReset() {
    resetButton.addEventListener("click", reset);
  }

  function reset() {
    templateSelect.children[0].selected = true;
    deleteButton.disabled = true;
  }

  main();
}

jsonGeneratorTemplates();
<commit_msg>Fix template options behavior on overwrite<commit_after>// ==UserScript==
// @name        JSON generator templates
// @namespace   https://github.com/healarconr
// @description Save JSON Generator templates in the browser local storage for later use
// @include     http://www.json-generator.com/
// @version     1
// @grant       none
// @license     MIT License
// ==/UserScript==
function jsonGeneratorTemplates() {

  var templates;
  var header;
  var controls;
  var templateControls;
  var templateSelect;
  var saveButton;
  var deleteButton;
  var resetButton;

  function main() {
    templates = getTemplates();
    header = getHeader()
    controls = getControls();
    resetButton = getResetButton();

    templateControls = createTemplateControls();

    header.insertBefore(templateControls, controls);

    handleReset();
  }

  function getTemplates() {
    var templates = localStorage.getItem("templates");

    if (templates == null) {
      templates = new Array();
      setTemplates(templates);
    } else {
      templates = JSON.parse(templates);
    }

    return templates;
  }

  function setTemplates(templates) {
    templates = JSON.stringify(templates);
    localStorage.setItem("templates", templates);
  }

  function getEditor() {
    return document.getElementsByClassName("CodeMirror")[0].CodeMirror;
  }

  function getHeader() {
    return document.getElementsByTagName("header")[0];
  }

  function getControls() {
    return document.getElementsByClassName("controls")[0];
  }

  function getResetButton() {
    return document.getElementById("reset-ui");
  }

  function createTemplateControls() {
    var div = document.createElement("div");
    div.style.display = "inline-block";
    div.style.lineHeight = "31px";
    div.style.marginLeft = "7px";
    div.style.marginTop = "4px";

    templateSelect = createTemplateSelect();
    loadTemplateOptions();

    saveButton = createSaveButton();
    deleteButton = createDeleteButton();

    div.appendChild(templateSelect);
    div.appendChild(saveButton);
    div.appendChild(deleteButton);

    return div;
  }

  function createTemplateSelect() {
    var select = document.createElement("select");
    select.id = "templates";
    select.style.color = "#35383B";
    select.style.width = "100px";
    select.style.height = "27px";
    select.style.verticalAlign = "middle";
    select.addEventListener("change", changeTemplate);
    return select;
  }

  function loadTemplateOptions() {
    while (templateSelect.hasChildNodes()) {
      templateSelect.removeChild(templateSelect.lastChild);
    }

    var option = document.createElement("option");
    option.value = null;
    option.disabled = true;
    option.selected = true;
    option.appendChild(document.createTextNode("Templates"));
    templateSelect.appendChild(option);

    for (i in templates) {
      var template = templates[i];
      var option = document.createElement("option");
      option.value = template.content;
      option.appendChild(document.createTextNode(template.name));
      templateSelect.appendChild(option);
    }
  }

  function changeTemplate() {
    getEditor().setValue(templateSelect.value);
    deleteButton.disabled = false;
  }

  function createSaveButton() {
    var button = createButton();
    button.id = "save"
    button.title = "Saves the current template";
    button.appendChild(document.createTextNode("Save"));
    button.addEventListener("click", saveTemplate);
    return button;
  }

  function createButton() {
    var button = document.createElement("button");
    button.style.color = "#35383B";
    button.style.lineHeight = 1;
    button.style.fontSize = "11px";
    button.style.padding = "5px 15px";
    return button;
  }

  function saveTemplate(e) {
    e.preventDefault();

    var overwrite = false;

    if (templateSelect.selectedIndex != 0) {
      overwrite = confirm("Overwrite?");
    }

    if (overwrite) {
      var index = templateSelect.selectedIndex - 1;
      var template = templates[index];
      template.content = getEditor().getValue();
      templateSelect.options[templateSelect.selectedIndex].value = template.content;
      setTemplates(templates);
    } else {
      var templateName = prompt("Template name", new Date().toLocaleString());

      if (templateName != null) {
        template = {
          "name": templateName,
          "content": getEditor().getValue()
        };

        templates.push(template);
        loadTemplateOptions();
        templateSelect.selectedIndex = templates.length;
        setTemplates(templates);
        deleteButton.disabled = false;
      }
    }
  }

  function createDeleteButton() {
    var button = createButton();
    button.id = "delete"
    button.title = "Deletes the current template";
    button.disabled = true;
    button.appendChild(document.createTextNode("Delete"));
    button.addEventListener("click", deleteTemplate);
    return button;
  }

  function deleteTemplate() {
    if (confirm("Are you sure?")) {
      var index = templateSelect.selectedIndex - 1;
      templates.splice(index, 1);
      setTemplates(templates);
      loadTemplateOptions();
      resetButton.click();
    }
  }

  function handleReset() {
    resetButton.addEventListener("click", reset);
  }

  function reset() {
    templateSelect.children[0].selected = true;
    deleteButton.disabled = true;
  }

  main();
}

jsonGeneratorTemplates();
<|endoftext|>


<commit_before>// http://stackoverflow.com/questions/6507293/convert-xml-to-string-with-jquery
function xmlToString(xmlData) {
    var xmlString;
    if (window.ActiveXObject){
        // IE
        xmlString = xmlData.xml;
    } else {
        // Mozilla, Firefox, Opera, etc.
        xmlString = (new XMLSerializer()).serializeToString(xmlData);
    }
    return xmlString;
}

// Parse an SVG string as XML
function stringToXML(svgString) {
    // Replace any leading whitespace which will mess up XML parsing
    svgString =  svgString.replace(/^[\s\n]*/, "");

    if (!svgString) { return; }

    // Parse SVG as XML
    var svgDoc;
    try {
        svgDoc = $.parseXML(svgString);
    } catch (err) {
        alert("Unable to parse SVG")
    }

    return svgDoc;
}

// Get an SVG from the server and add a string version to textarea
// Quite inefficient as we're going to convert it back to a XML object later.
function getExampleSVG(filename) {
    $.get("examples/" + filename + ".svg", function(data) {
        $("#input-svg").val(xmlToString(data));
    });
}

// Convert string into filesize
var getFileSize = function(str) {
    var size = str.length / 1000;
    if (size > 1000) {
        return (Math.round(size / 100) / 10) + " MB";
    } else {
        return (Math.round(size * 10) / 10) + " kB";
    }
};

// Clear element with given selector and add contents
function addContentsToDiv(contents, selector) {
    var div = $(selector);

    if (div.length === 1) {
        div.empty();
        div.append(contents);
    }
};

// Get SVG string from textarea with given id
// Parse as XML and convert to jQuery object
function loadSVG(id) {
    var svgStr = $('#input-svg').val()
    var svgDoc = stringToXML(svgStr);

    if (!svgDoc) { return; }

    var jQuerySVG = $(svgDoc).children()[0];
    var svgObj = new SVG_Object(jQuerySVG);

    // Output a nicely formatted file
    svgObj.options.whitespace = 'pretty';

    // Remove ids
    svgObj.options.removeIDs = true;

    // Update interface
    $('#upload-container').hide("fast");
    $('#input-svg').val(svgObj);
    $('#output-section').show();
    $('#optimise-section').show();

    // Add SVG images
    addContentsToDiv(svgStr, '#svg-before .svg-container');
    addContentsToDiv(svgObj.toString(), '#svg-after .svg-container');

    // Add SVG information
    var filesize1 = getFileSize(svgStr);
    var filesize2 = getFileSize(svgObj.toString());
    var compression = Math.round(1000 * svgObj.toString().length / svgStr.length) / 10;
    addContentsToDiv($("
Original filesize: " + filesize1 + "
"), '#svg-before .svg-data-container');
    addContentsToDiv($("
New filesize: " + filesize2 + " (" + compression + "%)
"), '#svg-after .svg-data-container');

    // Show code of updated SVG
    $('#output-container').text(svgObj.toString());
};

$(document).ready(function() {
    $('#upload-section > h2').click(function() {
        $('#upload-container').toggle('fast');
    });

    $('#output-section').hide();
    $('#optimise-section').hide();
});<commit_msg>Show count of elements and make attributes more efficient<commit_after>// http://stackoverflow.com/questions/6507293/convert-xml-to-string-with-jquery
function xmlToString(xmlData) {
    var xmlString;
    if (window.ActiveXObject){
        // IE
        xmlString = xmlData.xml;
    } else {
        // Mozilla, Firefox, Opera, etc.
        xmlString = (new XMLSerializer()).serializeToString(xmlData);
    }
    return xmlString;
}

// Parse an SVG string as XML
function stringToXML(svgString) {
    // Replace any leading whitespace which will mess up XML parsing
    svgString =  svgString.replace(/^[\s\n]*/, "");

    if (!svgString) { return; }

    // Parse SVG as XML
    var svgDoc;
    try {
        svgDoc = $.parseXML(svgString);
    } catch (err) {
        alert("Unable to parse SVG")
    }

    return svgDoc;
}

// Get an SVG from the server and add a string version to textarea
// Quite inefficient as we're going to convert it back to a XML object later.
function getExampleSVG(filename) {
    $.get("examples/" + filename + ".svg", function(data) {
        $("#input-svg").val(xmlToString(data));
    });
}

// Convert string into filesize
var getFileSize = function(str) {
    var size = str.length / 1000;
    if (size > 1000) {
        return (Math.round(size / 100) / 10) + " MB";
    } else {
        return (Math.round(size * 10) / 10) + " kB";
    }
};

// Clear element with given selector and add contents
function addContentsToDiv(contents, selector) {
    var div = $(selector);

    if (div.length === 1) {
        div.empty();
        div.append(contents);
    }
};

// Get SVG string from textarea with given id
// Parse as XML and convert to jQuery object
function loadSVG(id) {
    var svgStringOld = $('#input-svg').val()
    var svgDoc = stringToXML(svgStringOld);

    if (!svgDoc) { return; }

    var jQuerySVG = $(svgDoc).children();
    var svgObj = new SVG_Object(jQuerySVG[0]);

    // Output a nicely formatted file
    svgObj.options.whitespace = 'pretty';

    // Remove ids
    svgObj.options.removeIDs = true;

    // Create the new SVG string
    var svgStringNew = svgObj.toString();

    // Add SVG images
    addContentsToDiv(svgStringOld, '#svg-before .svg-container');
    addContentsToDiv(svgStringNew, '#svg-after .svg-container');

    // Add SVG information
    var filesizeOld = getFileSize(svgStringOld);
    var filesizeNew = getFileSize(svgStringNew);
    var numElementslOld = jQuerySVG.find("*").length;

    var compression = Math.round(1000 * svgStringNew.length / svgStringOld.length) / 10;
    addContentsToDiv($("
Original filesize: " + filesizeOld + "
"), '#svg-before .svg-data-container');
    addContentsToDiv($("
New filesize: " + filesizeNew + " (" + compression + "%)
"), '#svg-after .svg-data-container');

    // Update interface
    $('#upload-container').hide("fast");
    $('#input-svg').val(svgObj);
    $('#output-section').show();
    $('#optimise-section').show();

    // Show code of updated SVG
    $('#output-container').text(svgStringNew);
};

$(document).ready(function() {
    $('#upload-section > h2').click(function() {
        $('#upload-container').toggle('fast');
    });

    $('#output-section').hide();
    $('#optimise-section').hide();
});<|endoftext|>


<commit_before>var endpoint = 'http://tinybrain.de:8080/tb-talk/talk.json.php';

exports.getMe = function() {
	var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'me.png');
	if (!f.exists()) return false;
	var me = f.read();
	return me.nativePath;
};

exports.saveMe = function(me) {
	if (!me) return;
	var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'me.png');
	f.write(me);
};

exports.talk = function(_args) {
	if (Ti.Network.online == false) {
		alert('We need network connectivity to chat with bot.');
		_args.onload({
			success : false
		});
	}
	var client = Ti.Network.createHTTPClient({
		onload : function() {
			try {
				_args.onload({
					success : true,
					message : JSON.parse(this.responseText).answer
				});
			} catch(E) {
				_args.onload({
					success : false,
				});
				console.log(E);
			}
		},
		onerror : function(_e) {
			alert('We need network connectivity to chat with bot.');
		}
	});
	client.open('POST', endpoint);
	client.send({
		input : _args.message
	});
};
<commit_msg>          <commit_after>var endpoint = 'http://tinybrain.de:8080/tb-talk/talk.json.php';

exports.getMe = function() {
	var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'me.png');
	if (!f.exists()) return false;
	var me = f.read();
	return me.nativePath;
};

exports.saveMe = function(me) {
	if (!me) return;
	var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'me.png');
	f.write(me);
};

exports.talk = function(_args) {
	if (Ti.Network.online == false) {
		alert('We need network connectivity to chat with bot.');
		_args.onload({
			success : false
		});
	}
	var client = Ti.Network.createHTTPClient({
		onload : function() {
			try {
				_args.onload({
					success : true,
					message : JSON.parse(this.responseText).answer
				});
			} catch(E) {
				_args.onload({
					success : false,
				});
				console.log(E);
			}
		},
		onerror : function(_e) {
			alert('We need network connectivity to chat with bot.');
		}
	});
	client.open('POST', endpoint);
	client.send({
		input : _args.message
	});
};<|endoftext|>


<commit_before>// This file exports the common packages required by the Admin UI.

// It is used to build /public/js/packages.js, and exclude these packages from
// the Admin UI bundle generated by browserify.

module.exports = [
	'async',
	'blacklist',
	'bytes',
	'classnames',
	'color',
	'display-name',
	'elemental',
	'expression-match',
	'history',
	'i',
	'list-to-array',
	'marked',
	'moment',
	'numeral',
	'qs',
	'react-addons-css-transition-group',
	'react-alt-text',
	'react-color',
	'react-day-picker',
	'react-dnd',
	'react-dnd-html5-backend',
	'react-dom',
	'react-select',
	'react',
	'store-prototype',
	'superagent',
	'vkey',
	'xhr',
];
<commit_msg>superagent is not used by the client anymore<commit_after>// This file exports the common packages required by the Admin UI.

// It is used to build /public/js/packages.js, and exclude these packages from
// the Admin UI bundle generated by browserify.

module.exports = [
	'async',
	'blacklist',
	'bytes',
	'classnames',
	'color',
	'display-name',
	'elemental',
	'expression-match',
	'history',
	'i',
	'list-to-array',
	'marked',
	'moment',
	'numeral',
	'qs',
	'react-addons-css-transition-group',
	'react-alt-text',
	'react-color',
	'react-day-picker',
	'react-dnd',
	'react-dnd-html5-backend',
	'react-dom',
	'react-select',
	'react',
	'store-prototype',
	'vkey',
	'xhr',
];
<|endoftext|>


<commit_before>var assert = require('assert');
var expect = require('chai').expect;

var genesis = require('../data/fabric');
var message = require('../data/message');

var Fabric = require('../lib/fabric');
var Instruction = require('../lib/instruction');

var state = '90d6d8a4824727f98eb83f66cbcaf55eb48df86300bd51c526d590b037885faa';

//var Machine = require('../lib/machine');

// test our own expectations.  best of luck.
// @consensus:
// @quest:
// > *Warning:* ahead lies death. # must be attributed to "Game Master"
//
describe('Fabric', function () {
  it('should expose a constructor', function () {
    assert.equal(typeof Fabric, 'function');
  });

  it('has the correct, hard-coded genesis seed', async function provenance () {
    var fabric = new Fabric(genesis);
    //assert.equal(fabric.root.id, 0); // require a point of origin.
    fabric._sign();

    assert.equal(JSON.stringify(fabric['@data']), JSON.stringify(genesis));
    assert.equal(fabric['@id'], state);
  });

  it('has a correctly-defined NOOP operation', function () {
    var fabric = new Fabric(genesis);

    fabric.stack.push('NOOP');
    fabric.compute();

    assert.equal(JSON.stringify(fabric['@data']), JSON.stringify(genesis));

  });

  it('can compute a value', function prove () {
    var fabric = new Fabric();

    fabric.use('OP_TRUE', function compute () {
      return 1;
    })

    /*var instruction = new Instruction({
      inputs: ['OP_TRUE'],
      outputs: [1]
    });*/

    fabric.stack.push('OP_TRUE');

    var outcome = fabric.compute();

    assert.equal(outcome['@data'], 1);
  });

  it('can acknowledge its own existence', function identity (done) {
    var alice = new Fabric(genesis);
    alice.on('auth', async function validate (identity) {
      assert.equal(alice.identity.key.public, identity.key.public);
      return done();
    });

    alice.compute();

    alice.start();
  });

  /*/it('can register peers', async function identity () {

    alice.compute();
    bob.compute();

    await alice.connect(bob['@id']);

    var list = Object.keys(alice.peers).map(function(id) {
      return alice.peers[id]['@id'];
    });

    assert.equal(bob['@id'], list[0]);
  }); /**/

  it('can send a message', function broadcast () {
    var fabric = new Fabric(genesis);
    assert.ok(fabric.broadcast());
  });

  /*it('can build a world', function fabricate () {
    var Challenge = require('../lib/challenge');
    var challenge = new Challenge();

    console.log(challenge);

    var world = new Machine([ challenge ]);

    world.on('ready', function() {
      console.log('thing is ready');
    });

    world.step();

    assert.equal('done', world.state);
  });

  it('can produce a fountain', function spawn (ready) {
    var Fountain = require('../lib/fountain');
    var fountain = new Fountain();
    fountain.on('gush', ready);
    fountain.compute();
  });*/

  it('can store and retrieve some data', async function datastore () {
    var Datastore = require('../lib/datastore');
    var datastore = new Datastore(); // robust datastore

    var str = 'Hello, world!';

    await datastore.put('foo', str);

    assert.equal(datastore.get('foo'), str);

  });

});
<commit_msg>Manually close Store after tests in some conditions<commit_after>var assert = require('assert');
var expect = require('chai').expect;

var genesis = require('../data/fabric');
var message = require('../data/message');

var Fabric = require('../lib/fabric');
var Instruction = require('../lib/instruction');

var state = '90d6d8a4824727f98eb83f66cbcaf55eb48df86300bd51c526d590b037885faa';

//var Machine = require('../lib/machine');

// test our own expectations.  best of luck.
// @consensus:
// @quest:
describe('Fabric', function () {
  after(async function () {
    if (typeof fabric !== 'undefined') {
      await fabric.chain.store.close();
    }
  });

  it('should expose a constructor', function () {
    assert.equal(typeof Fabric, 'function');
  });

  it('has the correct, hard-coded genesis seed', async function provenance () {
    var fabric = new Fabric(genesis);
    //assert.equal(fabric.root.id, 0); // require a point of origin.
    fabric._sign();

    await fabric.chain.store.close();

    assert.equal(JSON.stringify(fabric['@data']), JSON.stringify(genesis));
    assert.equal(fabric['@id'], state);
  });

  it('has a correctly-defined NOOP operation', async function () {
    var fabric = new Fabric(genesis);

    fabric.stack.push('NOOP');
    fabric.compute();

    await fabric.chain.store.close();

    assert.equal(JSON.stringify(fabric['@data']), JSON.stringify(genesis));

  });

  it('can compute a value', async function prove () {
    var fabric = new Fabric();

    fabric.use('OP_TRUE', function compute () {
      return 1;
    })

    /*var instruction = new Instruction({
      inputs: ['OP_TRUE'],
      outputs: [1]
    });*/

    fabric.stack.push('OP_TRUE');

    var outcome = fabric.compute();

    await fabric.chain.store.close();

    assert.equal(outcome['@data'], 1);
  });

  it('can acknowledge its own existence', function identity (done) {
    var alice = new Fabric(genesis);

    alice.on('auth', async function validate (identity) {
      await alice.chain.store.close();

      assert.equal(alice.identity.key.public, identity.key.public);
      return done();
    });

    alice.compute();

    alice.start();
  });

  /*/it('can register peers', async function identity () {

    alice.compute();
    bob.compute();

    await alice.connect(bob['@id']);

    var list = Object.keys(alice.peers).map(function(id) {
      return alice.peers[id]['@id'];
    });

    assert.equal(bob['@id'], list[0]);
  }); /**/

  it('can send a message', async function broadcast () {
    var fabric = new Fabric(genesis);
    await fabric.chain.store.close();
    assert.ok(fabric.broadcast());
  });

  /*it('can build a world', function fabricate () {
    var Challenge = require('../lib/challenge');
    var challenge = new Challenge();

    console.log(challenge);

    var world = new Machine([ challenge ]);

    world.on('ready', function() {
      console.log('thing is ready');
    });

    world.step();

    assert.equal('done', world.state);
  });

  it('can produce a fountain', function spawn (ready) {
    var Fountain = require('../lib/fountain');
    var fountain = new Fountain();
    fountain.on('gush', ready);
    fountain.compute();
  });*/

  it('can store and retrieve some data', async function datastore () {
    var Datastore = require('../lib/datastore');
    var datastore = new Datastore(); // robust datastore

    var str = 'Hello, world!';

    await datastore.put('foo', str);

    assert.equal(datastore.get('foo'), str);

  });

});
<|endoftext|>


<commit_before>'use strict';
var requests = {};
var iframeID;
window.addEventListener('error', function(e) {
    if (typeof(iframeID) === 'undefined') {
        var metas = document.getElementsByTagName('meta');
        for (var i=0; i < metas.length; i++) {
            if (metas[i].getAttribute("name") == "iframeid") {
                iframeID = metas[i].getAttribute("content");
                break;
            }
        }
        console.log("Didn't find the iframe ID!!")
    }
    var t = e.target;
    var tag = t.tagName;
    var path = tag == 'LINK' ? t.getAttribute('href') : t.getAttribute('src');
    if ( typeof requests[tag] === 'undefined' ) {
        requests[tag] = {};
    }
    if ( typeof requests[tag][path] === 'undefined' ) {
        requests[tag][path] = {
            targets: []
        };
        parent.postMessage({
            IframeID: iframeID,
            Tag: tag,
            CardID: FB.card.id,
            Path: path,
        }, '*');
    }
    if ( typeof requests[tag][path].url === 'undefined' ) {
        // This means we already requested the file, but it hasn't arrived yet
        requests[tag][path].targets.push( t );
        return false;
    }
    // We've already requested the file, and we have it now!
    t.src = requests[tag][path].url;
    return false;
}, true);

window.addEventListener('message', function(e) {
    var tag = e.data.Tag,
        path = e.data.Path,
        type = e.data.ContentType,
        data = e.data.Data;
    var b = new Blob([data], {type: type})
    var url = URL.createObjectURL(b)

    var req = requests[ tag ][ path ];
    req.url = url
    var attr = data.Tag == 'LINK' ? 'href' : 'src';
    for ( var i = 0; i < req.targets.length; i++ ) {
        req.targets[i][attr] = url;
    }
    req.targets = [];
});
<commit_msg>Only show 'frameID not found' warning when it's actually true (hopefully never)<commit_after>'use strict';
var requests = {};
var iframeID;
window.addEventListener('error', function(e) {
    if (typeof(iframeID) === 'undefined') {
        var metas = document.getElementsByTagName('meta');
        for (var i=0; i < metas.length; i++) {
            if (metas[i].getAttribute("name") == "iframeid") {
                iframeID = metas[i].getAttribute("content");
                break;
            }
        }
        if (typeof iframeID === 'undefined') {
            console.log("Didn't find the iframe ID!!");
        }
    }
    var t = e.target;
    var tag = t.tagName;
    var path = tag == 'LINK' ? t.getAttribute('href') : t.getAttribute('src');
    if ( typeof requests[tag] === 'undefined' ) {
        requests[tag] = {};
    }
    if ( typeof requests[tag][path] === 'undefined' ) {
        requests[tag][path] = {
            targets: []
        };
        parent.postMessage({
            IframeID: iframeID,
            Tag: tag,
            CardID: FB.card.id,
            Path: path,
        }, '*');
    }
    if ( typeof requests[tag][path].url === 'undefined' ) {
        // This means we already requested the file, but it hasn't arrived yet
        requests[tag][path].targets.push( t );
        return false;
    }
    // We've already requested the file, and we have it now!
    t.src = requests[tag][path].url;
    return false;
}, true);

window.addEventListener('message', function(e) {
    var tag = e.data.Tag,
        path = e.data.Path,
        type = e.data.ContentType,
        data = e.data.Data;
    var b = new Blob([data], {type: type})
    var url = URL.createObjectURL(b)

    var req = requests[ tag ][ path ];
    req.url = url
    var attr = data.Tag == 'LINK' ? 'href' : 'src';
    for ( var i = 0; i < req.targets.length; i++ ) {
        req.targets[i][attr] = url;
    }
    req.targets = [];
});
<|endoftext|>


<commit_before>'use strict';

var Cache = require('./cache')
/**
 *  @usage
 *      app.use(noginx([
 *          <RegExp>,
 *          {
 *              rule: <RegExp>, // route match rule
 *              maxAge: <Number>, // ms, the cache data expired time
 *              keyQueries: [<String>, <String>], // picking params of query as cache-key
 *              timeout: <Number> // ms, max waitting time when cache unhit
 *          }
 *      ]), {
 *          maxAge: 3*1000, // ms, default 3000
 *          maxQueueSize: 5000, // default 5000
 *          timeout: 100 // ms, default 100
 *      })
 *
 */
function NOOP () {}
function Log () {
    console.log.apply(console, arguments)
}

function noginx(rules, opts) {

    var _conf = opts || {}
    var _caches = new Cache({
        max: 1000,
        maxAge: 3*1000,
        freePercent: 0.4
    })
    var _penddings = {}
    var _requestQueue = {}

    var MAX_AGE = _conf.maxAge || 3*1000
    var MAX_QUEUE_SIZE = _conf.maxQueueSize || 5000
    var TIMEOUT = _conf.timeout || 100

    var debug = _conf.debug ? Log : NOOP
    rules = rules.map(function (r) {
        if (r instanceof RegExp) {
            return {
                rule: r
            }
        } else if (Object.prototype.toString.call(r) == '[object Object]' && r.rule instanceof RegExp) {
            return r
        } else {
            throw new Error('Unvalid rule of path')
        }
    })

    return function(req, res, next) {
        var cacheKey = req.url
        var urlPath = cacheKey.split('?')[0]
        var maxAge
        var timeout

        // rule match
        if ( (req.method || '').toUpperCase() != 'GET' || !rules.some(function(r) {
            if (r.rule.test(urlPath)) {
                maxAge = r.maxAge || MAX_AGE
                timeout = r.timeout || TIMEOUT
                // 只使用部分配置的参数作为key
                if (r.keyQueries) {
                    cacheKey = urlPath + '?' + r.keyQueries.map(function (k) {
                        return k + '=' + req.query[k]
                    }).join('&')
                }
                debug('[Noginx] Match: Path=', urlPath, ' CacheKey=', cacheKey, ' Timeout=', timeout)
                return true
            }
        })) {
            return next()
        }
        var hitedCache = _caches.get(cacheKey)
        // if hit
        if (hitedCache) {
            res.setHeader('X-Noginx', 'hit')
            return res.status(200).send(hitedCache)
        } else if (_penddings[cacheKey]) {
            // allot
            var queue = _requestQueue[cacheKey] || []

            // 过载保护，服务器无法处理请求
            if (queue.length >= MAX_QUEUE_SIZE) {
                res.setHeader('X-Noginx', 'refuse')
                return res.status(503).send('Server is busy.')
            }
            res.setHeader('X-Noginx', 'queue')
            queue.push({
                req: req,
                res: res
            })
            _requestQueue[cacheKey] = queue
            return
        } else {
            // request for api
            _penddings[cacheKey] = true
        }
        res.setHeader('X-Noginx', 'through')

        var _render = res.render
        var _send = res.send
        var requestEnd
        var isTimeout
        var timer // 定时器，检验请求超时

        var start = +new Date
        function requestHandler (err, str, statusCode) {

            _penddings[cacheKey] = false

            // 缓存内容存在且 truly 时存进缓存中
            !err && str && _caches.set(cacheKey, str, maxAge)

            var queue = _requestQueue[cacheKey]
            // 释放请求队列
            _requestQueue[cacheKey] = null

            var contentType = res.getHeader('Content-Type')
            var cacheControl = res.getHeader('Cache-Control')

            if (queue && queue.length) {
                if (err) {
                    queue.forEach(function(item) {
                        item.res.status(statusCode || 500).send(err)
                    })
                } else {
                    queue.forEach(function(item) {
                        contentType && item.res.setHeader('Content-Type', contentType)
                        cacheControl && item.res.setHeader('Cache-Control', cacheControl)
                        item.res.status(statusCode || 200).send(str)
                    })
                }
            }

            if (err) {
                res.status(statusCode || 500)
                _send.call(res, err)
                return
            }
            res.status(statusCode || 200)
            _send.call(res, str)
        }
        res.render = function(tpl, data, fn) {
            _render.call(res, tpl, data, function(err, str) {
                debug('[Noginx] Render: Path=' + urlPath + ' CacheKey=' + cacheKey  + ' Timeout=' + timeout
                    + ' Queue=' + (_requestQueue[cacheKey] ? _requestQueue[cacheKey].length : 0)+ ' Time=' + (+new Date - start) )

                clearTimeout(timer)
                // 已超时就丢弃
                if (isTimeout || requestEnd) return
                // 避免逻辑层调用了render后还调用send引起的异常
                requestEnd = true
                requestHandler(err, str)
            })
        }
        /**
         *  混存的接口应避免使用这个方法，提供这个方法的原因只是为了容错
         *  因为使用Send接口，HTTP StatusCode 的获取存在不确定性
         */
        res.send = function (/*[statuCode, ]*/body) {
             debug('[Noginx] Send: Path=' + urlPath + ' CacheKey=' + cacheKey  + ' Timeout=' + timeout
                    + ' Queue=' + (_requestQueue[cacheKey] ? _requestQueue[cacheKey].length : 0)+ ' Time=' + (+new Date - start) )

            clearTimeout(timer)
            // 已超时就丢弃
            if (isTimeout || requestEnd) return
            // 避免逻辑层调用了render后还调用send引起的异常
            requestEnd = true

            var statusCode = this.statusCode
            if (arguments.length === 2 && typeof arguments[0] === 'number') {
                // 执行到这，方法的参数列表为 res.send(status, body)
                statusCode = body
                body = arguments[1]
            } else if (arguments.length === 1 && typeof arguments[0] === 'number') {
                // 执行到这，方法的参数列表为 res.send(status)
                statusCode = body
                body = ''
            }
            // 带上状态码
            requestHandler(null, body, statusCode)
        }

        timer = setTimeout(function() {
            isTimeout = true
            requestHandler('Request timeout.', null, 504)
        }, timeout)

        next()
    }
}

module.exports = noginx<commit_msg>add json method and timeout checking<commit_after>'use strict';

var Cache = require('./cache')
/**
 *  @usage
 *      app.use(noginx([
 *          <RegExp>,
 *          {
 *              rule: <RegExp>, // route match rule
 *              maxAge: <Number>, // ms, the cache data expired time
 *              keyQueries: [<String>, <String>], // picking params of query as cache-key
 *              timeout: <Number> // ms, max waitting time when cache unhit
 *          }
 *      ]), {
 *          maxAge: 3*1000, // ms, default 3000
 *          maxQueueSize: 5000, // default 5000
 *          timeout: 100 // ms, default 100
 *      })
 *
 */
function NOOP () {}
function Log () {
    console.log.apply(console, arguments)
}

function noginx(rules, opts) {

    var _conf = opts || {}
    var _caches = new Cache({
        max: 1000,
        maxAge: 3*1000,
        freePercent: 0.4
    })
    var _penddings = {}
    var _requestQueue = {}

    var MAX_AGE = _conf.maxAge || 3*1000
    var MAX_QUEUE_SIZE = _conf.maxQueueSize || 5000
    var TIMEOUT = _conf.timeout || 100

    var debug = _conf.debug ? Log : NOOP
    rules = rules.map(function (r) {
        if (r instanceof RegExp) {
            return {
                rule: r
            }
        } else if (Object.prototype.toString.call(r) == '[object Object]' && r.rule instanceof RegExp) {
            return r
        } else {
            throw new Error('Unvalid rule of path')
        }
    })

    return function(req, res, next) {
        var cacheKey = req.url
        var urlPath = cacheKey.split('?')[0]
        var maxAge
        var timeout

        // rule match
        if ( (req.method || '').toUpperCase() != 'GET' || !rules.some(function(r) {
            if (r.rule.test(urlPath)) {
                maxAge = r.maxAge || MAX_AGE
                timeout = r.timeout || TIMEOUT
                // 只使用部分配置的参数作为key
                if (r.keyQueries) {
                    cacheKey = urlPath + '?' + r.keyQueries.map(function (k) {
                        return k + '=' + req.query[k]
                    }).join('&')
                }
                debug('[Noginx] Match: Path=', urlPath, ' CacheKey=', cacheKey, ' Timeout=', timeout)
                return true
            }
        })) {
            return next()
        }
        var hitedCache = _caches.get(cacheKey)
        // if hit
        if (hitedCache) {
            res.setHeader('X-Noginx', 'hit')
            return res.status(200).send(hitedCache)
        } else if (_penddings[cacheKey]) {
            // allot
            var queue = _requestQueue[cacheKey] || []

            // 过载保护，服务器无法处理请求
            if (queue.length >= MAX_QUEUE_SIZE) {
                res.setHeader('X-Noginx', 'refuse')
                return res.status(503).send('Server is busy.')
            }
            res.setHeader('X-Noginx', 'queue')
            queue.push({
                req: req,
                res: res
            })
            _requestQueue[cacheKey] = queue
            return
        } else {
            // request for api
            _penddings[cacheKey] = true
        }
        res.setHeader('X-Noginx', 'through')

        var _render = res.render
        var _send = res.send
        var requestEnd
        var isTimeout
        var timer // 定时器，检验请求超时

        var start = +new Date
        function requestHandler (err, str, statusCode) {

            _penddings[cacheKey] = false

            // 缓存内容存在且 truly 时存进缓存中
            !err && str && _caches.set(cacheKey, str, maxAge)

            var queue = _requestQueue[cacheKey]
            // 释放请求队列
            _requestQueue[cacheKey] = null

            var contentType = res.getHeader('Content-Type')
            var cacheControl = res.getHeader('Cache-Control')

            if (queue && queue.length) {
                if (err) {
                    queue.forEach(function(item) {
                        item.res.status(statusCode || 500).send(err)
                    })
                } else {
                    queue.forEach(function(item) {
                        contentType && item.res.setHeader('Content-Type', contentType)
                        cacheControl && item.res.setHeader('Cache-Control', cacheControl)
                        item.res.status(statusCode || 200).send(str)
                    })
                }
            }

            if (err) {
                res.status(statusCode || 500)
                _send.call(res, err)
                // 会出现逻辑层在调用send之后再调用setHeader的情况，此处容错
                // res.setHeader = NOOP
                return
            }
            res.status(statusCode || 200)
            _send.call(res, str)
            // res.setHeader = NOOP
        }
        res.render = function(tpl, data, fn) {
            if (isTimeout || requestEnd) return

            _render.call(res, tpl, data, function(err, str) {
                debug('[Noginx] Render: Path=' + urlPath + ' CacheKey=' + cacheKey  + ' Timeout=' + timeout
                    + ' Queue=' + (_requestQueue[cacheKey] ? _requestQueue[cacheKey].length : 0)+ ' Time=' + (+new Date - start) )

                clearTimeout(timer)
                // 已超时就丢弃
                if (isTimeout || requestEnd) return
                // 避免逻辑层调用了render后还调用send引起的异常
                requestEnd = true
                requestHandler(err, str)
            })
        }
        /**
         *  混存的接口应避免使用这个方法，提供这个方法的原因只是为了容错
         *  因为使用Send接口，HTTP StatusCode 的获取存在不确定性
         */
        res.send = function (/*[statuCode, ]*/body) {
             debug('[Noginx] Send: Path=' + urlPath + ' CacheKey=' + cacheKey  + ' Timeout=' + timeout
                    + ' Queue=' + (_requestQueue[cacheKey] ? _requestQueue[cacheKey].length : 0)+ ' Time=' + (+new Date - start) )

            clearTimeout(timer)
            // 已超时就丢弃
            if (isTimeout || requestEnd) return
            // 避免逻辑层调用了render后还调用send引起的异常
            requestEnd = true

            var statusCode = this.statusCode
            if (arguments.length === 2 && typeof arguments[0] === 'number') {
                // 执行到这，方法的参数列表为 res.send(status, body)
                statusCode = body
                body = arguments[1]
            } else if (arguments.length === 1 && typeof arguments[0] === 'number') {
                // 执行到这，方法的参数列表为 res.send(status)
                statusCode = body
                body = ''
            }
            // 带上状态码
            requestHandler(null, body, statusCode)
        }

        res.json = function (obj) {
            debug('[Noginx] Json: Path=' + urlPath + ' CacheKey=' + cacheKey  + ' Timeout=' + timeout
                + ' Queue=' + (_requestQueue[cacheKey] ? _requestQueue[cacheKey].length : 0)+ ' Time=' + (+new Date - start) )
            clearTimeout(timer)

            // 已超时就丢弃
            if (isTimeout || requestEnd) return
            // 避免逻辑层调用了render后还调用send引起的异常
            requestEnd = true

            var data = null
            try {
                data = JSON.parse(JSON.stringify(obj))
            } catch (e) {
                data = obj
            }
            requestHandler(null, data, 200)
        }

        timer = setTimeout(function() {
            isTimeout = true
            requestHandler('Request timeout.', null, 504)
        }, timeout)

        next()
    }
}

module.exports = noginx<|endoftext|>


<commit_before>const path = require('path');
const autoprefixer = require('autoprefixer');
const precss = require('precss');
const postcssCalc = require('postcss-calc');
const packageConfig = require('./packageConfig');
const babelOptions = require('./babelOptions');

const cssOptions = {
  sourceMap: true,
  modules: true,
  importLoaders: 1,
  context: 'src/components',
  localIdentName: '[path][local]',
};

module.exports = {
  mode: 'development',
  context: __dirname,
  entry: [path.resolve(packageConfig.clientEntry || 'src/index.js')],
  output: {
    filename: '[name].js',
    path: path.resolve('build/assets'),
    publicPath: '/assets/',
  },
  plugins: [],
  resolve: {
    modules: ['node_modules'],
    extensions: [
      '.js',
      '.json',
      '.ts',
      '.tsx',
    ],
    alias: {
      Types: path.resolve(__dirname, 'src/__generated__'),
    },
  },
  module: {
    rules: [
      {
        test: /\btranslations\.(json|ya?ml)$/,
        type: 'javascript/auto',
        loader: 'messageformat-loader',
        options: {
          locale: packageConfig.locale || 'en',
        },
      },
      {
        test: /\.tsx*$/,
        include: [path.resolve('src')],
        use: [
          {
            loader: 'babel-loader',
            options: babelOptions,
          },
        ],
      },
      {
        test: /\.jsx*$/,
        include: [path.resolve('src'), path.resolve('server.js')],
        use: [
          {
            loader: 'babel-loader',
            options: babelOptions,
          },
        ],
      },
      {
        test: /\.css$/,
        include: path.resolve('src'),
        use: [
          {
            loader: 'css-loader',
            options: cssOptions,
          },
          {
            loader: 'postcss-loader',
            options: {
              sourceMap: true,
              ident: 'postcss',
              plugins: [autoprefixer(), postcssCalc(), precss()],
            },
          },
        ],
      },
      {
        test: /\.css$/,
        include: path.resolve('node_modules'),
        use: [
          {
            loader: 'css-loader',
            options: {
              modules: false,
            },
          },
        ],
      },
      {
        test: /\.scss$/,
        use: [
          {
            loader: 'css-loader',
            options: { ...cssOptions, importLoaders: 3 },
          },
          'resolve-url-loader',
          {
            loader: 'postcss-loader',
            options: {
              sourceMap: true,

              // needed to have two different postcss configs
              // without this, it just silently fails
              ident: 'postcss-sass',

              plugins: [autoprefixer()],
            },
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true,
            },
          },
        ],
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              hash: 'sha512',
              digest: 'hex',
              name: '[hash].[ext]',
            },
          },
          {
            loader: 'image-webpack-loader',
            options: {
              bypassOnDebug: true,
            },
          },
        ],
      },
      {
        test: /\.woff2?$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 10000,
              mimetype: 'application/font-woff',
            },
          },
        ],
      },
      {
        test: /masonry|imagesloaded|fizzy\-ui\-utils|desandro\-|outlayer|get\-size|doc\-ready|eventie|eventemitter/,
        use: 'imports-loader?define=>false&this=>window',
      },
    ],
  },
};
<commit_msg>sass-loader<commit_after>const path = require('path');
const autoprefixer = require('autoprefixer');
const precss = require('precss');
const postcssCalc = require('postcss-calc');
const packageConfig = require('./packageConfig');
const babelOptions = require('./babelOptions');

const cssOptions = {
  sourceMap: true,
  modules: true,
  importLoaders: 1,
  context: 'src/components',
  localIdentName: '[path][local]',
};

module.exports = {
  mode: 'development',
  context: __dirname,
  entry: [path.resolve(packageConfig.clientEntry || 'src/index.js')],
  output: {
    filename: '[name].js',
    path: path.resolve('build/assets'),
    publicPath: '/assets/',
  },
  plugins: [],
  resolve: {
    modules: ['node_modules'],
    extensions: [
      '.js',
      '.json',
      '.ts',
      '.tsx',
    ],
    alias: {
      Types: path.resolve(__dirname, 'src/__generated__'),
    },
  },
  module: {
    rules: [
      {
        test: /\btranslations\.(json|ya?ml)$/,
        type: 'javascript/auto',
        loader: 'messageformat-loader',
        options: {
          locale: packageConfig.locale || 'en',
        },
      },
      {
        test: /\.tsx*$/,
        include: [path.resolve('src')],
        use: [
          {
            loader: 'babel-loader',
            options: babelOptions,
          },
        ],
      },
      {
        test: /\.jsx*$/,
        include: [path.resolve('src'), path.resolve('server.js')],
        use: [
          {
            loader: 'babel-loader',
            options: babelOptions,
          },
        ],
      },
      {
        test: /\.css$/,
        include: path.resolve('src'),
        use: [
          {
            loader: 'css-loader',
            options: cssOptions,
          },
          {
            loader: 'postcss-loader',
            options: {
              sourceMap: true,
              ident: 'postcss',
              plugins: [autoprefixer(), postcssCalc(), precss()],
            },
          },
        ],
      },
      {
        test: /\.css$/,
        include: path.resolve('node_modules'),
        use: [
          {
            loader: 'css-loader',
            options: {
              modules: false,
            },
          },
        ],
      },
      {
        test: /\.scss$/,
        use: [
          {
            loader: 'css-loader',
            options: { ...cssOptions, importLoaders: 3 },
          },
          'resolve-url-loader',
          {
            loader: 'postcss-loader',
            options: {
              sourceMap: true,

              // needed to have two different postcss configs
              // without this, it just silently fails
              ident: 'postcss-sass',

              plugins: [autoprefixer()],
            },
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true,
              implementation: require.resolve('sass'),
            },
          },
        ],
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              hash: 'sha512',
              digest: 'hex',
              name: '[hash].[ext]',
            },
          },
          {
            loader: 'image-webpack-loader',
            options: {
              bypassOnDebug: true,
            },
          },
        ],
      },
      {
        test: /\.woff2?$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 10000,
              mimetype: 'application/font-woff',
            },
          },
        ],
      },
      {
        test: /masonry|imagesloaded|fizzy\-ui\-utils|desandro\-|outlayer|get\-size|doc\-ready|eventie|eventemitter/,
        use: 'imports-loader?define=>false&this=>window',
      },
    ],
  },
};
<|endoftext|>


<commit_before>var request = require('request');
var htmlparser = require("htmlparser");
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var parseUrl = require('url').parse;
var formatUrl = require('url').format;
var resolveUrl = require('url').resolve;
var querystring = require('querystring');

/**
 * Set this if you want fallback for sites that don't provide oEmbed.
 */
exports.EMBEDLY_KEY = undefined;
exports.EMBEDLY_URL = "http://api.embed.ly/1/oembed";

/**
 * htmlparser is not doing that for us :-(
 */
function expandEntities(s) {
    if (typeof s !== 'string')
	return undefined;
    return s.replace('&', '&').
	replace('<', '<').
	replace('>', '>').
	replace('"', '"').
	replace(''', '\'');
}

function getElementText(el) {
    if (el.children)
	return expandEntities(el.children.map(getElementText).join(""));
    else if (el.type === 'text')
	return expandEntities(el.data);
    else
	return "";
}

/**
 * Wraps request()
 */
function httpGet(url, cb) {
    try {
	return request({ uri: url,
			 jar: false,  /* no cookies */
			 headers: {
			     "User-Agent": exports.USER_AGENT
			 }
		       }, cb);
    } catch (e) {
	/* request() throws at us */
	if (cb)
	    cb(e);
	else
	    throw e;
    }
}

var package = require('../package.json');
exports.USER_AGENT = "node-oembed/" + package.version + " (" + package.homepage + ")";

/**
 * Write stream that collects <link rel='alternate'> @href by @type
 *
 * @param {Function} urlConvert Expands relative to absolute URL
 * @param {Function} cb Final callback
 */
function Discovery(urlConvert, cb) {
    this.urlConvert = urlConvert;
    this.callback = cb;
    var handler = new DiscoveryHandler(this);
    this.parser = new htmlparser.Parser(handler);
    this.alternates = {};
}
util.inherits(Discovery, EventEmitter);

Discovery.prototype.write = function(data) {
    this.parser.parseChunk(data);
    return true;
};

Discovery.prototype.end = function() {
    this.parser.done();
};

Discovery.prototype.addAlternate = function(type, href) {
    if (!this.alternates.hasOwnProperty(type))
	this.alternates[type] = this.urlConvert(href);
};

Discovery.prototype.onDone = function() {
    this.callback(null, this.alternates);
};

/**
 * Methods implement htmlparser handler interface
 *
 * @param {Discovery} disco
 */
function DiscoveryHandler(disco) {
    this.disco = disco;
}

DiscoveryHandler.prototype = {
    reset: function() {
    },
    done: function() {
	this.disco.onDone();
    },
    writeTag: function(el) {
	var attrs = el.attribs;
	var type = attrs && expandEntities(attrs.type);
	var href = attrs && expandEntities(attrs.href);
	if (el.name === 'link' &&
	    attrs && attrs.rel === 'alternate' &&
	    type && href) {
	    this.disco.addAlternate(type, href);
	}
    },
    writeText: function() {
    },
    writeComment: function() {
    },
    writeDirective: function() {
    }
};

exports.discover = function(url, cb) {
    var req;
    try {
	req = httpGet(url);
    } catch (e) {
	return cb(e);
    }

    req.on('response', function(res) {
	if (res.statusCode === 200) {
	    var disco = new Discovery(function(href) {
		return resolveUrl(url, href);
	    }, cb);
	    res.pipe(disco);
	} else
	    cb(new Error("HTTP status " + res.statusCode));
    });
    req.on('error', function(error) {
	cb(error);
    });
};

function OEmbedXMLParser(cb) {
    this.callback = cb;
    var handler = new htmlparser.DefaultHandler(function(error, dom) {
	var oembedRoot = dom &&
	    dom.filter(function(el) {
		return el.name === 'oembed';
	    })[0];
	if (oembedRoot && oembedRoot.children) {
	    var result = {};
	    oembedRoot.children.forEach(function(child) {
		if (child.name)
		    result[child.name] = getElementText(child);
	    });
	    cb(null, result);
	} else
	    cb(error || new Error("Invalid oEmbed document"));
    });
    this.parser = new htmlparser.Parser(handler);
    this.alternates = {};
}
util.inherits(OEmbedXMLParser, EventEmitter);

OEmbedXMLParser.prototype.write = function(data) {
    this.parser.parseChunk(data);
    return true;
};

OEmbedXMLParser.prototype.end = function() {
    this.parser.done();
};

exports.fetchXML = function(url, cb) {
    var req = httpGet(url);
    req.on('response', function(res) {
	if (res.statusCode === 200) {
	    var parser = new OEmbedXMLParser(cb);
	    res.pipe(parser);
	} else
	    cb(new Error("HTTP status " + res.statusCode));
    });
    req.on('error', function(error) {
	cb(error);
    });
};

exports.fetchJSON = function(url, cb) {
    httpGet(url, function(error, res, body) {
	if (!error &&
	    res.statusCode === 200 &&
	    body) {
	    try {
		cb(null, JSON.parse(body));
	    } catch (e) {
		cb(e);
	    }
	} else
	    cb(error || new Error("HTTP status " + res.statusCode));
    });
};

var MIME_OEMBED_JSON = exports.MIME_OEMBED_JSON = 'application/json+oembed';
var MIME_OEMBED_XML = exports.MIME_OEMBED_XML = 'text/xml+oembed';
var ALLOWED_PARAMETERS = ["url", "format", "key", "maxwidth", "maxheight"];

function applyParameters(url, parameters) {
    if (!parameters)
	/* Nothing to do, skip */
	return url;

    if (!url.query || typeof url.query === 'string')
	/* Parse querystring */
	url = parseUrl(url, true);

    for(var k in parameters)
	if (ALLOWED_PARAMETERS.indexOf(k) >= 0)
	    url.query[k] = parameters[k];

    /* request assumes .search, not .query */
    url.search = "?" + querystring.stringify(url.query);
    /* different libraries handle the multiple data of url onjects
     * differently, we use both the node stdlib and request. let's just
     * serialize for them so our parameters are kept.
     */
    return formatUrl(url);
}

/**
 * Main entry point
 */
exports.fetch = function(url, parameters, cb) {
    exports.discover(url, function(error, alternates) {
	var oembedUrl;
	if (alternates && alternates[MIME_OEMBED_JSON]) {
	    oembedUrl = applyParameters(alternates[MIME_OEMBED_JSON], parameters);
	    exports.fetchJSON(oembedUrl, cb);
	} else if (alternates && alternates[MIME_OEMBED_XML]) {
	    oembedUrl = applyParameters(alternates[MIME_OEMBED_XML], parameters);
	    exports.fetchXML(oembedUrl, cb);
	} else if (exports.EMBEDLY_KEY) {
	    if (!parameters)
		parameters = {};
	    /* Fallback to the Embedly oEmbed API */
	    parameters.key = exports.EMBEDLY_KEY;
	    parameters.url = url;
	    /* Sanitize user-provided parameters */
	    parameters.format = 'json';
	    delete parameters.callback;

	    oembedUrl = applyParameters(exports.EMBEDLY_URL, parameters);
	    exports.fetchJSON(oembedUrl, cb);
	} else
	    cb(error || new Error("No oEmbed links discovered"));
    });
};
<commit_msg>#7 - Soundcloud uses text/json+oembed<commit_after>var request = require('request');
var htmlparser = require("htmlparser");
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var parseUrl = require('url').parse;
var formatUrl = require('url').format;
var resolveUrl = require('url').resolve;
var querystring = require('querystring');

/**
 * Set this if you want fallback for sites that don't provide oEmbed.
 */
exports.EMBEDLY_KEY = undefined;
exports.EMBEDLY_URL = "http://api.embed.ly/1/oembed";

/**
 * htmlparser is not doing that for us :-(
 */
function expandEntities(s) {
    if (typeof s !== 'string')
	return undefined;
    return s.replace('&', '&').
	replace('<', '<').
	replace('>', '>').
	replace('"', '"').
	replace(''', '\'');
}

function getElementText(el) {
    if (el.children)
	return expandEntities(el.children.map(getElementText).join(""));
    else if (el.type === 'text')
	return expandEntities(el.data);
    else
	return "";
}

/**
 * Wraps request()
 */
function httpGet(url, cb) {
    try {
	return request({ uri: url,
			 jar: false,  /* no cookies */
			 headers: {
			     "User-Agent": exports.USER_AGENT
			 }
		       }, cb);
    } catch (e) {
	/* request() throws at us */
	if (cb)
	    cb(e);
	else
	    throw e;
    }
}

var package = require('../package.json');
exports.USER_AGENT = "node-oembed/" + package.version + " (" + package.homepage + ")";

/**
 * Write stream that collects <link rel='alternate'> @href by @type
 *
 * @param {Function} urlConvert Expands relative to absolute URL
 * @param {Function} cb Final callback
 */
function Discovery(urlConvert, cb) {
    this.urlConvert = urlConvert;
    this.callback = cb;
    var handler = new DiscoveryHandler(this);
    this.parser = new htmlparser.Parser(handler);
    this.alternates = {};
}
util.inherits(Discovery, EventEmitter);

Discovery.prototype.write = function(data) {
    this.parser.parseChunk(data);
    return true;
};

Discovery.prototype.end = function() {
    this.parser.done();
};

Discovery.prototype.addAlternate = function(type, href) {
    if (!this.alternates.hasOwnProperty(type))
	this.alternates[type] = this.urlConvert(href);
};

Discovery.prototype.onDone = function() {
    this.callback(null, this.alternates);
};

/**
 * Methods implement htmlparser handler interface
 *
 * @param {Discovery} disco
 */
function DiscoveryHandler(disco) {
    this.disco = disco;
}

DiscoveryHandler.prototype = {
    reset: function() {
    },
    done: function() {
	this.disco.onDone();
    },
    writeTag: function(el) {
	var attrs = el.attribs;
	var type = attrs && expandEntities(attrs.type);
	var href = attrs && expandEntities(attrs.href);
	if (el.name === 'link' &&
	    attrs && attrs.rel === 'alternate' &&
	    type && href) {
	    this.disco.addAlternate(type, href);
	}
    },
    writeText: function() {
    },
    writeComment: function() {
    },
    writeDirective: function() {
    }
};

exports.discover = function(url, cb) {
    var req;
    try {
	req = httpGet(url);
    } catch (e) {
	return cb(e);
    }

    req.on('response', function(res) {
	if (res.statusCode === 200) {
	    var disco = new Discovery(function(href) {
		return resolveUrl(url, href);
	    }, cb);
	    res.pipe(disco);
	} else
	    cb(new Error("HTTP status " + res.statusCode));
    });
    req.on('error', function(error) {
	cb(error);
    });
};

function OEmbedXMLParser(cb) {
    this.callback = cb;
    var handler = new htmlparser.DefaultHandler(function(error, dom) {
	var oembedRoot = dom &&
	    dom.filter(function(el) {
		return el.name === 'oembed';
	    })[0];
	if (oembedRoot && oembedRoot.children) {
	    var result = {};
	    oembedRoot.children.forEach(function(child) {
		if (child.name)
		    result[child.name] = getElementText(child);
	    });
	    cb(null, result);
	} else
	    cb(error || new Error("Invalid oEmbed document"));
    });
    this.parser = new htmlparser.Parser(handler);
    this.alternates = {};
}
util.inherits(OEmbedXMLParser, EventEmitter);

OEmbedXMLParser.prototype.write = function(data) {
    this.parser.parseChunk(data);
    return true;
};

OEmbedXMLParser.prototype.end = function() {
    this.parser.done();
};

exports.fetchXML = function(url, cb) {
    var req = httpGet(url);
    req.on('response', function(res) {
	if (res.statusCode === 200) {
	    var parser = new OEmbedXMLParser(cb);
	    res.pipe(parser);
	} else
	    cb(new Error("HTTP status " + res.statusCode));
    });
    req.on('error', function(error) {
	cb(error);
    });
};

exports.fetchJSON = function(url, cb) {
    httpGet(url, function(error, res, body) {
	if (!error &&
	    res.statusCode === 200 &&
	    body) {
	    try {
		cb(null, JSON.parse(body));
	    } catch (e) {
		cb(e);
	    }
	} else
	    cb(error || new Error("HTTP status " + res.statusCode));
    });
};

var MIME_OEMBED_JSON = exports.MIME_OEMBED_JSON = 'application/json+oembed';
var MIME_OEMBED_TEXT_JSON = exports.MIME_OEMBED_TEXT_JSON = 'text/json+oembed';
var MIME_OEMBED_XML = exports.MIME_OEMBED_XML = 'text/xml+oembed';
var ALLOWED_PARAMETERS = ["url", "format", "key", "maxwidth", "maxheight"];

function applyParameters(url, parameters) {
    if (!parameters)
	/* Nothing to do, skip */
	return url;

    if (!url.query || typeof url.query === 'string')
	/* Parse querystring */
	url = parseUrl(url, true);

    for(var k in parameters)
	if (ALLOWED_PARAMETERS.indexOf(k) >= 0)
	    url.query[k] = parameters[k];

    /* request assumes .search, not .query */
    url.search = "?" + querystring.stringify(url.query);
    /* different libraries handle the multiple data of url onjects
     * differently, we use both the node stdlib and request. let's just
     * serialize for them so our parameters are kept.
     */
    return formatUrl(url);
}

/**
 * Main entry point
 */
exports.fetch = function(url, parameters, cb) {
    exports.discover(url, function(error, alternates) {
	var oembedUrl;
	if (alternates && alternates[MIME_OEMBED_JSON]) {
	    oembedUrl = applyParameters(alternates[MIME_OEMBED_JSON], parameters);
	    exports.fetchJSON(oembedUrl, cb);
	} else if (alternates && alternates[MIME_OEMBED_TEXT_JSON]) {
	    oembedUrl = applyParameters(alternates[MIME_OEMBED_TEXT_JSON], parameters);
	    exports.fetchJSON(oembedUrl, cb);
	} else if (alternates && alternates[MIME_OEMBED_XML]) {
	    oembedUrl = applyParameters(alternates[MIME_OEMBED_XML], parameters);
	    exports.fetchXML(oembedUrl, cb);
	} else if (exports.EMBEDLY_KEY) {
	    if (!parameters)
		parameters = {};
	    /* Fallback to the Embedly oEmbed API */
	    parameters.key = exports.EMBEDLY_KEY;
	    parameters.url = url;
	    /* Sanitize user-provided parameters */
	    parameters.format = 'json';
	    delete parameters.callback;

	    oembedUrl = applyParameters(exports.EMBEDLY_URL, parameters);
	    exports.fetchJSON(oembedUrl, cb);
	} else
	    cb(error || new Error("No oEmbed links discovered"));
    });
};
<|endoftext|>


<commit_before>// Returns a jQuery or AngularJS deferred object, or pass a success and fail callbacks if you don't want to use jQuery or AngularJS
var getAppVersion = function (success, fail) {
  var toReturn, deferred;
  if ((typeof success) === 'undefined') {
    if(window.jQuery){
      deferred = jQuery.Deferred();
      toReturn = deferred;
    } else if(window.angular){
      var injector = angular.injector(["ng"]);
      var $q = injector.get("$q");
      deferred = $q.defer();
      toReturn = deferred.promise
    } else {
      return console.error('AppVersion either needs a success callback, or jQuery/AngularJS defined for using promises');
    }
    success = deferred.resolve;
    fail = deferred.reject;
  }
  // 5th param is NOT optional. must be at least empty array
  cordova.exec(success, fail, "AppVersion", "getVersionNumber", []);
  return toReturn;
};

module.exports = getAppVersion;
<commit_msg>Added phonegap interface.<commit_after>// Returns a jQuery or AngularJS deferred object, or pass a success and fail callbacks if you don't want to use jQuery or AngularJS
var getAppVersion = {
  getVersionNumber: function (success, fail) {
    var toReturn, deferred;
    if ((typeof success) === 'undefined') {
      if(window.jQuery){
        deferred = jQuery.Deferred();
        toReturn = deferred;
      } else if(window.angular){
        var injector = angular.injector(["ng"]);
        var $q = injector.get("$q");
        deferred = $q.defer();
        toReturn = deferred.promise
      } else {
        return console.error('AppVersion either needs a success callback, or jQuery/AngularJS defined for using promises');
      }
      success = deferred.resolve;
      fail = deferred.reject;
    }
    // 5th param is NOT optional. must be at least empty array
    cordova.exec(success, fail, "AppVersion", "getVersionNumber", []);
    return toReturn;
  },
  getVersionCode: function (success, fail) {
    var toReturn, deferred;
    if ((typeof success) === 'undefined') {
      if(window.jQuery){
        deferred = jQuery.Deferred();
        toReturn = deferred;
      } else if(window.angular){
        var injector = angular.injector(["ng"]);
        var $q = injector.get("$q");
        deferred = $q.defer();
        toReturn = deferred.promise
      } else {
        return console.error('AppVersion either needs a success callback, or jQuery/AngularJS defined for using promises');
      }
      success = deferred.resolve;
      fail = deferred.reject;
    }
    // 5th param is NOT optional. must be at least empty array
    cordova.exec(success, fail, "AppVersion", "getVersionCode", []);
    return toReturn;
  }
};

module.exports = getAppVersion;
<|endoftext|>


<commit_before>import {
  invoke
} from '../bridge'

export {
  isTabBarPage
}
  from '../bridge'

export function callApiSync (api, args, name, alias) {
  const ret = api(args)
  if (ret && ret.errMsg) {
    ret.errMsg = ret.errMsg.replace(name, alias)
  }
  return ret
}

export function getWebview (__page__) {
  if (__page__) {
    return __page__.$getAppWebview()
  }
  return getLastWebview()
}

export function getLastWebview () {
  try {
    const pages = getCurrentPages()
    if (pages.length) {
      return pages[pages.length - 1].$getAppWebview()
    }
  } catch (e) {
    if (process.env.NODE_ENV !== 'production') {
      console.log('getCurrentPages is not ready')
    }
  }
}

const getRealRoute = (e, t) => {
  if (t.indexOf('./') === 0) return getRealRoute(e, t.substr(2), !1)
  let n
  let i
  const o = t.split('/')
  for (n = 0, i = o.length; n < i && o[n] === '..'; n++);
  o.splice(0, n)
  t = o.join('/')
  const r = e.length > 0 ? e.split('/') : []
  r.splice(r.length - n - 1, n + 1)
  return r.concat(o).join('/')
}

// 处理 Android 平台解压与非解压模式下获取的路径不一致的情况
const _handleLocalPath = filePath => {
  const localUrl = plus.io.convertLocalFileSystemURL(filePath)
  return localUrl.replace(/^\/?apps\//, '/android_asset/apps/').replace(/\/$/, '')
}

export function getRealPath (filePath) {
  const SCHEME_RE = /^([a-z-]+:)?\/\//i
  const DATA_RE = /^data:.*,.*/

  // 无协议的情况补全 https
  if (filePath.indexOf('//') === 0) {
    filePath = 'https:' + filePath
  }

  // 网络资源或base64
  if (SCHEME_RE.test(filePath) || DATA_RE.test(filePath)) {
    return filePath
  }

  if (filePath.indexOf('_www') === 0 || filePath.indexOf('_doc') === 0 || filePath.indexOf('_documents') === 0 ||
    filePath.indexOf('_downloads') === 0) {
    return 'file://' + _handleLocalPath(filePath)
  }
  const wwwPath = 'file://' + _handleLocalPath('_www')
  // 绝对路径转换为本地文件系统路径
  if (filePath.indexOf('/') === 0) {
    return wwwPath + filePath
  }
  // 相对资源
  if (filePath.indexOf('../') === 0 || filePath.indexOf('./') === 0) {
    if (typeof __id__ === 'string') {
      return wwwPath + getRealRoute('/' + __id__, filePath)
    } else {
      const pages = getCurrentPages()
      if (pages.length) {
        return wwwPath + getRealRoute('/' + pages[pages.length - 1].route, filePath)
      }
    }
  }
  return filePath
}

export function getStatusBarStyle () {
  let style = plus.navigator.getStatusBarStyle()
  if (style === 'UIStatusBarStyleBlackTranslucent' || style === 'UIStatusBarStyleBlackOpaque' || style === 'null') {
    style = 'light'
  } else if (style === 'UIStatusBarStyleDefault') {
    style = 'dark'
  }
  return style
}

const PI = 3.1415926535897932384626
const a = 6378245.0
const ee = 0.00669342162296594323

export function wgs84togcj02 (lng, lat) {
  lat = +lat
  lng = +lng
  if (outOfChina(lng, lat)) {
    return [lng, lat]
  }
  let dlat = _transformlat(lng - 105.0, lat - 35.0)
  let dlng = _transformlng(lng - 105.0, lat - 35.0)
  const radlat = lat / 180.0 * PI
  let magic = Math.sin(radlat)
  magic = 1 - ee * magic * magic
  const sqrtmagic = Math.sqrt(magic)
  dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI)
  dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI)
  const mglat = lat + dlat
  const mglng = lng + dlng
  return [mglng, mglat]
}

export function gcj02towgs84 (lng, lat) {
  lat = +lat
  lng = +lng
  if (outOfChina(lng, lat)) {
    return [lng, lat]
  }
  let dlat = _transformlat(lng - 105.0, lat - 35.0)
  let dlng = _transformlng(lng - 105.0, lat - 35.0)
  const radlat = lat / 180.0 * PI
  let magic = Math.sin(radlat)
  magic = 1 - ee * magic * magic
  const sqrtmagic = Math.sqrt(magic)
  dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI)
  dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI)
  const mglat = lat + dlat
  const mglng = lng + dlng
  return [lng * 2 - mglng, lat * 2 - mglat]
}

const _transformlat = function (lng, lat) {
  let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng))
  ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
  ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0
  ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0
  return ret
}
const _transformlng = function (lng, lat) {
  let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))
  ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
  ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0
  ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0
  return ret
}

const outOfChina = function (lng, lat) {
  return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false)
}

export function getScreenInfo () {
  const {
    resolutionWidth,
    resolutionHeight
  } = plus.screen.getCurrentSize()
  return {
    screenWidth: Math.round(resolutionWidth),
    screenHeight: Math.round(resolutionHeight)
  }
}

export function warpPlusEvent (module, name) {
  return function (callbackId) {
    plus[module][name](function (data) {
      if (data) {
        delete data.code
        delete data.message
      }
      invoke(callbackId, data)
    })
  }
}

export function warpPlusSuccessCallback (callbackId, name) {
  return function errorCallback (result) {
    result = result || {}
    invoke(callbackId, Object.assign({}, result, {
      errMsg: `${name}:ok`
    }))
  }
}

export function warpPlusErrorCallback (callbackId, name, errMsg) {
  return function errorCallback (error) {
    error = error || {}
    const code = error.code || 0
    invoke(callbackId, {
      errMsg: `${name}:fail ${error.message || errMsg || ''}`,
      errCode: code,
      code
    })
  }
}

export function warpPlusMethod (module, name, before) {
  return function (options, callbackId) {
    if (typeof before === 'function') {
      options = before(options)
    }
    plus[module][name](Object.assign(options, {
      success (data = {}) {
        delete data.code
        delete data.message
        invoke(callbackId, Object.assign({}, data, {
          errMsg: `${name}:ok`
        }))
      },
      fail: warpPlusErrorCallback(callbackId, name)
    }))
  }
}

export function getFileName (path) {
  const array = path.split('/')
  return array[array.length - 1]
}

export function getExtName (path) {
  const array = path.split('.')
  return array.length > 1 ? '.' + array[array.length - 1] : ''
}
<commit_msg>feat(app): 一键登录errorCallback新增 appid、metadata、uid 参数返回<commit_after>import {
  invoke
} from '../bridge'

export {
  isTabBarPage
}
  from '../bridge'

export function callApiSync (api, args, name, alias) {
  const ret = api(args)
  if (ret && ret.errMsg) {
    ret.errMsg = ret.errMsg.replace(name, alias)
  }
  return ret
}

export function getWebview (__page__) {
  if (__page__) {
    return __page__.$getAppWebview()
  }
  return getLastWebview()
}

export function getLastWebview () {
  try {
    const pages = getCurrentPages()
    if (pages.length) {
      return pages[pages.length - 1].$getAppWebview()
    }
  } catch (e) {
    if (process.env.NODE_ENV !== 'production') {
      console.log('getCurrentPages is not ready')
    }
  }
}

const getRealRoute = (e, t) => {
  if (t.indexOf('./') === 0) return getRealRoute(e, t.substr(2), !1)
  let n
  let i
  const o = t.split('/')
  for (n = 0, i = o.length; n < i && o[n] === '..'; n++);
  o.splice(0, n)
  t = o.join('/')
  const r = e.length > 0 ? e.split('/') : []
  r.splice(r.length - n - 1, n + 1)
  return r.concat(o).join('/')
}

// 处理 Android 平台解压与非解压模式下获取的路径不一致的情况
const _handleLocalPath = filePath => {
  const localUrl = plus.io.convertLocalFileSystemURL(filePath)
  return localUrl.replace(/^\/?apps\//, '/android_asset/apps/').replace(/\/$/, '')
}

export function getRealPath (filePath) {
  const SCHEME_RE = /^([a-z-]+:)?\/\//i
  const DATA_RE = /^data:.*,.*/

  // 无协议的情况补全 https
  if (filePath.indexOf('//') === 0) {
    filePath = 'https:' + filePath
  }

  // 网络资源或base64
  if (SCHEME_RE.test(filePath) || DATA_RE.test(filePath)) {
    return filePath
  }

  if (filePath.indexOf('_www') === 0 || filePath.indexOf('_doc') === 0 || filePath.indexOf('_documents') === 0 ||
    filePath.indexOf('_downloads') === 0) {
    return 'file://' + _handleLocalPath(filePath)
  }
  const wwwPath = 'file://' + _handleLocalPath('_www')
  // 绝对路径转换为本地文件系统路径
  if (filePath.indexOf('/') === 0) {
    return wwwPath + filePath
  }
  // 相对资源
  if (filePath.indexOf('../') === 0 || filePath.indexOf('./') === 0) {
    if (typeof __id__ === 'string') {
      return wwwPath + getRealRoute('/' + __id__, filePath)
    } else {
      const pages = getCurrentPages()
      if (pages.length) {
        return wwwPath + getRealRoute('/' + pages[pages.length - 1].route, filePath)
      }
    }
  }
  return filePath
}

export function getStatusBarStyle () {
  let style = plus.navigator.getStatusBarStyle()
  if (style === 'UIStatusBarStyleBlackTranslucent' || style === 'UIStatusBarStyleBlackOpaque' || style === 'null') {
    style = 'light'
  } else if (style === 'UIStatusBarStyleDefault') {
    style = 'dark'
  }
  return style
}

const PI = 3.1415926535897932384626
const a = 6378245.0
const ee = 0.00669342162296594323

export function wgs84togcj02 (lng, lat) {
  lat = +lat
  lng = +lng
  if (outOfChina(lng, lat)) {
    return [lng, lat]
  }
  let dlat = _transformlat(lng - 105.0, lat - 35.0)
  let dlng = _transformlng(lng - 105.0, lat - 35.0)
  const radlat = lat / 180.0 * PI
  let magic = Math.sin(radlat)
  magic = 1 - ee * magic * magic
  const sqrtmagic = Math.sqrt(magic)
  dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI)
  dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI)
  const mglat = lat + dlat
  const mglng = lng + dlng
  return [mglng, mglat]
}

export function gcj02towgs84 (lng, lat) {
  lat = +lat
  lng = +lng
  if (outOfChina(lng, lat)) {
    return [lng, lat]
  }
  let dlat = _transformlat(lng - 105.0, lat - 35.0)
  let dlng = _transformlng(lng - 105.0, lat - 35.0)
  const radlat = lat / 180.0 * PI
  let magic = Math.sin(radlat)
  magic = 1 - ee * magic * magic
  const sqrtmagic = Math.sqrt(magic)
  dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI)
  dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI)
  const mglat = lat + dlat
  const mglng = lng + dlng
  return [lng * 2 - mglng, lat * 2 - mglat]
}

const _transformlat = function (lng, lat) {
  let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng))
  ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
  ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0
  ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0
  return ret
}
const _transformlng = function (lng, lat) {
  let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))
  ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
  ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0
  ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0
  return ret
}

const outOfChina = function (lng, lat) {
  return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false)
}

export function getScreenInfo () {
  const {
    resolutionWidth,
    resolutionHeight
  } = plus.screen.getCurrentSize()
  return {
    screenWidth: Math.round(resolutionWidth),
    screenHeight: Math.round(resolutionHeight)
  }
}

export function warpPlusEvent (module, name) {
  return function (callbackId) {
    plus[module][name](function (data) {
      if (data) {
        delete data.code
        delete data.message
      }
      invoke(callbackId, data)
    })
  }
}

export function warpPlusSuccessCallback (callbackId, name) {
  return function errorCallback (result) {
    result = result || {}
    invoke(callbackId, Object.assign({}, result, {
      errMsg: `${name}:ok`
    }))
  }
}

export function warpPlusErrorCallback (callbackId, name, errMsg) {
  return function errorCallback (error) {
    error = error || {}
    // 一键登录errorCallback新增 appid、metadata、uid 参数返回
    const { code = 0, message: errorMessage, ...extraData } = error
    invoke(callbackId, {
      errMsg: `${name}:fail ${errorMessage || errMsg || ''}`,
      errCode: code,
      code,
      ...extraData
    })
  }
}

export function warpPlusMethod (module, name, before) {
  return function (options, callbackId) {
    if (typeof before === 'function') {
      options = before(options)
    }
    plus[module][name](Object.assign(options, {
      success (data = {}) {
        delete data.code
        delete data.message
        invoke(callbackId, Object.assign({}, data, {
          errMsg: `${name}:ok`
        }))
      },
      fail: warpPlusErrorCallback(callbackId, name)
    }))
  }
}

export function getFileName (path) {
  const array = path.split('/')
  return array[array.length - 1]
}

export function getExtName (path) {
  const array = path.split('.')
  return array.length > 1 ? '.' + array[array.length - 1] : ''
}
<|endoftext|>


<commit_before>import React from 'react';
import cx from 'classnames';
import { area } from 'd3-shape';

export default function AreaClosed({
  x,
  y,
  xScale,
  yScale,
  data,
  defined,
  className,
  strokeDasharray,
  strokeWidth = 2,
  stroke = 'black',
  fill = rgba(0,0,0,0.3),
  curve,
  ...restProps,
}) {
  const path = area()
    .x(d => xScale(x(d)))
    .y0(yScale(0))
    .y1(d => yScale(y(d)))
    .defined(defined || (d => y(d) && x(d)));
  if (curve) path.curve(curve);
  return (
    <g>
      <path
        className={cx('vx-area-closed', className)}
        d={path(data)}
        stroke={stroke}
        strokeWidth={strokeWidth}
        strokeDasharray={strokeDasharray}
        fill={fill}
        {...restProps}
      />
    </g>
  );
}
<commit_msg>Get y0 based on domain of the y scale<commit_after>import React from 'react';
import cx from 'classnames';
import { area } from 'd3-shape';

export default function AreaClosed({
  x,
  y,
  xScale,
  yScale,
  data,
  defined,
  className,
  strokeDasharray,
  strokeWidth = 2,
  stroke = 'black',
  fill = rgba(0,0,0,0.3),
  curve,
  ...restProps,
}) {
  const path = area()
    .x(d => xScale(x(d)))
    .y0(yScale(yScale.domain()[0]))
    .y1(d => yScale(y(d)))
    .defined(defined || (d => y(d) && x(d)));
  if (curve) path.curve(curve);
  return (
    <g>
      <path
        className={cx('vx-area-closed', className)}
        d={path(data)}
        stroke={stroke}
        strokeWidth={strokeWidth}
        strokeDasharray={strokeDasharray}
        fill={fill}
        {...restProps}
      />
    </g>
  );
}
<|endoftext|>


<commit_before>
var createClass = require('../functions/createClass');
var convertValueType = require('../functions/convertValueType');
var Binder = require('../Binder');
var View = require('../View');
var Cursor = require('../Cursor');

var createClassBinder = function(negate)
{
	var ClassBinder = createClass(
	{
		extend: Binder
	},
	/** @lends ClassBinder.prototype */
	{
		/**
		 * One-way data binder (model to DOM) for CSS class.
		 * Sets/Unsets the class of the element to some predefined value when model atrribute changes.
		 *
		 * @constructs
		 * @augments Binder
		 * @param {Object} options Options objectt
		 */
		constructor: function(options)
		{
			Binder.call(this, options);
		},

		init: function()
		{
			this.className = this.options.params[0] || null;
			this.equalsTo = true;
			this.valueCursor = undefined;

			if(this.options.params[1])
			{
				this.equalsTo = this.convertBindingValue(this.options.params[1]);
				if(this.equalsTo instanceof Cursor)
				{
					this.valueCursor = this.equalsTo;
					this.equalsTo = this.valueCursor.get();
				}
				if(this.equalsTo == null) this.equalsTo = null;
			}

			this.negate = this.options.params[2] === 'ne' || negate;

			ClassBinder._super.init.call(this);
		},

		refresh: function()
		{
			if(this.className)
			{
				if(this.matchValue())
				{
					this.$element[0].classList.add(this.className);
				}
				else
				{
					this.$element[0].classList.remove(this.className);
				}
			}
		},

		matchValue: function()
		{
			if(this.options.params.length > 1)
			{
				if(this.valueCursor)
				{
					this.equalsTo = this.valueCursor.get();
					if(this.equalsTo == null) this.equalsTo = null;
				}
				var value = this.value;
				if(value == null) value = null;
				if(this.negate) return value !== this.equalsTo;
				else return value === this.equalsTo;
			}
			else return this.value;
		}
	});

	if(typeof document === 'object' && document !== null)
	{
		if(!('classList' in document.documentElement))
		{
			ClassBinder.prototype.refresh = function(value)
			{
				if(this.className)
				{
					this.$element[this.matchValue() ? 'addClass' : 'removeClass'](this.className);
				}
			};
		}
	}

	return ClassBinder;

};

var ClassBinder = createClassBinder(false);
var ClassNotBinder = createClassBinder(true);

View.registerBinder('class', ClassBinder);
View.registerBinder('classnot', ClassNotBinder);

module.exports = {
	ClassBinder: ClassBinder,
	ClassNotBinder: ClassNotBinder
};
<commit_msg>refactor(ClassBinder): declare class properties in constructor (it should help Chrome to use hidden classes)<commit_after>
var createClass = require('../functions/createClass');
var convertValueType = require('../functions/convertValueType');
var Binder = require('../Binder');
var View = require('../View');
var Cursor = require('../Cursor');

var createClassBinder = function(negate)
{
	var ClassBinder = createClass(
	{
		extend: Binder
	},
	/** @lends ClassBinder.prototype */
	{
		/**
		 * One-way data binder (model to DOM) for CSS class.
		 * Sets/Unsets the class of the element to some predefined value when model atrribute changes.
		 *
		 * @constructs
		 * @augments Binder
		 * @param {Object} options Options objectt
		 */
		constructor: function(options)
		{
			Binder.call(this, options);

			this.className = undefined;
			this.equalsTo = undefined;
			this.valueCursor = undefined;
		},

		init: function()
		{
			this.className = this.options.params[0] || null;
			this.equalsTo = true;
			this.valueCursor = undefined;

			if(this.options.params[1])
			{
				this.equalsTo = this.convertBindingValue(this.options.params[1]);
				if(this.equalsTo instanceof Cursor)
				{
					this.valueCursor = this.equalsTo;
					this.equalsTo = this.valueCursor.get();
				}
				if(this.equalsTo == null) this.equalsTo = null;
			}

			this.negate = this.options.params[2] === 'ne' || negate;

			ClassBinder._super.init.call(this);
		},

		refresh: function()
		{
			if(this.className)
			{
				if(this.matchValue())
				{
					this.$element[0].classList.add(this.className);
				}
				else
				{
					this.$element[0].classList.remove(this.className);
				}
			}
		},

		matchValue: function()
		{
			if(this.options.params.length > 1)
			{
				if(this.valueCursor)
				{
					this.equalsTo = this.valueCursor.get();
					if(this.equalsTo == null) this.equalsTo = null;
				}
				var value = this.value;
				if(value == null) value = null;
				if(this.negate) return value !== this.equalsTo;
				else return value === this.equalsTo;
			}
			else return this.value;
		}
	});

	if(typeof document === 'object' && document !== null)
	{
		if(!('classList' in document.documentElement))
		{
			ClassBinder.prototype.refresh = function(value)
			{
				if(this.className)
				{
					this.$element[this.matchValue() ? 'addClass' : 'removeClass'](this.className);
				}
			};
		}
	}

	return ClassBinder;

};

var ClassBinder = createClassBinder(false);
var ClassNotBinder = createClassBinder(true);

View.registerBinder('class', ClassBinder);
View.registerBinder('classnot', ClassNotBinder);

module.exports = {
	ClassBinder: ClassBinder,
	ClassNotBinder: ClassNotBinder
};
<|endoftext|>


<commit_before>const {
  optimize: { UglifyJsPlugin },
} = require('webpack');

module.exports = (config) => {
  const hasSourceMap =
    config.devtool && ~config.devtool.indexOf('source-map');

  config.plugins = [
    ...config.plugins,
    new UglifyJsPlugin({
      sourceMap: hasSourceMap,
      comments: false,
      mangle: true,
      mangle: {
        except: [],
      },
      compress: {
        booleans: true,
        dead_code: true,
        drop_console: true,
        drop_debugger: true,
        loops: true,
        pure_getters: true,
        screw_ie8: true,
        sequences: true,
        unsafe: true,
        unsafe_comps: true,
        unused: true,
        warnings: false,
      },
    }),
  ];

  return config;
};
<commit_msg>Improve Uglify configuration<commit_after>const {
  optimize: { UglifyJsPlugin },
} = require('webpack');

function isSourceMap({ devtool }) {
  return devtool &&
    devtool.indexOf('source-map') >= 0;
}

module.exports = (config) => {
  config.plugins = [
    ...config.plugins,
    new UglifyJsPlugin({
      sourceMap: isSourceMap(config),
      comments: false,
      mangle: true,
      mangle: {
        except: [],
      },
      compress: {
        booleans: true,
        dead_code: true,
        drop_console: true,
        drop_debugger: true,
        loops: true,
        pure_getters: true,
        screw_ie8: true,
        sequences: true,
        unsafe: true,
        unsafe_comps: true,
        unused: true,
        warnings: false,
      },
    }),
  ];

  return config;
};
<|endoftext|>


<commit_before>/* The Calendar Cycle Computation Engine (CCCE)
// (Formerly Milesian Compose and Decompose routines).
// Character set is UTF-8
//
// The functions of this package performs intercalation computations for calendars
// that set intercalation elements following regular cycles.
// The Milesian calendar, given its regulars month, is able to use totally this principle.
// For other calendars, including Gregorian and Julian, this routines may be used to compute
// the rank of a day within a year, and then hours, minutes, seconds and milliseconds.
// Computations on months require more specific algorithms.
// The principles of these routines are explained in "L'heure milésienne",
// a book by Louis-Aimé de Fouquières.
//
// Version 2 : M2017-06-21
// Version 2:
//	Changed the names of the functions
//	The parameters are now in each package. Only very common parameters and variables are defined here.
// Version 2.1 : M2017-12-14 (typos in commments)
//
*//////////////////////////////////////////////////////////////////////////////////////////////
/* Copyright Miletus 2016-2017 - Louis A. de Fouquières
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 1. The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// 2. Changes with respect to any former version shall be documented.
//
// The software is provided "as is", without warranty of any kind,
// express of implied, including but not limited to the warranties of
// merchantability, fitness for a particular purpose and noninfringement.
// In no event shall the authors of copyright holders be liable for any
// claim, damages or other liability, whether in an action of contract,
// tort or otherwise, arising from, out of or in connection with the software
// or the use or other dealings in the software.
// Inquiries: www.calendriermilesien.org
*////////////////////////////////////////////////////////////////////////////////
var Chronos = { // Set of chronological constants generally used when handling Unix dates.
  DAY_UNIT : 86400000, // One day in Unix time units
  HOUR_UNIT : 3600000,
  MINUTE_UNIT : 60000,
  SECOND_UNIT : 1000
}
/* Parameter object structure. Replace # with numbers or literals.
var decomposeParameterExample = {
	timeepoch : #, origin time in milliseconds (or in the suitable unit) to be used for the decomposition, with respect to 1/1/1970 00:00 UTC.
	coeff : [ // This array holds the coefficient used to decompose a time stamp into time cycles like eras, quadrisaeculae, centuries etc.
		{cyclelength : #, //length of the cycle, expressed in milliseconds.
		ceiling : #, // Infinity, or the maximum number of cycles of this size minus one in the upper cycle; the last cycle may hold an intercalary unit.
		multiplier : #, // multiplies the number of cycle of this level to convert into target units.
		target : #, // the unit (e.g. "year") of the decomposition element at this level.
		} ,
		{ // similar elements at the lower cycle level
		} // end of array element
	], // End of this array, but not end of object
	canvas : [ // this last array is the canvas of the decomposition , e.g. "year", "month", "date", with suitable properties at each level.
		{ name : #, // the name of the property at this level, which must match one target property of the coeff component,
		init : #, // value of this component at epoch, and lowest value (except for the first component), e.g. 0 for month, 1 for date, 0 for hours, minutes, seconds.
		} // End of array element (only two properties)
	] // End of second array
}	// End of object.
// Constraints:
//	1. 	The cycles and the canvas elements shall be definined from the larger to the smaller
//		e.g. quadrisaeculum, then century, then quadriannum, then year, etc.
//	2. 	The same names shall bu used for the "coeff" and the "canvas" properties, elsewise applications may return "NaN".
//
*/
var
Day_milliseconds = { 	// To convert a time or a duration to and from days + milliseconds in day.
	timeepoch : 0,
	coeff : [ // to be used with a Unix timestamp in ms. Decompose into days and milliseconds in day.
	  {cyclelength : 86400000, ceiling : Infinity, multiplier : 1, target : "day_number"},
	  {cyclelength : 1, ceiling : Infinity, multiplier : 1, target : "milliseconds_in_day"}
	],
	canvas : [
		{name : "day_number", init : 0},
		{name : "milliseconds_in_day", init : 0},
	]
}
/////////////////////////////////////////////
// ccceDecompose : from time serie figure to decomposition
/////////////////////////////////////////////
function ccceDecompose (quantity, params) { // from a chronological number, build an compound object holding the elements as required by cparams.
  quantity -= params.timeepoch; // set quantity to decompose into cycles to the right value.
  var result = new Object(); // Construct intitial result
  for (let i = 0; i < params.canvas.length; i++) {	// Define property of result object (a date or date-time)
    Object.defineProperty (result, params.canvas[i].name, {enumerable : true, writable : true, value : params.canvas[i].init});
  }
  for (let i = 0; i < params.coeff.length; ++i) {	// Perform decomposition by dividing by the successive cycle length
    let r = 0; // r is the computed quotient for this level of decomposition
    if (params.coeff[i].cyclelength == 1) r = quantity; // avoid performing a trivial divison by 1.
    else {		// at each level, search at the same time the quotient (r) and the modulus (quantity)
      while (quantity < 0) {
        --r;
        quantity += params.coeff[i].cyclelength;
      }
      while ((quantity >= params.coeff[i].cyclelength) && (r < params.coeff[i].ceiling)) {
        ++r;
        quantity -= params.coeff[i].cyclelength;
      }
    }
    result[params.coeff[i].target] += r*params.coeff[i].multiplier; // add result to suitable part of result array
  }
  return result;
}
////////////////////////////////////////////
// ccceCompose: from compound object to time serie figure.
////////////////////////////////////////////
function ccceCompose (cells, params) { // from an object 'cells' structured as params.canvas, compute the chronological number
	var quantity = params.timeepoch ; // initialise quantity
	for (let i = 0; i < params.canvas.length; i++) { // cells value shifted as to have all 0 if at epoch
		cells[params.canvas[i].name] -= params.canvas[i].init
	}
	for (let i = params.coeff.length-1; i >= 0; --i) { // consolidate from small to large
		let factor = (params.coeff[i].multiplier == 1 ? params.coeff[i].cyclelength :
		params.coeff[i].cyclelength -
									(params.coeff[i+1].cyclelength * params.coeff[i].multiplier / params.coeff[i+1].multiplier )
									);
		quantity += Math.floor(cells[params.coeff[i].target] / params.coeff[i].multiplier) * factor;
	}
	return quantity ;
}
<commit_msg>Replaced with CBCCE<commit_after><|endoftext|>