<commit_before>
/* global v3index:false */
/* exported v3index */

(function(){

/* variables */
var v3index = {
	typelist : [],
	current  : '',
	doclang  : 'ja',
	complete : false,
	captions : [],
	extend : function(obj){ for(var n in obj){ this[n] = obj[n];}}
};

var _doc = document;
var self = v3index;
var typelist = self.typelist;

function getEL(id){ return _doc.getElementById(id);}

v3index.extend({
	/* common function */
	addEvent : function(element,type,func,capt){
		if(!!element.addEventListener){ element.addEventListener(type,func,!!capt);}
		else if(!!element.attachEvent){ element.attachEvent("on"+type,func);}
		else                          { element["on"+type] = func;}
	},

	/* onload function */
	onload_include : function(){
		setTimeout(function(){
			if(!window.pzpr){ setTimeout(arguments.callee,50); return;}
			self.onload_func();
			self.complete = true;
		},10);
	},
	onload_func : function(){
		self.doclang = require('ipc').sendSync('get-pref').lang;
		if(!self.current){
			self.input_init();
			self.setTabEvent();
			self.setDragDropEvent();
			self.setTranslation();
			self.setAccordion();
			require('ipc').send('pzpr-version', pzpr.version);
		}
		self.disp();
	},
	input_init : function(){
		return +self.urlif.init();
	},

	reset_func : function(){
		typelist = [];
		self.current  = '';
		self.onload_func();
	},

	/* tab-click function */
	click_tab : function(e){
		var el = (e.target || e.srcElement);
		if(!!el){ self.current = el.id.substr(8); self.disp();}
	},

	/* display tabs and tables function */
	disp : function(){
		for(var i=0;i<typelist.length;i++){
			var el = getEL("puzmenu_"+typelist[i]);
			var table = getEL("table_"+typelist[i]);
			if(typelist[i]===self.current){
				el.className = "puzmenusel";
				table.style.display = 'table';
			}
			else{
				el.className = "puzmenu";
				table.style.display = 'none';
			}
		}
		self.translate();
	},

	/* open new puzzle window as Electron manner */
	openpuzzle : function(data){
		require('ipc').send('open-puzzle', data);
	},

	setTabEvent : function(){
		if(!getEL("puztypes")){
			getEL("table_all").style.display = "table";
			return;
		}
		var el = getEL("puztypes").firstChild;
		while(!!el){
			if(!!el.tagName && el.tagName.toLowerCase()==='li' &&
				!!el.id      && el.id.match(/puzmenu_(.+)$/)){
				var typename = RegExp.$1;
				typelist.push(typename);
				self.addEvent(el,"click",self.click_tab);
				if(el.className==="puzmenusel"){ self.current = typename;}
			}
			el = el.nextSibling;
		}
		if(!self.current && typelist.length>0){ self.current = typelist[0];}
		getEL("puztypes").style.display = "block";
	},

	setDragDropEvent : function(){
		// File API＋Drag&Drop APIの設定
		this.addEvent(window, 'dragover', function(e){ e.preventDefault();}, true);
		this.addEvent(window, 'drop', function(e){
			var reader = new FileReader();
			reader.onload = function(e){ v3index.openpuzzle(e.target.result);};
			reader.readAsText(e.dataTransfer.files[0]);
			e.preventDefault();
			e.stopPropagation();
		}, true);
	},

	setTranslation : function(){
		var els = [_doc.getElementById("table_all")];
		while(els.length>0){
			var el = els.pop();
			if(!el){ continue;}
			if(el.nodeType===1 && el.nodeName==="LI"){
				var href = el.firstChild.href;
				var pid  = pzpr.variety.toPID(href.substr(href.indexOf("?")+1));
				self.captions.push({textnode:el.firstChild.firstChild, str_ja:pzpr.variety.info[pid].ja, str_en:pzpr.variety.info[pid].en});
			}
			else if(el.nodeType===3 && el.data.match(/^__(.+)__(.+)__$/)){
				self.captions.push({textnode:el, str_ja:RegExp.$1, str_en:RegExp.$2});
			}
			if(!!el.nextSibling){ els.push(el.nextSibling);}
			if(el.childNodes.length>0){ els.push(el.firstChild);}
		}
	},
	translate : function(){
		/* キャプションの設定 */
		for(var i=0;i<this.captions.length;i++){
			var obj = this.captions[i];
			if(!!obj.textnode){ obj.textnode.data = obj['str_'+self.doclang];}
		}
	},

	setAccordion : function(){
		var trs = Array.prototype.slice.call(_doc.querySelectorAll('.accordion'));
		trs.forEach(function(tr){
			tr.addEventListener('click', function(e){
				var next = tr.nextElementSibling;
				if(next.style.display==='none'){
					tr.querySelector('span').className = 'triangle-open';
					next.style.display = '';
				}
				else{
					tr.querySelector('span').className = 'triangle-close';
					next.style.display = 'none';
				}
				e.stopPropagation();
			}, true);
		});
	}
});

/* addEventListener */
self.addEvent(window, 'load', self.onload_include);

/* extern */
window.v3index = v3index;

})();

require('ipc').on('config-req', function(req){
	if(req.match(/language\:(.+)/)){
		v3index.doclang = RegExp.$1;
		v3index.translate();
	}
});

/*********************/
/* URLInput function */
/*********************/
(function(){

var v3index = window.v3index;

v3index.urlif = {
	extend : function(obj){ for(var n in obj){ this[n] = obj[n];}}
};

var _doc = document;
var _form;
var self = v3index.urlif;

function getEL(id){ return _doc.getElementById(id);}

v3index.urlif.extend({
	init : function(){
		_form = _doc.urlinput;
		if(!!_form){
			v3index.addEvent(getEL("urlinput_btn"), "click", self.urlinput);
			return true;
		}
	},
	urlinput : function(e){
		var url = getEL("urlinput_text").value;
		if(!!url){ v3index.openpuzzle(url);}
	}
});

})();
<commit_msg>v3index: Remove unused url input handling routine which was deleted before<commit_after>
/* global v3index:false */
/* exported v3index */

(function(){

/* variables */
var v3index = {
	typelist : [],
	current  : '',
	doclang  : 'ja',
	complete : false,
	captions : [],
	extend : function(obj){ for(var n in obj){ this[n] = obj[n];}}
};

var _doc = document;
var self = v3index;
var typelist = self.typelist;

function getEL(id){ return _doc.getElementById(id);}

v3index.extend({
	/* common function */
	addEvent : function(element,type,func,capt){
		if(!!element.addEventListener){ element.addEventListener(type,func,!!capt);}
		else if(!!element.attachEvent){ element.attachEvent("on"+type,func);}
		else                          { element["on"+type] = func;}
	},

	/* onload function */
	onload_include : function(){
		setTimeout(function(){
			if(!window.pzpr){ setTimeout(arguments.callee,50); return;}
			self.onload_func();
			self.complete = true;
		},10);
	},
	onload_func : function(){
		self.doclang = require('ipc').sendSync('get-pref').lang;
		if(!self.current){
			self.setTabEvent();
			self.setDragDropEvent();
			self.setTranslation();
			self.setAccordion();
			require('ipc').send('pzpr-version', pzpr.version);
		}
		self.disp();
	},

	reset_func : function(){
		typelist = [];
		self.current  = '';
		self.onload_func();
	},

	/* tab-click function */
	click_tab : function(e){
		var el = (e.target || e.srcElement);
		if(!!el){ self.current = el.id.substr(8); self.disp();}
	},

	/* display tabs and tables function */
	disp : function(){
		for(var i=0;i<typelist.length;i++){
			var el = getEL("puzmenu_"+typelist[i]);
			var table = getEL("table_"+typelist[i]);
			if(typelist[i]===self.current){
				el.className = "puzmenusel";
				table.style.display = 'table';
			}
			else{
				el.className = "puzmenu";
				table.style.display = 'none';
			}
		}
		self.translate();
	},

	/* open new puzzle window as Electron manner */
	openpuzzle : function(data){
		require('ipc').send('open-puzzle', data);
	},

	setTabEvent : function(){
		if(!getEL("puztypes")){
			getEL("table_all").style.display = "table";
			return;
		}
		var el = getEL("puztypes").firstChild;
		while(!!el){
			if(!!el.tagName && el.tagName.toLowerCase()==='li' &&
				!!el.id      && el.id.match(/puzmenu_(.+)$/)){
				var typename = RegExp.$1;
				typelist.push(typename);
				self.addEvent(el,"click",self.click_tab);
				if(el.className==="puzmenusel"){ self.current = typename;}
			}
			el = el.nextSibling;
		}
		if(!self.current && typelist.length>0){ self.current = typelist[0];}
		getEL("puztypes").style.display = "block";
	},

	setDragDropEvent : function(){
		// File API＋Drag&Drop APIの設定
		this.addEvent(window, 'dragover', function(e){ e.preventDefault();}, true);
		this.addEvent(window, 'drop', function(e){
			var reader = new FileReader();
			reader.onload = function(e){ v3index.openpuzzle(e.target.result);};
			reader.readAsText(e.dataTransfer.files[0]);
			e.preventDefault();
			e.stopPropagation();
		}, true);
	},

	setTranslation : function(){
		var els = [_doc.getElementById("table_all")];
		while(els.length>0){
			var el = els.pop();
			if(!el){ continue;}
			if(el.nodeType===1 && el.nodeName==="LI"){
				var href = el.firstChild.href;
				var pid  = pzpr.variety.toPID(href.substr(href.indexOf("?")+1));
				self.captions.push({textnode:el.firstChild.firstChild, str_ja:pzpr.variety.info[pid].ja, str_en:pzpr.variety.info[pid].en});
			}
			else if(el.nodeType===3 && el.data.match(/^__(.+)__(.+)__$/)){
				self.captions.push({textnode:el, str_ja:RegExp.$1, str_en:RegExp.$2});
			}
			if(!!el.nextSibling){ els.push(el.nextSibling);}
			if(el.childNodes.length>0){ els.push(el.firstChild);}
		}
	},
	translate : function(){
		/* キャプションの設定 */
		for(var i=0;i<this.captions.length;i++){
			var obj = this.captions[i];
			if(!!obj.textnode){ obj.textnode.data = obj['str_'+self.doclang];}
		}
	},

	setAccordion : function(){
		var trs = Array.prototype.slice.call(_doc.querySelectorAll('.accordion'));
		trs.forEach(function(tr){
			tr.addEventListener('click', function(e){
				var next = tr.nextElementSibling;
				if(next.style.display==='none'){
					tr.querySelector('span').className = 'triangle-open';
					next.style.display = '';
				}
				else{
					tr.querySelector('span').className = 'triangle-close';
					next.style.display = 'none';
				}
				e.stopPropagation();
			}, true);
		});
	}
});

/* addEventListener */
self.addEvent(window, 'load', self.onload_include);

/* extern */
window.v3index = v3index;

})();

require('ipc').on('config-req', function(req){
	if(req.match(/language\:(.+)/)){
		v3index.doclang = RegExp.$1;
		v3index.translate();
	}
});
<|endoftext|>


<commit_before>var FG = L.FeatureGroup,
    FGproto = FG.prototype,
    LG = L.LayerGroup;

var Plugin = FG.SubGroup = FG.extend({

    statics: {
        version: "1.0.0"
    },

    /**
     * Instantiates a SubGroup.
     * @param parentGroup (L.LayerGroup) (optional)
     * @param layersArray (L.Layer[]) (optional)
     */
    initialize: function (parentGroup, layersArray) {
        FGproto.initialize.call(this, layersArray);

        this.setParentGroup(parentGroup);
    },

    /**
     * Changes the parent group into which child markers are added to /
     * removed from.
     * @param parentGroup (L.LayerGroup)
     * @returns {Plugin} this
     */
    setParentGroup: function (parentGroup) {
        var pgInstanceOfLG = parentGroup instanceof LG;

        this._parentGroup = parentGroup;

        // onAdd
        this.onAdd =
            pgInstanceOfLG ?
                (
                    typeof parentGroup.addLayers === "function" ?
                        this._onAddToGroupBatch :
                        this._onAddToGroup
                ) :
                this._onAddToMap;

        // onRemove
        this.onRemove =
            pgInstanceOfLG ?
                (
                    typeof parentGroup.removeLayers === "function" ?
                        this._onRemoveFromGroupBatch :
                        this._onRemoveFromGroup
                ) :
                this._onRemoveFromMap;

        // addLayer
        this.addLayer = pgInstanceOfLG ?
            this._addLayerToGroup :
            this._addLayerToMap;

        // removeLayer
        this.removeLayer = pgInstanceOfLG ?
            this._removeLayerFromGroup :
            this._removeLayerFromMap;

        return this;
    },

    /**
     * Removes the current sub-group from map before changing the parent
     * group. Re-adds the sub-group to map if it was before changing.
     * @param parentGroup (L.LayerGroup)
     * @returns {Plugin} this
     */
    setParentGroupSafe: function (parentGroup) {
        var map = this._map;

        if (map) {
            map.removeLayer(this);
        }

        this.setParentGroup(parentGroup);

        if (map) {
            map.addLayer(this);
        }

        return this;
    },

    /**
     * Returns the current parent group.
     * @returns {*}
     */
    getParentGroup: function () {
        return this._parentGroup;
    },

    // For parent groups with batch methods (addLayers and removeLayers)
    // like MarkerCluster.
    _onAddToGroupBatch: function (map) {
        var layersArray = this.getLayers();

        this._map = map;
        this._parentGroup.addLayers(layersArray);
    },

    _onRemoveFromGroupBatch: function () {
        var layersArray = this.getLayers();

        this._parentGroup.removeLayers(layersArray);
        this._map = null;
    },

    // For other parent layer groups.
    _onAddToGroup: function (map) {
        var parentGroup = this._parentGroup;

        this._map = map;
        this.eachLayer(parentGroup.addLayer, parentGroup);
    },

    _onRemoveFromGroup: function () {
        var parentGroup = this._parentGroup;

        this.eachLayer(parentGroup.removeLayer, parentGroup);
        this._map = null;
    },

    // Defaults to standard FeatureGroup behaviour when parent group is not
    // specified or is not a type of LayerGroup.
    _onAddToMap: FGproto.onAdd,
    _onRemoveFromMap: FGproto.onRemove,

    _addLayerToGroup: function (layer) {
        if (this.hasLayer(layer)) {
            return this;
        }

        layer.addEventParent(this);

        var id = this.getLayerId(layer);

        this._layers[id] = layer;

        if (this._map) {
            // Add to parent group instead of directly to map.
            this._parentGroup.addLayer(layer);
        }

        return this.fire("layeradd", {layer: layer});
    },

    _removeLayerFromGroup: function (layer) {
        if (!this.hasLayer(layer)) {
            return this;
        }
        if (layer in this._layers) {
            layer = this._layers[layer];
        }

                    layer.removeEventParent(this);

        var id = layer in this._layers ? layer : this.getLayerId(layer);

        if (this._map && this._layers[id]) {
            // Remove from parent group instead of directly from map.
            this._parentGroup.removeLayer(id);
        }

        delete this._layers[id];

        return this.fire("layerremove", {layer: layer});
    },

    // Defaults to standard FeatureGroup behaviour when parent group is not
    // specified or is not a type of LayerGroup.
    _addLayerToMap: FGproto.addLayer,
    _removeLayerFromMap: FGproto.removeLayer

});

// Supply with a factory for consistency with Leaflet.
L.featureGroup.subGroup = function (parentGroup, options) {
    return new FG.SubGroup(parentGroup, options);
};
<commit_msg>Remove some scope variables<commit_after>var Plugin = L.FeatureGroup.SubGroup = L.FeatureGroup.extend({

    statics: {
        version: "1.0.0"
    },

    /**
     * Instantiates a SubGroup.
     * @param parentGroup (L.LayerGroup) (optional)
     * @param layersArray (L.Layer[]) (optional)
     */
    initialize: function (parentGroup, layersArray) {
        L.FeatureGroup.prototype.initialize.call(this, layersArray);

        this.setParentGroup(parentGroup);
    },

    /**
     * Changes the parent group into which child markers are added to /
     * removed from.
     * @param parentGroup (L.LayerGroup)
     * @returns {Plugin} this
     */
    setParentGroup: function (parentGroup) {
        var pgInstanceOfLG = parentGroup instanceof L.LayerGroup;

        this._parentGroup = parentGroup;

        // onAdd
        this.onAdd =
            pgInstanceOfLG ?
                (
                    typeof parentGroup.addLayers === "function" ?
                        this._onAddToGroupBatch :
                        this._onAddToGroup
                ) :
                this._onAddToMap;

        // onRemove
        this.onRemove =
            pgInstanceOfLG ?
                (
                    typeof parentGroup.removeLayers === "function" ?
                        this._onRemoveFromGroupBatch :
                        this._onRemoveFromGroup
                ) :
                this._onRemoveFromMap;

        // addLayer
        this.addLayer = pgInstanceOfLG ?
            this._addLayerToGroup :
            this._addLayerToMap;

        // removeLayer
        this.removeLayer = pgInstanceOfLG ?
            this._removeLayerFromGroup :
            this._removeLayerFromMap;

        return this;
    },

    /**
     * Removes the current sub-group from map before changing the parent
     * group. Re-adds the sub-group to map if it was before changing.
     * @param parentGroup (L.LayerGroup)
     * @returns {Plugin} this
     */
    setParentGroupSafe: function (parentGroup) {
        var map = this._map;

        if (map) {
            map.removeLayer(this);
        }

        this.setParentGroup(parentGroup);

        if (map) {
            map.addLayer(this);
        }

        return this;
    },

    /**
     * Returns the current parent group.
     * @returns {*}
     */
    getParentGroup: function () {
        return this._parentGroup;
    },

    // For parent groups with batch methods (addLayers and removeLayers)
    // like MarkerCluster.
    _onAddToGroupBatch: function (map) {
        var layersArray = this.getLayers();

        this._map = map;
        this._parentGroup.addLayers(layersArray);
    },

    _onRemoveFromGroupBatch: function () {
        var layersArray = this.getLayers();

        this._parentGroup.removeLayers(layersArray);
        this._map = null;
    },

    // For other parent layer groups.
    _onAddToGroup: function (map) {
        var parentGroup = this._parentGroup;

        this._map = map;
        this.eachLayer(parentGroup.addLayer, parentGroup);
    },

    _onRemoveFromGroup: function () {
        var parentGroup = this._parentGroup;

        this.eachLayer(parentGroup.removeLayer, parentGroup);
        this._map = null;
    },

    // Defaults to standard FeatureGroup behaviour when parent group is not
    // specified or is not a type of LayerGroup.
    _onAddToMap: L.FeatureGroup.prototype.onAdd,
    _onRemoveFromMap: L.FeatureGroup.prototype.onRemove,

    _addLayerToGroup: function (layer) {
        if (this.hasLayer(layer)) {
            return this;
        }

        layer.addEventParent(this);

        var id = this.getLayerId(layer);

        this._layers[id] = layer;

        if (this._map) {
            // Add to parent group instead of directly to map.
            this._parentGroup.addLayer(layer);
        }

        return this.fire("layeradd", {layer: layer});
    },

    _removeLayerFromGroup: function (layer) {
        if (!this.hasLayer(layer)) {
            return this;
        }
        if (layer in this._layers) {
            layer = this._layers[layer];
        }

                    layer.removeEventParent(this);

        var id = layer in this._layers ? layer : this.getLayerId(layer);

        if (this._map && this._layers[id]) {
            // Remove from parent group instead of directly from map.
            this._parentGroup.removeLayer(id);
        }

        delete this._layers[id];

        return this.fire("layerremove", {layer: layer});
    },

    // Defaults to standard FeatureGroup behaviour when parent group is not
    // specified or is not a type of LayerGroup.
    _addLayerToMap: L.FeatureGroup.prototype.addLayer,
    _removeLayerFromMap: L.FeatureGroup.prototype.removeLayer

});

// Supply with a factory for consistency with Leaflet.
L.featureGroup.subGroup = function (parentGroup, options) {
    return new L.FeatureGroup.SubGroup(parentGroup, options);
};
<|endoftext|>


<commit_before>import {
  always,
  assocPartialU,
  identicalU,
  inherit,
  isArray,
  isObject
} from "infestines"
import {Observable, Property, combine} from "kefir"
import {get, modify, set} from "partial.lenses"

//

const header = "kefir.atom: "

function error(m) {
  throw new Error(header + m)
}

function errorGiven(m, o) {
  console.error(header + m + " - given:", o)
  error(m)
}

//

let lock = 0

const prevs = []
const atoms = []

function release() {
  while (prevs.length) {
    const prev = prevs.shift()
    const atom = atoms.shift()
    const next = atom._currentEvent.value

    if (!identicalU(prev, next))
      atom._emitValue(next)
  }
}

export function holding(ef) {
  ++lock
  try {
    return ef()
  } finally {
    if (!--lock)
      release()
  }
}

//

export function AbstractMutable() {
  Property.call(this)
}

inherit(AbstractMutable, Property, {
  set(value) {
    this.modify(always(value))
  },
  remove() {
    this.set()
  },
  view(lens) {
    if (process.env.NODE_ENV !== "production")
      if (arguments.length !== 1)
        errorGiven("The `view` method takes exactly 1 argument", arguments.length)
    return new LensedAtom(this, lens)
  },
  _maybeEmitValue(next) {
    const prev = this._currentEvent
    if (!prev || !identicalU(prev.value, next))
      this._emitValue(next)
  }
})

//

export function MutableWithSource(source) {
  if (process.env.NODE_ENV !== "production")
    if (!(source instanceof Observable))
      errorGiven("Expected an Observable", source)
  AbstractMutable.call(this)
  this._source = source
  this._$onAny = void 0
}

inherit(MutableWithSource, AbstractMutable, {
  get() {
    const current = this._currentEvent
    if (current && !lock)
      return current.value
    else
      return this._getFromSource()
  },
  _onAny() {
    this._maybeEmitValue(this._getFromSource())
  },
  _onActivation() {
    this._source.onAny(this._$onAny = e => this._onAny(e))
  },
  _onDeactivation() {
    this._source.offAny(this._$onAny)
    this._$onAny =
    this._currentEvent = void 0
  }
})

//

export function LensedAtom(source, lens) {
  MutableWithSource.call(this, source)
  this._lens = lens
}

inherit(LensedAtom, MutableWithSource, {
  set(v) {
    this._source.set(set(this._lens, v, this._source.get()))
  },
  modify(fn) {
    this._source.modify(modify(this._lens, fn))
  },
  _getFromSource() {
    return get(this._lens, this._source.get())
  }
})

//

export function Atom() {
  AbstractMutable.call(this)
  if (arguments.length)
    this._emitValue(arguments[0])
}

inherit(Atom, AbstractMutable, {
  get() {
    const current = this._currentEvent
    return current ? current.value : void 0
  },
  set(v) {
    const current = this._currentEvent
    this._set(current, current ? current.value : void 0, v)
  },
  modify(fn) {
    const current = this._currentEvent
    const prev = current ? current.value : void 0
    this._set(current, prev, fn(prev))
  },
  _set(current, prev, next) {
    if (lock) {
      if (atoms.indexOf(this) < 0) {
        prevs.push(current ? prev : error /* <- just needs to be unique */)
        atoms.push(this)
      }
      if (current)
        current.value = next
      else
        this._currentEvent = {type: "value", value: next}
    } else {
      this._maybeEmitValue(next)
    }
  }
})

//

function pushMutables(template, mutables) {
  if (template instanceof AbstractMutable &&
      mutables.indexOf(template) < 0) {
    mutables.push(template)
  } else {
    if (isArray(template))
      for (let i=0, n=template.length; i<n; ++i)
        pushMutables(template[i], mutables)
    else if (isObject(template))
      for (const k in template)
        pushMutables(template[k], mutables)
  }
}

function molecule(template) {
  if (template instanceof AbstractMutable) {
    return template.get()
  } else {
    if (isArray(template)) {
      const n = template.length
      let next = template
      for (let i=0; i<n; ++i) {
        const v = molecule(template[i])
        if (!identicalU(next[i], v)) {
          if (next === template)
            next = template.slice(0)
          next[i] = v
        }
      }
      return next
    } else if (isObject(template)) {
      let next = template
      for (const k in template) {
        const v = molecule(template[k])
        if (!identicalU(next[k], v)) {
          if (next === template)
            next = assocPartialU(void 0, void 0, template) // Avoid Object.assign
          next[k] = v
        }
      }
      return next
    } else {
      return template
    }
  }
}

function setMutables(template, value) {
  if (template instanceof AbstractMutable) {
    return template.set(value)
  } else {
    if (isArray(template) && isArray(value))
      for (let i=0, n=template.length; i<n; ++i)
        setMutables(template[i], value[i])
    else if (isObject(template) && isObject(value))
      for (const k in template)
        setMutables(template[k], value[k])
    else if (!identicalU(template, value))
      error("Molecule cannot change the template.")
  }
}

export function Molecule(template) {
  const mutables = []
  pushMutables(template, mutables)
  MutableWithSource.call(this, combine(mutables))
  this._template = template
}

inherit(Molecule, MutableWithSource, {
  _getFromSource() {
    return molecule(this._template)
  },
  modify(fn) {
    const next = fn(this.get())
    holding(() => setMutables(this._template, next))
  }
})

//

export default function atom() {
  if (arguments.length)
    return new Atom(arguments[0])
  else
    return new Atom()
}
<commit_msg>Pass errors through and handle end<commit_after>import {
  always,
  array0,
  assocPartialU,
  identicalU,
  inherit,
  isArray,
  isObject
} from "infestines"
import {
  Observable,
  Property,
  combine,
  constant
} from "kefir"
import {get, modify, set} from "partial.lenses"

//

const header = "kefir.atom: "

function error(m) {
  throw new Error(header + m)
}

function errorGiven(m, o) {
  console.error(header + m + " - given:", o)
  error(m)
}

//

let lock = 0

const prevs = []
const atoms = []

function release() {
  while (prevs.length) {
    const prev = prevs.shift()
    const atom = atoms.shift()
    const next = atom._currentEvent.value

    if (!identicalU(prev, next))
      atom._emitValue(next)
  }
}

export function holding(ef) {
  ++lock
  try {
    return ef()
  } finally {
    if (!--lock)
      release()
  }
}

//

export function AbstractMutable() {
  Property.call(this)
}

inherit(AbstractMutable, Property, {
  set(value) {
    this.modify(always(value))
  },
  remove() {
    this.set()
  },
  view(lens) {
    if (process.env.NODE_ENV !== "production")
      if (arguments.length !== 1)
        errorGiven("The `view` method takes exactly 1 argument", arguments.length)
    return new LensedAtom(this, lens)
  },
  _maybeEmitValue(next) {
    const prev = this._currentEvent
    if (!prev || !identicalU(prev.value, next))
      this._emitValue(next)
  }
})

//

export function MutableWithSource(source) {
  if (process.env.NODE_ENV !== "production")
    if (!(source instanceof Observable))
      errorGiven("Expected an Observable", source)
  AbstractMutable.call(this)
  this._source = source
  this._$onAny = null
}

inherit(MutableWithSource, AbstractMutable, {
  get() {
    const current = this._currentEvent
    if (current && !lock)
      return current.value
    else
      return this._getFromSource()
  },
  _onAny(e) {
    switch (e.type) {
      case "value":
        return this._maybeEmitValue(this._getFromSource())
      case "error":
        return this._emitError(e.value)
      default:
        this._$onAny = null
        return this._emitEnd()
    }
  },
  _onActivation() {
    this._source.onAny(this._$onAny = e => this._onAny(e))
  },
  _onDeactivation() {
    const onAny = this._$onAny
    if (onAny)
      this._source.offAny(onAny)
    this._$onAny = null
  }
})

//

export function LensedAtom(source, lens) {
  MutableWithSource.call(this, source)
  this._lens = lens
}

inherit(LensedAtom, MutableWithSource, {
  set(v) {
    this._source.set(set(this._lens, v, this._source.get()))
  },
  modify(fn) {
    this._source.modify(modify(this._lens, fn))
  },
  _getFromSource() {
    return get(this._lens, this._source.get())
  }
})

//

export function Atom() {
  AbstractMutable.call(this)
  if (arguments.length)
    this._emitValue(arguments[0])
}

inherit(Atom, AbstractMutable, {
  get() {
    const current = this._currentEvent
    return current ? current.value : void 0
  },
  set(v) {
    const current = this._currentEvent
    this._set(current, current ? current.value : void 0, v)
  },
  modify(fn) {
    const current = this._currentEvent
    const prev = current ? current.value : void 0
    this._set(current, prev, fn(prev))
  },
  _set(current, prev, next) {
    if (lock) {
      if (atoms.indexOf(this) < 0) {
        prevs.push(current ? prev : error /* <- just needs to be unique */)
        atoms.push(this)
      }
      if (current)
        current.value = next
      else
        this._currentEvent = {type: "value", value: next}
    } else {
      this._maybeEmitValue(next)
    }
  }
})

//

function pushMutables(template, mutables) {
  if (template instanceof AbstractMutable &&
      mutables.indexOf(template) < 0) {
    mutables.push(template)
  } else {
    if (isArray(template))
      for (let i=0, n=template.length; i<n; ++i)
        pushMutables(template[i], mutables)
    else if (isObject(template))
      for (const k in template)
        pushMutables(template[k], mutables)
  }
}

function molecule(template) {
  if (template instanceof AbstractMutable) {
    return template.get()
  } else {
    if (isArray(template)) {
      const n = template.length
      let next = template
      for (let i=0; i<n; ++i) {
        const v = molecule(template[i])
        if (!identicalU(next[i], v)) {
          if (next === template)
            next = template.slice(0)
          next[i] = v
        }
      }
      return next
    } else if (isObject(template)) {
      let next = template
      for (const k in template) {
        const v = molecule(template[k])
        if (!identicalU(next[k], v)) {
          if (next === template)
            next = assocPartialU(void 0, void 0, template) // Avoid Object.assign
          next[k] = v
        }
      }
      return next
    } else {
      return template
    }
  }
}

function setMutables(template, value) {
  if (template instanceof AbstractMutable) {
    return template.set(value)
  } else {
    if (isArray(template) && isArray(value))
      for (let i=0, n=template.length; i<n; ++i)
        setMutables(template[i], value[i])
    else if (isObject(template) && isObject(value))
      for (const k in template)
        setMutables(template[k], value[k])
    else if (!identicalU(template, value))
      error("Molecule cannot change the template.")
  }
}

const empty = constant(array0)

export function Molecule(template) {
  const mutables = []
  pushMutables(template, mutables)
  MutableWithSource.call(this, mutables.length ? combine(mutables) : empty)
  this._template = template
}

inherit(Molecule, MutableWithSource, {
  _getFromSource() {
    return molecule(this._template)
  },
  modify(fn) {
    const next = fn(this.get())
    holding(() => setMutables(this._template, next))
  }
})

//

export default function atom() {
  if (arguments.length)
    return new Atom(arguments[0])
  else
    return new Atom()
}
<|endoftext|>


<commit_before>
// Shim deps
var _ = _ || shim( 'lodash' ),
    $ = $ || shim( 'jquery' );

// Export public API
var exports = function( opts ) {
    exports.setOptions( opts );
};

_.extend( exports, (function() {
    var options = {
        selfRegister: true,
        basePath: './'
    },

        cache = [];

    return {
        VERSION: '0.2.2',

        setOptions: function( opts ) {
            _.extend( options, opts );

            return options;
        },

        getCachedItem: function( el ) {
            return _.find( cache, function( item ) {
                return item.id === $( el ).data( 'src' );
            });
        },

        injectCache: function( item ) {
            _.each( item.elements, function( el ) {
                this.injectSVG( el, item.content );
            }, this );
        },

        injectSVG: function( el, svg ) {
            $( el ).replaceWith( svg );

            // Fire an onload callback if one is specified
            if ( $( el ).data( 'onload' ) ) {
                var strip = $( el ).data( 'onload' ).split( '.' ),
                    section = strip.shift(),
                    fn = window;
                while ( section ) {
                    if ( fn[ section ] ) {
                        fn = fn[ section ];
                    }
                    section = strip.shift();
                }
                if ( typeof fn === 'function' ) {
                    fn();
                }
            }
        },

        inject: function( force ) {
            if ( !options.selfRegister && !force ) {
                return;
            }

            var els = $( '.icon' );

            _.each( els, function( el ) {
                var self = this;

                // Bail
                if ( !$( el ).data( 'src' ) ) {
                    console.error( 'No URL specified for icon' );
                    return;
                }

                // Check the cache
                var cached = self.getCachedItem( el );

                if ( cached ) {
                    if ( cached.content ) {
                        this.injectSVG( el, cached.content );
                        return;
                    }

                    cached.elements.push( el );
                    return;
                }

                // Load the icon
                if ( !cached ) {
                    cache.push( {
                        id: $( el ).data( 'src' ),
                        content: null,
                        elements: [ el ]
                    });
                }
                $.ajax( {
                    type: 'GET',
                    url: $( el ).data( 'src' ).match( /^http/ ) ? $( el ).data( 'src' ) : join( options.basePath, $( el ).data( 'src' ) ),
                    dataType: 'text'
                })
                    .done( function( data, status, xhr) {
                        var cached = null;
                        iconClass = $( el ).attr( 'class' ) || '';
                        res = data.replace( /\r?\n|\r/g, '' )
                                  .replace( /<svg/, '<svg class="' + iconClass + '" ')
                                  .match( /<svg(.*?)svg>/g )
                                  .toString();

                        cached = self.getCachedItem( el );
                        cached.content = res;
                        self.injectCache( cached );
                    })
                    .fail( function( xhr, status, err ) {
                        console.log( 'xhr failed', status, err );
                        console.log( 'Error loading icon', err );
                    });

            }, this );
        }
    };
})() );

// Self running module
document.addEventListener( 'DOMContentLoaded', function( event ) {
    exports.inject();
});
<commit_msg>Add support for IE9 + IE10 (reinstated data('class') )<commit_after>
// Shim deps
var _ = _ || shim( 'lodash' ),
    $ = $ || shim( 'jquery' );

// Export public API
var exports = function( opts ) {
    exports.setOptions( opts );
};

_.extend( exports, (function() {
    var options = {
        selfRegister: true,
        basePath: './'
    },

        cache = [];

    return {
        VERSION: '0.2.2',

        setOptions: function( opts ) {
            _.extend( options, opts );

            return options;
        },

        getCachedItem: function( el ) {
            return _.find( cache, function( item ) {
                return item.id === $( el ).data( 'src' );
            });
        },

        injectCache: function( item ) {
            _.each( item.elements, function( el ) {
                this.injectSVG( el, item.content );
            }, this );
        },

        injectSVG: function( el, svg ) {
            $( el ).replaceWith( svg );

            // Fire an onload callback if one is specified
            if ( $( el ).data( 'onload' ) ) {
                var strip = $( el ).data( 'onload' ).split( '.' ),
                    section = strip.shift(),
                    fn = window;
                while ( section ) {
                    if ( fn[ section ] ) {
                        fn = fn[ section ];
                    }
                    section = strip.shift();
                }
                if ( typeof fn === 'function' ) {
                    fn();
                }
            }
        },

        inject: function( force ) {
            if ( !options.selfRegister && !force ) {
                return;
            }

            var els = $( '.icon' );

            _.each( els, function( el ) {
                var self = this;

                // Bail
                if ( !$( el ).data( 'src' ) ) {
                    console.error( 'No URL specified for icon' );
                    return;
                }

                // Check the cache
                var cached = self.getCachedItem( el );

                if ( cached ) {
                    if ( cached.content ) {
                        this.injectSVG( el, cached.content );
                        return;
                    }

                    cached.elements.push( el );
                    return;
                }

                // Load the icon
                if ( !cached ) {
                    cache.push( {
                        id: $( el ).data( 'src' ),
                        content: null,
                        elements: [ el ]
                    });
                }
                $.ajax( {
                    type: 'GET',
                    url: $( el ).data( 'src' ).match( /^http/ ) ? $( el ).data( 'src' ) : join( options.basePath, $( el ).data( 'src' ) ),
                    dataType: 'text'
                })
                    .done( function( data, status, xhr) {
                        var cached = null;
                        iconClass = $( el ).data( 'class' ) || '';
                        res = data.replace( /\r?\n|\r/g, '' )
                                  .replace( /<svg/, '<svg class="' + iconClass + '" ')
                                  .match( /<svg(.*?)svg>/g )
                                  .toString();

                        cached = self.getCachedItem( el );
                        cached.content = res;
                        self.injectCache( cached );
                    })
                    .fail( function( xhr, status, err ) {
                        console.log( 'xhr failed', status, err );
                        console.log( 'Error loading icon', err );
                    });

            }, this );
        }
    };
})() );

// Self running module
document.addEventListener( 'DOMContentLoaded', function( event ) {
    exports.inject();
});
<|endoftext|>


<commit_before>const compose = require('koa-compose');
const statuses = require('statuses');
const isJSON = require('koa-is-json');
const Stream = require('stream');
const onFinished = require('on-finished');

const Koa = require('koa');

export class KronosKoa extends Koa {
  /**
   * Overwrite the super function. It will update the middleware chain
   */
  use(fn) {
    super.use(fn);
    this.composedMiddleware = compose(this.middleware);
    return this;
  }

  /**
   * Overwrites the callback. This is now a dynamic callback.
   * The returned function takes the changing generator chain
   * instead of a fixed one.
   */
  callback() {
    if (!this.listeners('error').length) this.on('error', this.onerror);

    this.composedMiddleware = compose(this.middleware);

    return (req, res) => {
      res.statusCode = 404;
      const ctx = this.createContext(req, res);
      onFinished(res, ctx.onerror);
      this.composedMiddleware(ctx)
        .then(() => respond(ctx))
        .catch(ctx.onerror);
    };
  }

  /**
   * Returns true if there is still registered middleware
   * @return status True if there is still registered middleware
   */
  hasMiddleware() {
    return this.middleware.length > 0;
  }

  /**
   * Removes an existing generator function
   * @param {GeneratorFunction} fn The generator function to be deleted
   * @api public
   */
  delete(fn) {
    const index = this.middleware.indexOf(fn);
    if (index >= 0) {
      this.middleware.splice(index, 1);
      this.composedMiddleware = compose(this.middleware);
    }
  }
}

/**
 * Response helper.
 * copied from the original
 */

function respond(ctx) {
  // allow bypassing koa
  if (false === ctx.respond) return;

  const res = ctx.res;
  if (!ctx.writable) return;

  let body = ctx.body;
  const code = ctx.status;

  // ignore body
  if (statuses.empty[code]) {
    // strip headers
    ctx.body = null;
    return res.end();
  }

  if ('HEAD' == ctx.method) {
    if (!res.headersSent && isJSON(body)) {
      ctx.length = Buffer.byteLength(JSON.stringify(body));
    }
    return res.end();
  }

  // status body
  if (null === body) {
    body = ctx.message || String(code);
    if (!res.headersSent) {
      ctx.type = 'text';
      ctx.length = Buffer.byteLength(body);
    }
    return res.end(body);
  }

  // responses
  if (body === undefined) return res.end();
  if (Buffer.isBuffer(body)) return res.end(body);
  if ('string' == typeof body) return res.end(body);
  if (body instanceof Stream) return body.pipe(res);

  // body: json
  body = JSON.stringify(body);
  if (!res.headersSent) {
    ctx.length = Buffer.byteLength(body);
  }
  res.end(body);
}
<commit_msg>fix: sync respond() from koa<commit_after>const compose = require('koa-compose');
const statuses = require('statuses');
const isJSON = require('koa-is-json');
const Stream = require('stream');
const onFinished = require('on-finished');

const Koa = require('koa');

export class KronosKoa extends Koa {
  /**
   * Overwrite the super function. It will update the middleware chain
   */
  use(fn) {
    super.use(fn);
    this.composedMiddleware = compose(this.middleware);
    return this;
  }

  /**
   * Overwrites the callback. This is now a dynamic callback.
   * The returned function takes the changing generator chain
   * instead of a fixed one.
   */
  callback() {
    if (!this.listeners('error').length) this.on('error', this.onerror);

    this.composedMiddleware = compose(this.middleware);

    return (req, res) => {
      res.statusCode = 404;
      const ctx = this.createContext(req, res);
      onFinished(res, ctx.onerror);
      this.composedMiddleware(ctx)
        .then(() => respond(ctx))
        .catch(ctx.onerror);
    };
  }

  /**
   * Returns true if there is still registered middleware
   * @return status True if there is still registered middleware
   */
  hasMiddleware() {
    return this.middleware.length > 0;
  }

  /**
   * Removes an existing generator function
   * @param {GeneratorFunction} fn The generator function to be deleted
   * @api public
   */
  delete(fn) {
    const index = this.middleware.indexOf(fn);
    if (index >= 0) {
      this.middleware.splice(index, 1);
      this.composedMiddleware = compose(this.middleware);
    }
  }
}

/**
 * Response helper.
 * copied from the original
 */

function respond(ctx) {
  // allow bypassing koa
  if (false === ctx.respond) return;

  const res = ctx.res;
  if (!ctx.writable) return;

  let body = ctx.body;
  const code = ctx.status;

  // ignore body
  if (statuses.empty[code]) {
    // strip headers
    ctx.body = null;
    return res.end();
  }

  if ('HEAD' == ctx.method) {
    if (!res.headersSent && isJSON(body)) {
      ctx.length = Buffer.byteLength(JSON.stringify(body));
    }
    return res.end();
  }

  // status body
  if (null == body) {
    body = ctx.message || String(code);
    if (!res.headersSent) {
      ctx.type = 'text';
      ctx.length = Buffer.byteLength(body);
    }
    return res.end(body);
  }

  // responses
  if (Buffer.isBuffer(body)) return res.end(body);
  if ('string' == typeof body) return res.end(body);
  if (body instanceof Stream) return body.pipe(res);

  // body: json
  body = JSON.stringify(body);
  if (!res.headersSent) {
    ctx.length = Buffer.byteLength(body);
  }
  res.end(body);
}
<|endoftext|>


<commit_before>// display the calendar here
var hotelTable = document.getElementById("hotelCalendarTable");
var defaultData = hotelTable.innerHTML;
var stringHTML = "";
stringHTML = "
1	2	3	4	5	6	7

9	10	11	12	13	14	15

17	18	19	20	21	22	23

25	26	27	28	29	30	31
";
hotelTable.innerHTML += stringHTML;
<commit_msg>week2 wed hw2 for loop<commit_after>// display the calendar here
var hotelTable = document.getElementById("hotelCalendarTable");
var defaultData = hotelTable.innerHTML;
var stringHTML = "
";

for (var i=1; i < 32; i++) {
	if (i%7 == 0){
		stringHTML += ""+i+"

";
	} else {
		stringHTML += ""+i+"	";
	}
}
//stringHTML += "
"
hotelTable.innerHTML += stringHTML;
<|endoftext|>


<commit_before>// The driver maintains the state of the application and drives everything.
// Most everything else is just stateless
// This is similar to Redux except more flexible for faster development
import Printify from '../lib/Printify';
import Byol from './Byol';
import _ from 'lodash';
import Stellarify from '../lib/Stellarify';
import BigNumber from 'bignumber.js';
BigNumber.config({ EXPONENTIAL_AT: 100 });

// Spoonfed Stellar-SDK: Super easy to use higher level Stellar-Sdk functions
// Simplifies the objects to what is necessary. Listens to updates automagically.
// It's in the same file as the driver because the driver is the only one that
// should ever use the spoon.
const MagicSpoon = {
  async Account(Server, keypair, onUpdate) {
    let sdkAccount = await Server.loadAccount(keypair.accountId())
    sdkAccount.sign = transaction => {
      transaction.sign(keypair);
    };

    let accountEventsClose = Server.accounts().accountId(keypair.accountId()).stream({
      onmessage: res => {
        let updated = false;
        if (!_.isEqual(sdkAccount.balances, res.balances)) {
          sdkAccount.balances = res.balances;
          updated = true;
        }

        if (updated) {
          onUpdate();
        }
      }
    });

    sdkAccount.offers = {};

    // Horizon offers for account doesn't return us updates. So we will have to manually update it.
    // We won't miss any offers assuming that the user only updates their offers through the client
    // with just one window open at a time
    sdkAccount.updateOffers = () => {
      Server.offers('accounts', keypair.accountId())
        .limit(100) // TODO: Keep iterating through next() to show more than 100 offers
        .call()
        .then(res => {
          let newOffers = {};
          _.each(res.records, offer => {
            console.log(offer.id)
            newOffers[offer.id] = offer;
            console.log(newOffers)
          });
          sdkAccount.offers = newOffers;
      console.log('updateing ofers')
          onUpdate();
        });
    }
    sdkAccount.updateOffers();

    sdkAccount.close = () => {
      accountEventsClose();
    };

    return sdkAccount;
  },
  Orderbook(Server, baseBuying, counterSelling, onUpdate) {
    // Orderbook is an object that keeps track of the orderbook for you.
    // All the driver needs to do is remember to call the close function

    this.ready = false;
    const initialOrderbook = Server.orderbook(baseBuying, counterSelling).call()
      .then((res) => {
        this.asks = res.asks;
        this.bids = res.bids;
        this.baseBuying = baseBuying;
        this.counterSelling = counterSelling;
        this.ready = true;
        onUpdate();

      });
    let streamingOrderbookClose = Server.orderbook(baseBuying, counterSelling)
      .stream({
        onmessage: res => {
          let updated = false;
          if (!_.isEqual(this.bids, res.bids)) {
            this.bids = res.bids;
            updated = true;
          }
          if (!_.isEqual(this.asks, res.asks)) {
            this.asks = res.asks;
            updated = true;
          }
          if (updated) {
            onUpdate();
          }
        }
      })
    this.close = streamingOrderbookClose;
    // TODO: Close
  },

  // opts.baseBuying -- StellarSdk.Asset (example: XLM)
  // opts.counterSelling -- StellarSdk.Asset (example: USD)
  // opts.price -- Exchange ratio selling/buying
  // opts.amount -- Here, it's relative to the base (JS-sdk does: Total amount selling)
  // opts.type -- String of either 'buy' or 'sell' (relative to base currency)
  createOffer(Server, spoonAccount, side, opts) {
    let sdkBuying;
    let sdkSelling;
    let sdkPrice;
    let sdkAmount;

    const bigOptsPrice = new BigNumber(opts.price).toPrecision(15);
    const bigOptsAmount = new BigNumber(opts.amount).toPrecision(15);

    console.log(`Creating *${side}* offer at price ${opts.price}`);
    if (side === 'buy') {
      sdkBuying = opts.baseBuying; // ex: lumens
      sdkSelling = opts.counterSelling; // ex: USD
      sdkPrice = new BigNumber(1).dividedBy(bigOptsPrice);
      sdkAmount = new BigNumber(bigOptsAmount).times(bigOptsPrice).toFixed(7);
    } else if (side === 'sell') {
      sdkBuying = opts.counterSelling; // ex: USD
      sdkSelling = opts.baseBuying; // ex: lumens
      sdkPrice = new BigNumber(bigOptsPrice);
      sdkAmount = new BigNumber(bigOptsAmount).toFixed(7);
    } else {
      throw new Error(`Invalid side ${side}`);
    }

    const operationOpts = {
      buying: sdkBuying,
      selling: sdkSelling,
      amount: String(sdkAmount),
      price: String(sdkPrice),
      offerId: 0, // 0 for new offer
    };
    const transaction = new StellarSdk.TransactionBuilder(spoonAccount)
      .addOperation(StellarSdk.Operation.manageOffer(operationOpts))
      .build();
    spoonAccount.sign(transaction);
    return Server.submitTransaction(transaction)
      .then(res => {
        console.log('Offer create success');
        console.log(res)
        spoonAccount.updateOffers(); // Just to be doubly sure
      })
      .catch(err => {
        console.error(err)
      })
  },
  changeTrust(Server, spoonAccount, opts) {
    let sdkLimit;
    if (typeof opts.limit === 'string' || opts.limit instanceof String) {
      sdkLimit = opts.limit;
    } else if (opts.limit !== undefined) {
      throw new Error('changeTrust opts.limit must be a string');
    }

    const operationOpts = {
      asset: opts.asset,
      limit: sdkLimit,
    };

    const transaction = new StellarSdk.TransactionBuilder(spoonAccount)
      .addOperation(StellarSdk.Operation.changeTrust(operationOpts))
      .build();
    spoonAccount.sign(transaction);
    const transactionResult = Server.submitTransaction(transaction);
  },
  async removeOffer(Server, spoonAccount, offerId) {
    const transaction = new StellarSdk.TransactionBuilder(spoonAccount)
      .addOperation(StellarSdk.Operation.manageOffer({
        buying: StellarSdk.Asset.native(),
        selling: new StellarSdk.Asset('REMOVE', spoonAccount.accountId()),
        amount: '0',
        price: '1',
        offerId,
      }))
      .build();
    spoonAccount.sign(transaction);
    const transactionResult = await Server.submitTransaction(transaction);
    spoonAccount.updateOffers();
  },
};

// Using old school "classes" because I'm old scohol and it's simpler for
// someone experienced in JavaScript to understand. I may use the ES6 form
// later though.
function Driver(opts) {
  this.Server = new StellarSdk.Server(opts.horizonUrl); // Should never change
  this.Server.serverUrl = opts.horizonUrl;
  this._baseBuying = new StellarSdk.Asset('XLM', null);
  this._counterSelling = new StellarSdk.Asset('USD', 'GBZ3P4Z53Z7ZHATW6KCA2OXEBWKQGN2433WMSMKF7OJXWFJL4JT6NG4V');

  const byol = new Byol();

  const availableEvents = [
    'session',
    'orderbook',
  ];
  const trigger = {};
  availableEvents.forEach((eventName) => {
    this[`listen${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`] = cb => byol.listen(eventName, cb);
    this[`unlisten${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`] = id => byol.unlisten(eventName, id);
    trigger[eventName] = () => byol.trigger(eventName);
  });

  // ----- Initializations above this line -----
  // Only the driver should change the session.
  this.session = {
    state: 'out',
    account: null, // MagicSpoon.Account instance
  };
  // Due to a bug in horizon where it doesn't update offers for accounts, we have to manually check
  // It shouldn't cause too much of an overhead
  let forceUpdateAccountOffers = () => {
    let updateFn = _.get(this.session, 'account.updateOffers');
    if (updateFn) {
      updateFn();
    }
  }

  this.orderbook = new MagicSpoon.Orderbook(this.Server, this._baseBuying, this._counterSelling, () => {
    trigger.orderbook();
    forceUpdateAccountOffers();
  });

  this.baseBuyingAssetName = () => Printify.assetName(this._baseBuying);
  this.counterSellingAssetName = () => Printify.assetName(this._counterSelling);
  this.baseBuyingGetIssuer = () => this._baseBuying.getIssuer();
  this.counterSellingGetIssuer = () => this._counterSelling.getIssuer();

  this.handlers = {
    logIn: async (secretKey) => {
      let keypair;
      try {
        keypair = StellarSdk.Keypair.fromSeed(secretKey);
      } catch (e) {
        console.log('Invalid secret key');
        return;
      }
      this.session.state = 'loading';
      trigger.session();

      this.session.account = await MagicSpoon.Account(this.Server, keypair, () => {
        trigger.session();
      });
      this.session.state = 'in';
      trigger.session();
    },
    createOffer: async (side, opts) => {
      MagicSpoon.createOffer(this.Server, this.session.account, side, _.assign(opts, {
        baseBuying: this.orderbook.baseBuying,
        counterSelling: this.orderbook.counterSelling,
      }));
    },
    addTrust: async (code, issuer) => {
      // For simplicity, currently only adds max trust line
      MagicSpoon.changeTrust(this.Server, this.session.account, {
        asset: new StellarSdk.Asset(code, issuer),
      })
    },
    removeTrust: async (code, issuer) => {
      MagicSpoon.changeTrust(this.Server, this.session.account, {
        asset: new StellarSdk.Asset(code, issuer),
        limit: '0',
      })
    },
    removeOffer: async (offerId) => {
      MagicSpoon.removeOffer(this.Server, this.session.account, offerId);
    },
  };
}

export default Driver;
<commit_msg>Remove old console.logs<commit_after>// The driver maintains the state of the application and drives everything.
// Most everything else is just stateless
// This is similar to Redux except more flexible for faster development
import Printify from '../lib/Printify';
import Byol from './Byol';
import _ from 'lodash';
import Stellarify from '../lib/Stellarify';
import BigNumber from 'bignumber.js';
BigNumber.config({ EXPONENTIAL_AT: 100 });

// Spoonfed Stellar-SDK: Super easy to use higher level Stellar-Sdk functions
// Simplifies the objects to what is necessary. Listens to updates automagically.
// It's in the same file as the driver because the driver is the only one that
// should ever use the spoon.
const MagicSpoon = {
  async Account(Server, keypair, onUpdate) {
    let sdkAccount = await Server.loadAccount(keypair.accountId())
    sdkAccount.sign = transaction => {
      transaction.sign(keypair);
    };

    let accountEventsClose = Server.accounts().accountId(keypair.accountId()).stream({
      onmessage: res => {
        let updated = false;
        if (!_.isEqual(sdkAccount.balances, res.balances)) {
          sdkAccount.balances = res.balances;
          updated = true;
        }

        if (updated) {
          onUpdate();
        }
      }
    });

    sdkAccount.offers = {};

    // Horizon offers for account doesn't return us updates. So we will have to manually update it.
    // We won't miss any offers assuming that the user only updates their offers through the client
    // with just one window open at a time
    sdkAccount.updateOffers = () => {
      return Server.offers('accounts', keypair.accountId())
        .limit(100) // TODO: Keep iterating through next() to show more than 100 offers
        .call()
        .then(res => {
          let newOffers = {};
          _.each(res.records, offer => {
            newOffers[offer.id] = offer;
          });
          sdkAccount.offers = newOffers;
          onUpdate();
          return null;
        });
    }
    sdkAccount.updateOffers();

    sdkAccount.close = () => {
      accountEventsClose();
    };

    return sdkAccount;
  },
  Orderbook(Server, baseBuying, counterSelling, onUpdate) {
    // Orderbook is an object that keeps track of the orderbook for you.
    // All the driver needs to do is remember to call the close function

    this.ready = false;
    const initialOrderbook = Server.orderbook(baseBuying, counterSelling).call()
      .then((res) => {
        this.asks = res.asks;
        this.bids = res.bids;
        this.baseBuying = baseBuying;
        this.counterSelling = counterSelling;
        this.ready = true;
        onUpdate();

      });
    let streamingOrderbookClose = Server.orderbook(baseBuying, counterSelling)
      .stream({
        onmessage: res => {
          let updated = false;
          if (!_.isEqual(this.bids, res.bids)) {
            this.bids = res.bids;
            updated = true;
          }
          if (!_.isEqual(this.asks, res.asks)) {
            this.asks = res.asks;
            updated = true;
          }
          if (updated) {
            onUpdate();
          }
        }
      })
    this.close = streamingOrderbookClose;
    // TODO: Close
  },

  // opts.baseBuying -- StellarSdk.Asset (example: XLM)
  // opts.counterSelling -- StellarSdk.Asset (example: USD)
  // opts.price -- Exchange ratio selling/buying
  // opts.amount -- Here, it's relative to the base (JS-sdk does: Total amount selling)
  // opts.type -- String of either 'buy' or 'sell' (relative to base currency)
  createOffer(Server, spoonAccount, side, opts) {
    let sdkBuying;
    let sdkSelling;
    let sdkPrice;
    let sdkAmount;

    const bigOptsPrice = new BigNumber(opts.price).toPrecision(15);
    const bigOptsAmount = new BigNumber(opts.amount).toPrecision(15);

    console.log(`Creating *${side}* offer at price ${opts.price}`);
    if (side === 'buy') {
      sdkBuying = opts.baseBuying; // ex: lumens
      sdkSelling = opts.counterSelling; // ex: USD
      sdkPrice = new BigNumber(1).dividedBy(bigOptsPrice);
      sdkAmount = new BigNumber(bigOptsAmount).times(bigOptsPrice).toFixed(7);
    } else if (side === 'sell') {
      sdkBuying = opts.counterSelling; // ex: USD
      sdkSelling = opts.baseBuying; // ex: lumens
      sdkPrice = new BigNumber(bigOptsPrice);
      sdkAmount = new BigNumber(bigOptsAmount).toFixed(7);
    } else {
      throw new Error(`Invalid side ${side}`);
    }

    const operationOpts = {
      buying: sdkBuying,
      selling: sdkSelling,
      amount: String(sdkAmount),
      price: String(sdkPrice),
      offerId: 0, // 0 for new offer
    };
    const transaction = new StellarSdk.TransactionBuilder(spoonAccount)
      .addOperation(StellarSdk.Operation.manageOffer(operationOpts))
      .build();
    spoonAccount.sign(transaction);
    Server.submitTransaction(transaction)
      .then(res => {
        console.log('Offer create success');
        console.log(res)
        spoonAccount.updateOffers(); // Just to be doubly sure
        return;
      })
      .catch(err => {
        console.error(err)
      })
  },
  changeTrust(Server, spoonAccount, opts) {
    let sdkLimit;
    if (typeof opts.limit === 'string' || opts.limit instanceof String) {
      sdkLimit = opts.limit;
    } else if (opts.limit !== undefined) {
      throw new Error('changeTrust opts.limit must be a string');
    }

    const operationOpts = {
      asset: opts.asset,
      limit: sdkLimit,
    };

    const transaction = new StellarSdk.TransactionBuilder(spoonAccount)
      .addOperation(StellarSdk.Operation.changeTrust(operationOpts))
      .build();
    spoonAccount.sign(transaction);
    const transactionResult = Server.submitTransaction(transaction);
  },
  async removeOffer(Server, spoonAccount, offerId) {
    const transaction = new StellarSdk.TransactionBuilder(spoonAccount)
      .addOperation(StellarSdk.Operation.manageOffer({
        buying: StellarSdk.Asset.native(),
        selling: new StellarSdk.Asset('REMOVE', spoonAccount.accountId()),
        amount: '0',
        price: '1',
        offerId,
      }))
      .build();
    spoonAccount.sign(transaction);
    const transactionResult = await Server.submitTransaction(transaction);
    spoonAccount.updateOffers();
  },
};

// Using old school "classes" because I'm old scohol and it's simpler for
// someone experienced in JavaScript to understand. I may use the ES6 form
// later though.
function Driver(opts) {
  this.Server = new StellarSdk.Server(opts.horizonUrl); // Should never change
  this.Server.serverUrl = opts.horizonUrl;
  this._baseBuying = new StellarSdk.Asset('XLM', null);
  this._counterSelling = new StellarSdk.Asset('USD', 'GBZ3P4Z53Z7ZHATW6KCA2OXEBWKQGN2433WMSMKF7OJXWFJL4JT6NG4V');

  const byol = new Byol();

  const availableEvents = [
    'session',
    'orderbook',
  ];
  const trigger = {};
  availableEvents.forEach((eventName) => {
    this[`listen${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`] = cb => byol.listen(eventName, cb);
    this[`unlisten${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`] = id => byol.unlisten(eventName, id);
    trigger[eventName] = () => byol.trigger(eventName);
  });

  // ----- Initializations above this line -----
  // Only the driver should change the session.
  this.session = {
    state: 'out',
    account: null, // MagicSpoon.Account instance
  };
  // Due to a bug in horizon where it doesn't update offers for accounts, we have to manually check
  // It shouldn't cause too much of an overhead
  let forceUpdateAccountOffers = () => {
    let updateFn = _.get(this.session, 'account.updateOffers');
    if (updateFn) {
      updateFn();
    }
  }

  this.orderbook = new MagicSpoon.Orderbook(this.Server, this._baseBuying, this._counterSelling, () => {
    trigger.orderbook();
    forceUpdateAccountOffers();
  });

  this.baseBuyingAssetName = () => Printify.assetName(this._baseBuying);
  this.counterSellingAssetName = () => Printify.assetName(this._counterSelling);
  this.baseBuyingGetIssuer = () => this._baseBuying.getIssuer();
  this.counterSellingGetIssuer = () => this._counterSelling.getIssuer();

  this.handlers = {
    logIn: async (secretKey) => {
      let keypair;
      try {
        keypair = StellarSdk.Keypair.fromSeed(secretKey);
      } catch (e) {
        console.log('Invalid secret key');
        return;
      }
      this.session.state = 'loading';
      trigger.session();

      this.session.account = await MagicSpoon.Account(this.Server, keypair, () => {
        trigger.session();
      });
      this.session.state = 'in';
      trigger.session();
    },
    createOffer: async (side, opts) => {
      MagicSpoon.createOffer(this.Server, this.session.account, side, _.assign(opts, {
        baseBuying: this.orderbook.baseBuying,
        counterSelling: this.orderbook.counterSelling,
      }));
    },
    addTrust: async (code, issuer) => {
      // For simplicity, currently only adds max trust line
      MagicSpoon.changeTrust(this.Server, this.session.account, {
        asset: new StellarSdk.Asset(code, issuer),
      })
    },
    removeTrust: async (code, issuer) => {
      MagicSpoon.changeTrust(this.Server, this.session.account, {
        asset: new StellarSdk.Asset(code, issuer),
        limit: '0',
      })
    },
    removeOffer: async (offerId) => {
      MagicSpoon.removeOffer(this.Server, this.session.account, offerId);
    },
  };
}

export default Driver;
<|endoftext|>


<commit_before>"use strict";
let axios = require("axios");
let cheerio = require("cheerio");
let url = require("../config").newpct;
const vm = require('vm');
const _ = require('lodash');

function runNewpctScript(code) {
	const fake$ = () => {
		return {
			ready: _.noop,
			load: _.noop,
			scroll: _.noop
		};
	};
	const sandbox = vm.createContext({
		$: fake$,
		document: Object.create(null),
		window: Object.create(null),
		setInterval: _.noop
	});
	vm.runInNewContext(code, sandbox, { filename: 'newpctscript.js' });
	return sandbox;
}

async function getTVShowEpisodeTorrentUrl(tvShowUrl, season, episode, page = 1) {
	const response = await axios.get(`${tvShowUrl}/pg/${page}`);
	const $ = cheerio.load(response.data);
	const $episodeList = $('.buscar-list li');
	if (!$episodeList.length) {
		return null;
	}
	const $result = $episodeList.filter((index, episodeElement) => {
		const $episode = $(episodeElement);
		return $episode.find('h2').text().includes(`Temporada ${season} Capitulo ${episode}`);
	});
	if ($result.length) {
		return $result.eq(0).find('a').eq(0).attr('href');
	}
	return getTVShowEpisodeTorrentUrl(tvShowUrl, season, episode, ++page);
}

module.exports = {
	async search(query, page) {
		let queryUrl = url + '/index.php';
		const response = await axios.get(queryUrl, {
			params: {
				page: 'buscar',
				q: query,
				pg: page
			}
		});
		const $ = cheerio.load(response.data);
			const $searchResults = $('.buscar-list li');
			const torrents = [];
			const ids = [];
			for (let i = 0; i < $searchResults.length; i++) {
				const $element = $searchResults.eq(i);
				const torrent = {};
				torrent.name = $element.find('h2 strong').text();
				torrent.url = $element.find('a').eq(0).attr('href');
				const category = $element.find('h2 span:last-of-type').text();
				torrent.category = category.replace(/\[/gi, '').replace(/\]/gi, '').trim();
				if (torrent.url.includes('series')) {
					const titleWords = torrent.name.split(' ');
					const season = titleWords[titleWords.indexOf('Temporada') + 1];
					const episode = titleWords[titleWords.indexOf('Capitulo') + 1];
					torrent.url = await getTVShowEpisodeTorrentUrl(torrent.url, season, episode);
					if (!torrent.url) {
						continue;
					}
				}
				const id = torrent.url.replace(url, '');
				if (ids.includes(id)) {
					continue;
				}
				ids.push(id);
				torrent.id = encodeURIComponent(id);
				torrent.image = $element.find('img').attr('src');
				torrents.push(torrent);
			}
			const total = parseInt($('.page-box h3 strong').text().match(/\((.*?)\)/gi)[0].replace(/\(/gi, '').replace(/\)/gi, '').trim());
			return {
				torrents,
				total
			};
	},
	getTorrent(id) {
		return axios.get(`${url}${decodeURIComponent(id)}`).then((response) => {
			let $ = cheerio.load(response.data);
			let torrent = {};
			torrent.title = $('.page-box h1 strong').text().trim();
			torrent.image = $('.entry-left img').eq(0).attr('src');
			torrent.description = $('.descripcion_top').text();
			torrent.category = $('.page-box h1').text().match(/\[(.*?)\]/gi)[0].replace(/\[/gi, '').replace(/\]/gi, '');
			torrent.url = $('.f2-tab2 a').attr('href');
			return torrent;
		});
	},
	getLastDownloads() {
		return axios.get(url).then((response) => {
			let $ = cheerio.load(response.data);
			const script = $('script[src="http://www.newpct1.com/pct1/library/content/template/js/custom.js"]').next();
			const scriptVariables = runNewpctScript(script.html());
			const downloadProperties = ['id', 'url', 'image', 'name', 'category', 'cta'];
			const arrays = ['arrayMODPC', 'arrayMODEC', 'arrayMODOP', 'arrayMODSE', 'arrayMODx264', 'arrayMODSH', 'arrayMODSVO', 'arrayMODPH', 'arrayMODP3D', 'arrayMODPL', 'arrayMODV'];
			const downloads = [];

			arrays.forEach((array) => {
				scriptVariables[array].forEach((rawDownload) => {
					const download = {};
					rawDownload.forEach((property, index) => {
						download[downloadProperties[index]] = property.trim();
					});
					download.id = encodeURIComponent(download.url.replace(url, ''));
					downloads.push(download);
				});
			});

			return downloads;
		});
	}
};
<commit_msg>Fix movies names in newpct search<commit_after>"use strict";
let axios = require("axios");
let cheerio = require("cheerio");
let url = require("../config").newpct;
const vm = require('vm');
const _ = require('lodash');

function runNewpctScript(code) {
	const fake$ = () => {
		return {
			ready: _.noop,
			load: _.noop,
			scroll: _.noop
		};
	};
	const sandbox = vm.createContext({
		$: fake$,
		document: Object.create(null),
		window: Object.create(null),
		setInterval: _.noop
	});
	vm.runInNewContext(code, sandbox, { filename: 'newpctscript.js' });
	return sandbox;
}

async function getTVShowEpisodeTorrentUrl(tvShowUrl, season, episode, page = 1) {
	const response = await axios.get(`${tvShowUrl}/pg/${page}`);
	const $ = cheerio.load(response.data);
	const $episodeList = $('.buscar-list li');
	if (!$episodeList.length) {
		return null;
	}
	const $result = $episodeList.filter((index, episodeElement) => {
		const $episode = $(episodeElement);
		return $episode.find('h2').text().includes(`Temporada ${season} Capitulo ${episode}`);
	});
	if ($result.length) {
		return $result.eq(0).find('a').eq(0).attr('href');
	}
	return getTVShowEpisodeTorrentUrl(tvShowUrl, season, episode, ++page);
}

module.exports = {
	async search(query, page) {
		let queryUrl = url + '/index.php';
		const response = await axios.get(queryUrl, {
			params: {
				page: 'buscar',
				q: query,
				pg: page
			}
		});
		const $ = cheerio.load(response.data);
			const $searchResults = $('.buscar-list li');
			const torrents = [];
			const ids = [];
			for (let i = 0; i < $searchResults.length; i++) {
				const $element = $searchResults.eq(i);
				const torrent = {};
				torrent.url = $element.find('a').eq(0).attr('href');
				if (torrent.url.includes('series')) {
					torrent.name = $element.find('h2 strong').text();
					const category = $element.find('h2 span:last-of-type').text();
					torrent.category = category.replace(/\[/gi, '').replace(/\]/gi, '').trim();
					const titleWords = torrent.name.split(' ');
					const season = titleWords[titleWords.indexOf('Temporada') + 1];
					const episode = titleWords[titleWords.indexOf('Capitulo') + 1];
					torrent.url = await getTVShowEpisodeTorrentUrl(torrent.url, season, episode);
					if (!torrent.url) {
						continue;
					}
				} else {
					torrent.name = $element.find('h2').text();
				}
				const id = torrent.url.replace(url, '');
				if (ids.includes(id)) {
					continue;
				}
				ids.push(id);
				torrent.id = encodeURIComponent(id);
				torrent.image = $element.find('img').attr('src');
				torrents.push(torrent);
			}
			const total = parseInt($('.page-box h3 strong').text().match(/\((.*?)\)/gi)[0].replace(/\(/gi, '').replace(/\)/gi, '').trim());
			return {
				torrents,
				total
			};
	},
	getTorrent(id) {
		return axios.get(`${url}${decodeURIComponent(id)}`).then((response) => {
			let $ = cheerio.load(response.data);
			let torrent = {};
			torrent.title = $('.page-box h1 strong').text().trim();
			torrent.image = $('.entry-left img').eq(0).attr('src');
			torrent.description = $('.descripcion_top').text();
			torrent.category = $('.page-box h1').text().match(/\[(.*?)\]/gi)[0].replace(/\[/gi, '').replace(/\]/gi, '');
			torrent.url = $('.f2-tab2 a').attr('href');
			return torrent;
		});
	},
	getLastDownloads() {
		return axios.get(url).then((response) => {
			let $ = cheerio.load(response.data);
			const script = $('script[src="http://www.newpct1.com/pct1/library/content/template/js/custom.js"]').next();
			const scriptVariables = runNewpctScript(script.html());
			const downloadProperties = ['id', 'url', 'image', 'name', 'category', 'cta'];
			const arrays = ['arrayMODPC', 'arrayMODEC', 'arrayMODOP', 'arrayMODSE', 'arrayMODx264', 'arrayMODSH', 'arrayMODSVO', 'arrayMODPH', 'arrayMODP3D', 'arrayMODPL', 'arrayMODV'];
			const downloads = [];

			arrays.forEach((array) => {
				scriptVariables[array].forEach((rawDownload) => {
					const download = {};
					rawDownload.forEach((property, index) => {
						download[downloadProperties[index]] = property.trim();
					});
					download.id = encodeURIComponent(download.url.replace(url, ''));
					downloads.push(download);
				});
			});

			return downloads;
		});
	}
};
<|endoftext|>


<commit_before>'use strict';

/*
 trees - a module for trees in gramene

 */
var TreeModel = require('tree-model');
var FlatToNested = require('flat-to-nested');
var _ = require('lodash');

module.exports = {
  tree: function (taxonomy) {
    function cleanUpProperties(taxonomy) {
      return taxonomy.map(function (taxon) {
        if (!taxon.is_a) {
          if (taxon._id !== 1) {
            throw new Error('unrooted node!');
          }
        }

        return {
          id: taxon._id,
          parent: taxon.is_a ? taxon.is_a[0] : undefined,
          rank: taxon.property_value ? taxon.property_value.substring(19) : 'not specified',
          name: taxon.name,
          synonyms: taxon.synonym || []
        };
      });
    }

    function createTree(nestedTaxa) {
      function childNodeNameLexComparator(a, b) {
        return a.name > b.name ? 1 : -1;
      }

      return new TreeModel({modelComparatorFn: childNodeNameLexComparator}).parse(nestedTaxa);
    }

    function compressTreePaths(tree) {
      tree.all(function (node) {
        return !node.isRoot() && node.children.length === 1;
      }).forEach(function (node) {
        var parent = node.parent
          , child = node.children[0];

        parent.addChild(child);
        node.drop();

        // maintain the link from the compressed node to the parent
        // (this is deleted in call to node.drop())
        node.parent = parent;
        node.compressed = true;

        if (!child.compressedNodes) {
          child.compressedNodes = [];
        }
        child.compressedNodes.push(node);
        if (node.compressedNodes) {
          child.compressedNodes = node.compressedNodes.concat(child.compressedNodes);
          delete node.compressedNodes;
        }
      });
    }

    function decorateTree(tree) {
      tree.depth = function calculateEffectiveNodeDepth(node) {
        var path = node.getPath()
          , depth = path.length - 1
          , compressedDepth = _.reduce(path, function (acc, n) {
            return acc + (n.compressedNodes ? n.compressedNodes.length : 0);
          }, 0);

        return depth + compressedDepth;
      };

      tree.leafNodes = function findAllLeafNodes() {
        return tree.all(function (node) { return !node.hasChildren(); });
      };

      tree.lca = function lowestCommonAncestor(nodes) {
        var parentNodesInCommon = _.chain(nodes)
          .map(function (node) {
            return node.getPath(); // .map(function (n) { return n.model.id });
          })
          .reduce(function (acc, nextPath) {
            return _.intersection(acc, nextPath)
          })
          .value();
        return parentNodesInCommon.pop();
      }
    }

    function indexTree(tree, attrs) {
      tree.indices = _.chain(attrs)
        .map(function (attr) {
          var result = {_attr: attr};
          tree.walk(function (node) {
            result[node.model[attr]] = node;
          });
          return result;
        })
        .indexBy('_attr')
        .value();
    }

    var taxa
      , nestedTaxa
      , tree;

    taxa = cleanUpProperties(taxonomy);
    nestedTaxa = new FlatToNested().convert(taxa);
    tree = createTree(nestedTaxa);
    indexTree(tree, ['id', 'name']);
    compressTreePaths(tree);
    decorateTree(tree);

    return tree;
  }
};<commit_msg>added semicolon<commit_after>'use strict';

/*
 trees - a module for trees in gramene

 */
var TreeModel = require('tree-model');
var FlatToNested = require('flat-to-nested');
var _ = require('lodash');

module.exports = {
  tree: function (taxonomy) {
    function cleanUpProperties(taxonomy) {
      return taxonomy.map(function (taxon) {
        if (!taxon.is_a) {
          if (taxon._id !== 1) {
            throw new Error('unrooted node!');
          }
        }

        return {
          id: taxon._id,
          parent: taxon.is_a ? taxon.is_a[0] : undefined,
          rank: taxon.property_value ? taxon.property_value.substring(19) : 'not specified',
          name: taxon.name,
          synonyms: taxon.synonym || []
        };
      });
    }

    function createTree(nestedTaxa) {
      function childNodeNameLexComparator(a, b) {
        return a.name > b.name ? 1 : -1;
      }

      return new TreeModel({modelComparatorFn: childNodeNameLexComparator}).parse(nestedTaxa);
    }

    function compressTreePaths(tree) {
      tree.all(function (node) {
        return !node.isRoot() && node.children.length === 1;
      }).forEach(function (node) {
        var parent = node.parent
          , child = node.children[0];

        parent.addChild(child);
        node.drop();

        // maintain the link from the compressed node to the parent
        // (this is deleted in call to node.drop())
        node.parent = parent;
        node.compressed = true;

        if (!child.compressedNodes) {
          child.compressedNodes = [];
        }
        child.compressedNodes.push(node);
        if (node.compressedNodes) {
          child.compressedNodes = node.compressedNodes.concat(child.compressedNodes);
          delete node.compressedNodes;
        }
      });
    }

    function decorateTree(tree) {
      tree.depth = function calculateEffectiveNodeDepth(node) {
        var path = node.getPath()
          , depth = path.length - 1
          , compressedDepth = _.reduce(path, function (acc, n) {
            return acc + (n.compressedNodes ? n.compressedNodes.length : 0);
          }, 0);

        return depth + compressedDepth;
      };

      tree.leafNodes = function findAllLeafNodes() {
        return tree.all(function (node) { return !node.hasChildren(); });
      };

      tree.lca = function lowestCommonAncestor(nodes) {
        var parentNodesInCommon = _.chain(nodes)
          .map(function (node) {
            return node.getPath(); // .map(function (n) { return n.model.id });
          })
          .reduce(function (acc, nextPath) {
            return _.intersection(acc, nextPath)
          })
          .value();
        return parentNodesInCommon.pop();
      };
    }

    function indexTree(tree, attrs) {
      tree.indices = _.chain(attrs)
        .map(function (attr) {
          var result = {_attr: attr};
          tree.walk(function (node) {
            result[node.model[attr]] = node;
          });
          return result;
        })
        .indexBy('_attr')
        .value();
    }

    var taxa
      , nestedTaxa
      , tree;

    taxa = cleanUpProperties(taxonomy);
    nestedTaxa = new FlatToNested().convert(taxa);
    tree = createTree(nestedTaxa);
    indexTree(tree, ['id', 'name']);
    compressTreePaths(tree);
    decorateTree(tree);

    return tree;
  }
};<|endoftext|>


<commit_before>const awaitMethodName = 'await';
const renderMethodName = 'render';

class Engine {
    constructor(container = {}) {
        this.container = container;
    }

    register(...types) {
        types.forEach(type => this.container[type.name] = type);
        return this;
    }

    getInstanceParams() {
        return {
            renderAll: (...args) => this.renderAll(...args),
            render: (...args) => this.render(...args),
            components: this.container
        };
    }

    instantiate(component) {
        return new component(this.getInstanceParams());
    }

    renderAll(...components) {
        return (...params) => new Promise((resolve, reject) => {
            let renderedComponents = {};
            let renderedComponentsCnt = 0;
            components.forEach(component => this.render(component, ...params).then(rendering => {
                renderedComponents[component.name] = rendering;
                if (++renderedComponentsCnt >= components.length) {
                    resolve(renderedComponents);
                }
            }).catch(reject));
        });
    }

    render(component, ...params) {
        return new Promise((resolve, reject) => {
            let instance = this.instantiate(component),
                instanceRender = () => resolve(instance[renderMethodName](...params));

            if (instance[awaitMethodName] !== undefined) {
                new Promise((awaitResolve, awaitReject) =>
                    instance[awaitMethodName](awaitResolve, this.getInstanceParams()))
                .then(instanceRender)
                .catch(reject);
            } else {
                try {
                    instanceRender();
                } catch(error) {
                    reject(error);
                }
            }
        });
    }
}

class Message {
    render({ message, type  = 'info' } = {}) {
        return `<h1 class="${ type }">${ message }</h1>`;
    }
}

class Button {
    render({ text } = {}) {
        return `<button></button>`;
    }
}

class HomePage {
    await(done, { renderAll, components }) {
        renderAll(components.Message, components.Button)({
            message: 'home page',
            type: 'success'
        }).then(html => {
            this.html = html;
            this.title = 'Hello world';
            done();
        });
    }

    render({ subtitle }) {
        return `

${ this.title }

${ subtitle }

${ this.html.Message } ${ this.html.Button }

        `;
    }

}

let engine = new Engine().register(
    HomePage,
    Message,
    Button
);

engine.render(HomePage, { subtitle: 'subtitle' }).then(console.log);
<commit_msg>synchronous rendering<commit_after>const awaitMethodName = 'await';
const renderMethodName = 'render';

class Engine {
    constructor(container = {}) {
        this.container = container;
    }

    register(...types) {
        types.forEach(type => this.container[type.name] = type);
        return this;
    }

    getInstanceParams() {
        return {
            render: (...args) => this.render(...args),
            renderAll: (...args) => this.renderAll(...args),
            asyncRenderAll: (...args) => this.asyncRenderAll(...args),
            asyncRender: (...args) => this.asyncRender(...args),
            components: this.container
        };
    }

    instantiate(component) {
        return new component(this.getInstanceParams());
    }

    render(component, ...params) {
        return this.instantiate(component)[renderMethodName](...params);
    }

    renderAll(...components) {
        return (...params) => {
            let result = {};
            components.forEach(component =>
                result[component.name] = this.render(component, ...params));
            return result;
        };
    }

    asyncRenderAll(...components) {
        return (...params) => new Promise((resolve, reject) => {
            let renderedComponents = {};
            let renderedComponentsCnt = 0;
            components.forEach(component => this.asyncRender(component, ...params).then(rendering => {
                renderedComponents[component.name] = rendering;
                if (++renderedComponentsCnt >= components.length) {
                    resolve(renderedComponents);
                }
            }).catch(reject));
        });
    }

    asyncRender(component, ...params) {
        return new Promise((resolve, reject) => {
            let instance = this.instantiate(component),
                instanceRender = () => resolve(instance[renderMethodName](...params));

            if (instance[awaitMethodName] !== undefined) {
                new Promise((awaitResolve, awaitReject) =>
                    instance[awaitMethodName](awaitResolve, this.getInstanceParams()))
                .then(instanceRender)
                .catch(reject);
            } else {
                try {
                    instanceRender();
                } catch(error) {
                    reject(error);
                }
            }
        });
    }
}

class Message {
    render({ message, type  = 'info' } = {}) {
        return `<h1 class="${ type }">${ message }</h1>`;
    }
}

class Button {
    render({ text } = {}) {
        return `<button></button>`;
    }
}

class HomePage {
    await(done, { asyncRenderAll, components }) {
        asyncRenderAll(components.Message, components.Button)({
            message: 'home page',
            type: 'success'
        }).then(html => {
            this.html = html;
            this.title = 'Hello world';
            done();
        });
    }

    render({ subtitle }) {
        return `

${ this.title }

${ subtitle }

${ this.html.Message } ${ this.html.Button }

        `;
    }

}

let engine = new Engine().register(
    HomePage,
    Message,
    Button
);

engine.asyncRender(HomePage, { subtitle: 'subtitle' }).then(console.log);
<|endoftext|>


<commit_before>define(["Element"], function($Element, _parseFragment, _legacy, _forOwn, _forEach, _makeError) {
    "use strict";

    // SETTER
    // ------

    (function() {
        var hooks = {};

        /**
         * Set property/attribute value
         * @param {String} [name] property/attribute name
         * @param {String} value property/attribute value
         * @return {$Element}
         * @tutorial Getter and setter
         */
        $Element.prototype.set = function(name, value) {
            var len = arguments.length,
                nameType = typeof name;

            return _legacy(this, function(node, el) {
                var initialName, hook;

                if (len === 1) {
                    if (name == null) {
                        value = "";
                    } else if (nameType === "object") {
                        return _forOwn(name, function(value, name) { el.set(name, value) });
                    } else {
                        // handle numbers, booleans etc.
                        value = nameType === "function" ? name : String(name);
                    }

                    initialName = name;

                    if (node.type && "value" in node) {
                        // for IE use innerText because it doesn't trigger onpropertychange
                        name = window.addEventListener ? "value" : "innerText";
                    } else {
                        name = "innerHTML";
                    }
                } else if (len > 2 || len === 0 || nameType !== "string") {
                    throw _makeError("set", el);
                }

                if (typeof value === "function") {
                    value = value.call(el, value.length ? el.get(name) : undefined);
                }

                if (hook = hooks[name]) {
                    hook(node, value);
                } else if (value == null) {
                    node.removeAttribute(name);
                } else if (name in node) {
                    node[name] = value;
                } else {
                    node.setAttribute(name, value);
                }

                if (initialName) {
                    name = initialName;
                    value = undefined;
                }
            });
        };

        hooks.defaultValue = function(node, value) {
            // emulate defaultValue for select via selected attribute
            if (node.tagName === "SELECT") {
                _forEach(node.options, function(option) {
                    if (option.value === value) option.selected = true;
                });
            }

            node.defaultValue = value;
        };

        if (document.attachEvent) {
            // fix NoScope elements in IE < 10
            hooks.innerHTML = function(node, value) {
                node.innerHTML = "";
                node.appendChild(_parseFragment(value));
            };
        }
    })();
});
<commit_msg>fix $Element.set<commit_after>define(["Element"], function($Element, _parseFragment, _legacy, _forOwn, _forEach, _makeError) {
    "use strict";

    // SETTER
    // ------

    (function() {
        var hooks = {};

        /**
         * Set property/attribute value
         * @param {String} [name] property/attribute name
         * @param {String} value property/attribute value
         * @return {$Element}
         * @tutorial Getter and setter
         */
        $Element.prototype.set = function(name, value) {
            var len = arguments.length,
                nameType = typeof name;

            return _legacy(this, function(node, el) {
                var initialName, hook;

                if (len === 1) {
                    if (name == null) {
                        value = "";
                    } else if (nameType === "object") {
                        return _forOwn(name, function(value, name) { el.set(name, value) });
                    } else {
                        // handle numbers, booleans etc.
                        value = nameType === "function" ? name : String(name);
                    }

                    initialName = name;

                    if (node.type && "value" in node) {
                        // for IE use innerText because it doesn't trigger onpropertychange
                        name = window.addEventListener ? "value" : "innerText";
                    } else {
                        name = "innerHTML";
                    }
                } else if (len > 2 || len === 0 || nameType !== "string") {
                    throw _makeError("set", el);
                }

                if (typeof value === "function") {
                    value = value.call(el, value.length ? el.get(name) : undefined);
                }

                if (hook = hooks[name]) {
                    hook(node, value);
                } else if (value == null) {
                    node.removeAttribute(name);
                } else if (name in node) {
                    node[name] = value;
                } else {
                    node.setAttribute(name, value);
                }

                if (initialName) {
                    name = initialName;
                    value = undefined;
                }
            });
        };

        hooks.defaultValue = function(node, value) {
            // emulate defaultValue for select via selected attribute
            if (node.tagName === "SELECT") {
                _forEach(node.options, function(option) {
                    if (option.value === value) {
                        option.selected = true;
                        option.setAttribute("selected", "selected");
                    }
                });
            }

            node.defaultValue = value;
        };

        if (document.attachEvent) {
            // fix NoScope elements in IE < 10
            hooks.innerHTML = function(node, value) {
                node.innerHTML = "";
                node.appendChild(_parseFragment(value));
            };
        }
    })();
});
<|endoftext|>