<commit_before>
ElmRuntime.Render.Element = function() {
'use strict';

var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
var newElement = Utils.newElement, extract = Utils.extract,
    addTransform = Utils.addTransform, removeTransform = Utils.removeTransform,
    fromList = Utils.fromList, eq = Utils.eq;

function setProps(props, e) {
    e.style.width  = (props.width |0) + 'px';
    e.style.height = (props.height|0) + 'px';
    if (props.opacity !== 1) { e.style.opacity = props.opacity; }
    if (props.color.ctor === 'Just') {
        e.style.backgroundColor = extract(props.color._0);
    }
    if (props.tag !== '') { e.id = props.tag; }
    if (props.href !== '') {
        var a = newElement('a');
        a.href = props.href;
        a.style.width = '100%';
        a.style.height = '100%';
        a.style.top = 0;
        a.style.left = 0;
        a.style.display = 'block';
        a.style.position = 'absolute';
        e.style.position = 'relative';
        e.appendChild(a);
    }
    if (props.hover.ctor !== '_Tuple0') {
        var overCount = 0;
        e.addEventListener('mouseover', function() {
            if (overCount++ > 0) return;
            props.hover(true);
        });
        e.addEventListener('mouseout', function(evt) {
            if (e.contains(evt.toElement || evt.relatedTarget)) return;
            overCount = 0;
            props.hover(false);
        });
    }
    return e;
}

function image(props, img) {
    switch (img._0.ctor) {
    case 'Plain':   return plainImage(img._3);
    case 'Fitted':  return fittedImage(props.width, props.height, img._3);
    case 'Cropped': return croppedImage(img,props.width,props.height,img._3);
    case 'Tiled':   return tiledImage(img._3);
    }
}

function plainImage(src) {
    var img = newElement('img');
    img.src = src;
    img.name = src;
    img.style.display = "block";
    return img;
}

function tiledImage(src) {
    var div = newElement('div');
    div.style.backgroundImage = 'url(' + src + ')';
    return div;
}

function fittedImage(w, h, src) {
    var div = newElement('div');
    div.style.background = 'url(' + src + ') no-repeat center';
    div.style.webkitBackgroundSize = 'cover';
    div.style.MozBackgroundSize = 'cover';
    div.style.OBackgroundSize = 'cover';
    div.style.backgroundSize = 'cover';
    return div;
}

function croppedImage(elem, w, h, src) {
    var pos = elem._0._0;
    var e = newElement('div');
    e.style.overflow = "hidden";

    var img = newElement('img');
    img.onload = function() {
        var sw = w / elem._1, sh = h / elem._2;
        img.style.width = ((this.width * sw)|0) + 'px';
        img.style.height = ((this.height * sh)|0) + 'px';
        img.style.marginLeft = ((- pos._0 * sw)|0) + 'px';
        img.style.marginTop = ((- pos._1 * sh)|0) + 'px';
    };
    img.src = src;
    img.name = src;
    e.appendChild(img);
    return e;
}

function goIn(e) { e.style.position = 'absolute'; return e; }
function goDown(e) { return e }
function goRight(e) { e.style.styleFloat = e.style.cssFloat = "left"; return e; }
function flowWith(f, array) {
    var container = newElement('div');
    for (var i = array.length; i--; ) {
        container.appendChild(f(render(array[i])));
    }
    return container;
}

function flow(dir,elist) {
    var array = fromList(elist);
    switch(dir.ctor) {
    case "DDown":  array.reverse();
    case "DUp":    return flowWith(goDown,array);
    case "DRight": array.reverse();
    case "DLeft":  return flowWith(goRight,array);
    case "DOut":   array.reverse();
    case "DIn":    return flowWith(goIn,array);
    }
}

function toPos(pos) {
    switch(pos.ctor) {
    case "Absolute": return  pos._0 + "px";
    case "Relative": return (pos._0 * 100) + "%";
    }
}

// must clear right, left, top, bottom, and transform
// before calling this function
function setPos(pos,w,h,e) {
    e.style.position = 'absolute';
    e.style.margin = 'auto';
    var transform = '';
    switch(pos.horizontal.ctor) {
    case 'P': e.style.right = toPos(pos.x); e.style.removeProperty('left'); break;
    case 'Z': transform = 'translateX(' + ((-w/2)|0) + 'px) ';
    case 'N': e.style.left = toPos(pos.x); e.style.removeProperty('right'); break;
    }
    switch(pos.vertical.ctor) {
    case 'N': e.style.bottom = toPos(pos.y); e.style.removeProperty('top'); break;
    case 'Z': transform += 'translateY(' + ((-h/2)|0) + 'px)';
    case 'P': e.style.top = toPos(pos.y); e.style.removeProperty('bottom'); break;
    }
    if (transform !== '') addTransform(e.style, transform);
    return e;
}

function container(pos,elem) {
    var e = render(elem);
    setPos(pos, elem.props.width, elem.props.height, e);
    var div = newElement('div');
    div.style.position = 'relative';
    div.style.overflow = 'hidden';
    div.appendChild(e);
    return div;
}

function rawHtml(elem) {
    var html = elem.html;
    var args = elem.args;
    var guid = elem.guid;

    var div = newElement('div');
    div.innerHTML = html;
    div.style.visibility = "hidden";
    document.body.appendChild(div);

    for (var i = args.length; i--; ) {
        var arg = args[i];
        var span = document.getElementById('md-' + guid + '-' + i);
        if (arg.isText) {
            span.innerHTML = arg;
        } else {
            span.style.display = 'block';
            span.style.width = arg.props.width + 'px';
            span.style.height = arg.props.height + 'px';
            span.appendChild(render(arg));
        }
    }
    document.body.removeChild(div);
    div.style.visibility = 'visible';
    return div;
}

function render(elem) { return setProps(elem.props, makeElement(elem)); }
function makeElement(e) {
    var elem = e.element;
    switch(elem.ctor) {
    case 'Image':     return image(e.props, elem);
    case 'Flow':      return flow(elem._0, elem._1);
    case 'Container': return container(elem._0, elem._1);
    case 'Spacer':    return newElement('div');
    case 'RawHtml':   return rawHtml(elem);
    case 'Custom':    return elem.render(elem.model);
    }
}

function update(node, curr, next) {
    if (node.tagName === 'A') { node = node.firstChild; }
    if (curr.props.id === next.props.id) return updateProps(node, curr, next);
    if (curr.element.ctor !== next.element.ctor) {
        node.parentNode.replaceChild(render(next),node);
        return true;
    }
    var nextE = next.element, currE = curr.element;
    switch(nextE.ctor) {
    case "Spacer": break;
    case "RawHtml":
        if (nextE.guid !== currE.guid) {
            node.parentNode.replaceChild(render(next),node);
            return true;
        }
        var nargs = nextE.args;
        var cargs = currE.args;
        for (var i = nargs.length; i--; ) {
            var narg = nargs[i];
            var carg = cargs[i]
            if (narg == carg) continue;
            var span = document.getElementById('md-' + currE.guid + '-' + i);
            if (narg.isElement) {
                if (carg.isElement) {
                    update(span, carg, narg);
                } else {
                    span.style.display = 'block';
                    var e = render(narg);
                    span.innerHTML = '';
                    span.appendChild(e);
                }
            } else {
                span.style.display = 'inline';
                span.innerHTML = narg;
            }
        }
        break;
    case "Image":
        if (nextE._0.ctor === 'Plain') {
            if (nextE._3 !== currE._3) node.src = nextE._3;
        } else if (!eq(nextE,currE) ||
                   next.props.width !== curr.props.width ||
                   next.props.height !== curr.props.height) {
            node.parentNode.replaceChild(render(next),node);
            return true;
        }
        break;
    case "Flow":
        var arr = fromList(nextE._1);
        for (var i = arr.length; i--; ) { arr[i] = arr[i].element.ctor; }
        if (nextE._0.ctor !== currE._0.ctor) {
            node.parentNode.replaceChild(render(next),node);
            return true;
        }
        var nexts = fromList(nextE._1);
        var kids = node.childNodes;
        if (nexts.length !== kids.length) {
            node.parentNode.replaceChild(render(next),node);
            return true;
        }
        var currs = fromList(currE._1);
        var goDir = function(x) { return x; };
        switch(nextE._0.ctor) {
        case "DDown":  case "DUp":   goDir = goDown; break;
        case "DRight": case "DLeft": goDir = goRight; break;
        case "DOut":   case "DIn":   goDir = goIn; break;
        }
        for (var i = kids.length; i-- ;) {
            update(kids[i],currs[i],nexts[i]);
            goDir(kids[i]);
        }
        break;
    case "Container":
        update(node.firstChild, currE._1, nextE._1)
        setPos(nextE._0, nextE._1.props.width, nextE._1.props.height, node.firstChild);
        break;
    case "Custom":
        if (currE.type === nextE.type) {
            var done = nextE.update(node, currE.model, nextE.model);
            if (done) return;
        } else {
            return node.parentNode.replaceChild(render(next), node);
        }
    }
    updateProps(node, curr, next);
}

function updateProps(node, curr, next) {
    var props = next.props, currP = curr.props, e = node;
    if (props.width !== currP.width)   e.style.width  = (props.width |0) + 'px';
    if (props.height !== currP.height) e.style.height = (props.height|0) + 'px';
    if (props.opacity !== 1 && props.opacity !== currP.opacity) {
        e.style.opacity = props.opacity;
    }
    var nextColor = (props.color.ctor === 'Just' ?
                     extract(props.color._0) : '');
    if (e.style.backgroundColor !== nextColor) {
        e.style.backgroundColor = (nextColor === '' ? 'transparent' : nextColor);
    }
    if (props.tag !== currP.tag) { e.id = props.tag; }
    if (props.href !== currP.href) {
        if (currP.href === '') {
            var a = newElement('a');
            a.href = props.href;
            a.style.width = '100%';
            a.style.height = '100%';
            a.style.top = 0;
            a.style.left = 0;
            a.style.display = 'block';
            a.style.position = 'absolute';
            e.style.position = 'relative';
            e.appendChild(a);
        } else {
            node.lastNode.href = props.href;
        }
    }
}

return { render:render, update:update };

};<commit_msg>Fix newline at EOF in Element.js<commit_after>
ElmRuntime.Render.Element = function() {
'use strict';

var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
var newElement = Utils.newElement, extract = Utils.extract,
    addTransform = Utils.addTransform, removeTransform = Utils.removeTransform,
    fromList = Utils.fromList, eq = Utils.eq;

function setProps(props, e) {
    e.style.width  = (props.width |0) + 'px';
    e.style.height = (props.height|0) + 'px';
    if (props.opacity !== 1) { e.style.opacity = props.opacity; }
    if (props.color.ctor === 'Just') {
        e.style.backgroundColor = extract(props.color._0);
    }
    if (props.tag !== '') { e.id = props.tag; }
    if (props.href !== '') {
        var a = newElement('a');
        a.href = props.href;
        a.style.width = '100%';
        a.style.height = '100%';
        a.style.top = 0;
        a.style.left = 0;
        a.style.display = 'block';
        a.style.position = 'absolute';
        e.style.position = 'relative';
        e.appendChild(a);
    }
    if (props.hover.ctor !== '_Tuple0') {
        var overCount = 0;
        e.addEventListener('mouseover', function() {
            if (overCount++ > 0) return;
            props.hover(true);
        });
        e.addEventListener('mouseout', function(evt) {
            if (e.contains(evt.toElement || evt.relatedTarget)) return;
            overCount = 0;
            props.hover(false);
        });
    }
    return e;
}

function image(props, img) {
    switch (img._0.ctor) {
    case 'Plain':   return plainImage(img._3);
    case 'Fitted':  return fittedImage(props.width, props.height, img._3);
    case 'Cropped': return croppedImage(img,props.width,props.height,img._3);
    case 'Tiled':   return tiledImage(img._3);
    }
}

function plainImage(src) {
    var img = newElement('img');
    img.src = src;
    img.name = src;
    img.style.display = "block";
    return img;
}

function tiledImage(src) {
    var div = newElement('div');
    div.style.backgroundImage = 'url(' + src + ')';
    return div;
}

function fittedImage(w, h, src) {
    var div = newElement('div');
    div.style.background = 'url(' + src + ') no-repeat center';
    div.style.webkitBackgroundSize = 'cover';
    div.style.MozBackgroundSize = 'cover';
    div.style.OBackgroundSize = 'cover';
    div.style.backgroundSize = 'cover';
    return div;
}

function croppedImage(elem, w, h, src) {
    var pos = elem._0._0;
    var e = newElement('div');
    e.style.overflow = "hidden";

    var img = newElement('img');
    img.onload = function() {
        var sw = w / elem._1, sh = h / elem._2;
        img.style.width = ((this.width * sw)|0) + 'px';
        img.style.height = ((this.height * sh)|0) + 'px';
        img.style.marginLeft = ((- pos._0 * sw)|0) + 'px';
        img.style.marginTop = ((- pos._1 * sh)|0) + 'px';
    };
    img.src = src;
    img.name = src;
    e.appendChild(img);
    return e;
}

function goIn(e) { e.style.position = 'absolute'; return e; }
function goDown(e) { return e }
function goRight(e) { e.style.styleFloat = e.style.cssFloat = "left"; return e; }
function flowWith(f, array) {
    var container = newElement('div');
    for (var i = array.length; i--; ) {
        container.appendChild(f(render(array[i])));
    }
    return container;
}

function flow(dir,elist) {
    var array = fromList(elist);
    switch(dir.ctor) {
    case "DDown":  array.reverse();
    case "DUp":    return flowWith(goDown,array);
    case "DRight": array.reverse();
    case "DLeft":  return flowWith(goRight,array);
    case "DOut":   array.reverse();
    case "DIn":    return flowWith(goIn,array);
    }
}

function toPos(pos) {
    switch(pos.ctor) {
    case "Absolute": return  pos._0 + "px";
    case "Relative": return (pos._0 * 100) + "%";
    }
}

// must clear right, left, top, bottom, and transform
// before calling this function
function setPos(pos,w,h,e) {
    e.style.position = 'absolute';
    e.style.margin = 'auto';
    var transform = '';
    switch(pos.horizontal.ctor) {
    case 'P': e.style.right = toPos(pos.x); e.style.removeProperty('left'); break;
    case 'Z': transform = 'translateX(' + ((-w/2)|0) + 'px) ';
    case 'N': e.style.left = toPos(pos.x); e.style.removeProperty('right'); break;
    }
    switch(pos.vertical.ctor) {
    case 'N': e.style.bottom = toPos(pos.y); e.style.removeProperty('top'); break;
    case 'Z': transform += 'translateY(' + ((-h/2)|0) + 'px)';
    case 'P': e.style.top = toPos(pos.y); e.style.removeProperty('bottom'); break;
    }
    if (transform !== '') addTransform(e.style, transform);
    return e;
}

function container(pos,elem) {
    var e = render(elem);
    setPos(pos, elem.props.width, elem.props.height, e);
    var div = newElement('div');
    div.style.position = 'relative';
    div.style.overflow = 'hidden';
    div.appendChild(e);
    return div;
}

function rawHtml(elem) {
    var html = elem.html;
    var args = elem.args;
    var guid = elem.guid;

    var div = newElement('div');
    div.innerHTML = html;
    div.style.visibility = "hidden";
    document.body.appendChild(div);

    for (var i = args.length; i--; ) {
        var arg = args[i];
        var span = document.getElementById('md-' + guid + '-' + i);
        if (arg.isText) {
            span.innerHTML = arg;
        } else {
            span.style.display = 'block';
            span.style.width = arg.props.width + 'px';
            span.style.height = arg.props.height + 'px';
            span.appendChild(render(arg));
        }
    }
    document.body.removeChild(div);
    div.style.visibility = 'visible';
    return div;
}

function render(elem) { return setProps(elem.props, makeElement(elem)); }
function makeElement(e) {
    var elem = e.element;
    switch(elem.ctor) {
    case 'Image':     return image(e.props, elem);
    case 'Flow':      return flow(elem._0, elem._1);
    case 'Container': return container(elem._0, elem._1);
    case 'Spacer':    return newElement('div');
    case 'RawHtml':   return rawHtml(elem);
    case 'Custom':    return elem.render(elem.model);
    }
}

function update(node, curr, next) {
    if (node.tagName === 'A') { node = node.firstChild; }
    if (curr.props.id === next.props.id) return updateProps(node, curr, next);
    if (curr.element.ctor !== next.element.ctor) {
        node.parentNode.replaceChild(render(next),node);
        return true;
    }
    var nextE = next.element, currE = curr.element;
    switch(nextE.ctor) {
    case "Spacer": break;
    case "RawHtml":
        if (nextE.guid !== currE.guid) {
            node.parentNode.replaceChild(render(next),node);
            return true;
        }
        var nargs = nextE.args;
        var cargs = currE.args;
        for (var i = nargs.length; i--; ) {
            var narg = nargs[i];
            var carg = cargs[i]
            if (narg == carg) continue;
            var span = document.getElementById('md-' + currE.guid + '-' + i);
            if (narg.isElement) {
                if (carg.isElement) {
                    update(span, carg, narg);
                } else {
                    span.style.display = 'block';
                    var e = render(narg);
                    span.innerHTML = '';
                    span.appendChild(e);
                }
            } else {
                span.style.display = 'inline';
                span.innerHTML = narg;
            }
        }
        break;
    case "Image":
        if (nextE._0.ctor === 'Plain') {
            if (nextE._3 !== currE._3) node.src = nextE._3;
        } else if (!eq(nextE,currE) ||
                   next.props.width !== curr.props.width ||
                   next.props.height !== curr.props.height) {
            node.parentNode.replaceChild(render(next),node);
            return true;
        }
        break;
    case "Flow":
        var arr = fromList(nextE._1);
        for (var i = arr.length; i--; ) { arr[i] = arr[i].element.ctor; }
        if (nextE._0.ctor !== currE._0.ctor) {
            node.parentNode.replaceChild(render(next),node);
            return true;
        }
        var nexts = fromList(nextE._1);
        var kids = node.childNodes;
        if (nexts.length !== kids.length) {
            node.parentNode.replaceChild(render(next),node);
            return true;
        }
        var currs = fromList(currE._1);
        var goDir = function(x) { return x; };
        switch(nextE._0.ctor) {
        case "DDown":  case "DUp":   goDir = goDown; break;
        case "DRight": case "DLeft": goDir = goRight; break;
        case "DOut":   case "DIn":   goDir = goIn; break;
        }
        for (var i = kids.length; i-- ;) {
            update(kids[i],currs[i],nexts[i]);
            goDir(kids[i]);
        }
        break;
    case "Container":
        update(node.firstChild, currE._1, nextE._1)
        setPos(nextE._0, nextE._1.props.width, nextE._1.props.height, node.firstChild);
        break;
    case "Custom":
        if (currE.type === nextE.type) {
            var done = nextE.update(node, currE.model, nextE.model);
            if (done) return;
        } else {
            return node.parentNode.replaceChild(render(next), node);
        }
    }
    updateProps(node, curr, next);
}

function updateProps(node, curr, next) {
    var props = next.props, currP = curr.props, e = node;
    if (props.width !== currP.width)   e.style.width  = (props.width |0) + 'px';
    if (props.height !== currP.height) e.style.height = (props.height|0) + 'px';
    if (props.opacity !== 1 && props.opacity !== currP.opacity) {
        e.style.opacity = props.opacity;
    }
    var nextColor = (props.color.ctor === 'Just' ?
                     extract(props.color._0) : '');
    if (e.style.backgroundColor !== nextColor) {
        e.style.backgroundColor = (nextColor === '' ? 'transparent' : nextColor);
    }
    if (props.tag !== currP.tag) { e.id = props.tag; }
    if (props.href !== currP.href) {
        if (currP.href === '') {
            var a = newElement('a');
            a.href = props.href;
            a.style.width = '100%';
            a.style.height = '100%';
            a.style.top = 0;
            a.style.left = 0;
            a.style.display = 'block';
            a.style.position = 'absolute';
            e.style.position = 'relative';
            e.appendChild(a);
        } else {
            node.lastNode.href = props.href;
        }
    }
}

return { render:render, update:update };

};
<|endoftext|>


<commit_before>'use strict'

let tls = require('tls')
let url = require('url')
let tty = require('tty')
let stream = require('stream')
let cli = require('heroku-cli-util')
let helpers = require('../lib/helpers')

/** Represents a dyno process */
class Dyno {
  /**
   * @param {Object} options
   * @param {Object} options.heroku - instance of heroku-client
   * @param {boolean} options.exit-code - get exit code from process
   * @param {string} options.command - command to run
   * @param {string} options.app - app to run dyno on
   * @param {string} options.attach - attach to dyno
   * @param {string} options.size - size of dyno to create
   * @param {boolean} options.no-tty - force not to use a tty
   * @param {Object} options.env - dyno environment variables
  */
  constructor (opts) {
    this.opts = opts
    this.heroku = opts.heroku
    if (this.opts.showStatus === undefined) this.opts.showStatus = true
  }

  /**
   * Starts the dyno
   * @returns {Promise} promise resolved when dyno process is created
   */
  start () {
    let command = this.opts['exit-code'] ? `${this.opts.command}; echo heroku-command-exit-status $?` : this.opts.command
    let start = this.heroku.request({
      path: this.opts.dyno ? `/apps/${this.opts.app}/dynos/${this.opts.dyno}` : `/apps/${this.opts.app}/dynos`,
      method: 'POST',
      headers: {
        Accept: this.opts.dyno ? 'application/vnd.heroku+json; version=3.run-inside' : 'application/vnd.heroku+json; version=3'
      },
      body: {
        command: command,
        attach: this.opts.attach,
        size: this.opts.size,
        env: this._env(),
        force_no_tty: this.opts['no-tty']
      }
    })
    .then(dyno => {
      this.dyno = dyno
      if (this.opts.attach || this.opts.dyno) return this.attach()
      else if (this.opts.showStatus) cli.action.done(this._status('done'))
    })

    if (this.opts.showStatus) {
      return cli.action(`Running ${cli.color.cyan.bold(this.opts.command)} on ${cli.color.app(this.opts.app)}`, {success: false}, start)
    } else return start
  }

  /**
   * Attaches stdin/stdout to dyno
   */
  attach () {
    return new Promise((resolve, reject) => {
      if (this.opts.showStatus) cli.action.status(this._status('starting'))
      this.resolve = resolve
      this.reject = reject
      let uri = url.parse(this.dyno.attach_url)
      let c = tls.connect(uri.port, uri.hostname, {rejectUnauthorized: this.heroku.options.rejectUnauthorized})
      c.setTimeout(1000 * 60 * 20)
      c.setEncoding('utf8')
      c.on('connect', () => {
        c.write(uri.path.substr(1) + '\r\n', () => {
          if (this.opts.showStatus) cli.action.status(this._status('connecting'))
        })
      })
      c.on('data', this._readData(c))
      c.on('close', () => {
        this.opts['exit-code'] ? reject('No exit code returned') : resolve()
        if (this.unpipeStdin) this.unpipeStdin()
      })
      c.on('error', reject)
      process.once('SIGINT', () => c.end())
    })
  }

  _env () {
    let c = this.opts.env ? helpers.buildEnvFromFlag(this.opts.env) : {}
    c.TERM = process.env.TERM
    if (tty.isatty(1)) {
      c.COLUMNS = process.stdout.columns
      c.LINES = process.stdout.rows
    }
    return c
  }

  _status (status) {
    return `${status}, ${this.dyno.name || this.opts.dyno}`
  }

  _readData (c) {
    let firstLine = true
    return data => {
      // discard first line
      if (firstLine) {
        if (this.opts.showStatus) cli.action.done(this._status('up'))
        firstLine = false
        this._readStdin(c)
        return
      }
      data = data.replace('\r\n', '\n')
      let exitCode = data.match(/heroku-command-exit-status (\d+)/m)
      if (exitCode) {
        process.stdout.write(data.replace(/^heroku-command-exit-status \d+$\n?/m, ''))
        let code = parseInt(exitCode[1])
        if (code === 0) this.resolve()
        else {
          let err = new Error(`Process exited with code ${cli.color.red(code)}`)
          err.exitCode = code
          this.reject(err)
        }
        return
      }
      process.stdout.write(data)
    }
  }

  _readStdin (c) {
    let stdin = process.stdin
    stdin.setEncoding('utf8')
    stdin.unref()
    if (tty.isatty(0)) {
      stdin.setRawMode(true)
      stdin.pipe(c)
      let sigints = []
      stdin.on('data', function (c) {
        if (c === '\u0003') sigints.push(new Date())
        sigints = sigints.filter(d => d > new Date() - 1000)
        if (sigints.length >= 4) {
          cli.error('forcing dyno disconnect')
          process.exit(1)
        }
      })
    } else {
      stdin.pipe(new stream.Transform({
        objectMode: true,
        transform: (chunk, _, next) => c.write(chunk, next),
        flush: done => c.write('\x04', done)
      }))
    }
  }
}

module.exports = Dyno
<commit_msg>only unref if defined<commit_after>'use strict'

let tls = require('tls')
let url = require('url')
let tty = require('tty')
let stream = require('stream')
let cli = require('heroku-cli-util')
let helpers = require('../lib/helpers')

/** Represents a dyno process */
class Dyno {
  /**
   * @param {Object} options
   * @param {Object} options.heroku - instance of heroku-client
   * @param {boolean} options.exit-code - get exit code from process
   * @param {string} options.command - command to run
   * @param {string} options.app - app to run dyno on
   * @param {string} options.attach - attach to dyno
   * @param {string} options.size - size of dyno to create
   * @param {boolean} options.no-tty - force not to use a tty
   * @param {Object} options.env - dyno environment variables
  */
  constructor (opts) {
    this.opts = opts
    this.heroku = opts.heroku
    if (this.opts.showStatus === undefined) this.opts.showStatus = true
  }

  /**
   * Starts the dyno
   * @returns {Promise} promise resolved when dyno process is created
   */
  start () {
    let command = this.opts['exit-code'] ? `${this.opts.command}; echo heroku-command-exit-status $?` : this.opts.command
    let start = this.heroku.request({
      path: this.opts.dyno ? `/apps/${this.opts.app}/dynos/${this.opts.dyno}` : `/apps/${this.opts.app}/dynos`,
      method: 'POST',
      headers: {
        Accept: this.opts.dyno ? 'application/vnd.heroku+json; version=3.run-inside' : 'application/vnd.heroku+json; version=3'
      },
      body: {
        command: command,
        attach: this.opts.attach,
        size: this.opts.size,
        env: this._env(),
        force_no_tty: this.opts['no-tty']
      }
    })
    .then(dyno => {
      this.dyno = dyno
      if (this.opts.attach || this.opts.dyno) return this.attach()
      else if (this.opts.showStatus) cli.action.done(this._status('done'))
    })

    if (this.opts.showStatus) {
      return cli.action(`Running ${cli.color.cyan.bold(this.opts.command)} on ${cli.color.app(this.opts.app)}`, {success: false}, start)
    } else return start
  }

  /**
   * Attaches stdin/stdout to dyno
   */
  attach () {
    return new Promise((resolve, reject) => {
      if (this.opts.showStatus) cli.action.status(this._status('starting'))
      this.resolve = resolve
      this.reject = reject
      let uri = url.parse(this.dyno.attach_url)
      let c = tls.connect(uri.port, uri.hostname, {rejectUnauthorized: this.heroku.options.rejectUnauthorized})
      c.setTimeout(1000 * 60 * 20)
      c.setEncoding('utf8')
      c.on('connect', () => {
        c.write(uri.path.substr(1) + '\r\n', () => {
          if (this.opts.showStatus) cli.action.status(this._status('connecting'))
        })
      })
      c.on('data', this._readData(c))
      c.on('close', () => {
        this.opts['exit-code'] ? reject('No exit code returned') : resolve()
        if (this.unpipeStdin) this.unpipeStdin()
      })
      c.on('error', reject)
      process.once('SIGINT', () => c.end())
    })
  }

  _env () {
    let c = this.opts.env ? helpers.buildEnvFromFlag(this.opts.env) : {}
    c.TERM = process.env.TERM
    if (tty.isatty(1)) {
      c.COLUMNS = process.stdout.columns
      c.LINES = process.stdout.rows
    }
    return c
  }

  _status (status) {
    return `${status}, ${this.dyno.name || this.opts.dyno}`
  }

  _readData (c) {
    let firstLine = true
    return data => {
      // discard first line
      if (firstLine) {
        if (this.opts.showStatus) cli.action.done(this._status('up'))
        firstLine = false
        this._readStdin(c)
        return
      }
      data = data.replace('\r\n', '\n')
      let exitCode = data.match(/heroku-command-exit-status (\d+)/m)
      if (exitCode) {
        process.stdout.write(data.replace(/^heroku-command-exit-status \d+$\n?/m, ''))
        let code = parseInt(exitCode[1])
        if (code === 0) this.resolve()
        else {
          let err = new Error(`Process exited with code ${cli.color.red(code)}`)
          err.exitCode = code
          this.reject(err)
        }
        return
      }
      process.stdout.write(data)
    }
  }

  _readStdin (c) {
    let stdin = process.stdin
    stdin.setEncoding('utf8')
    if (stdin.unref) stdin.unref()
    if (tty.isatty(0)) {
      stdin.setRawMode(true)
      stdin.pipe(c)
      let sigints = []
      stdin.on('data', function (c) {
        if (c === '\u0003') sigints.push(new Date())
        sigints = sigints.filter(d => d > new Date() - 1000)
        if (sigints.length >= 4) {
          cli.error('forcing dyno disconnect')
          process.exit(1)
        }
      })
    } else {
      stdin.pipe(new stream.Transform({
        objectMode: true,
        transform: (chunk, _, next) => c.write(chunk, next),
        flush: done => c.write('\x04', done)
      }))
    }
  }
}

module.exports = Dyno
<|endoftext|>


<commit_before>/*
 Copyright 2012 Telefonica Investigación y Desarrollo, S.A.U

 This file is part of PopBox.

 PopBox is free software: you can redistribute it and/or modify it under the
 terms of the GNU Affero General Public License as published by the Free
 Software Foundation, either version 3 of the License, or (at your option) any
 later version.
 PopBox is distributed in the hope that it will be useful, but WITHOUT ANY
 WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
 License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with PopBox. If not, seehttp://www.gnu.org/licenses/.

 For those usages not covered by the GNU Affero General Public License
 please contact with::dtc_support@tid.es
 */

var dir_prefix = './';
if (process.env.POPBOX_DIR_PREFIX) {
  dir_prefix = process.env.POPBOX_DIR_PREFIX;
}
/**
 * Level for logger
 * debug
 * warning
 * error
 *
 * @type {String}
 */
exports.logger = {};
exports.logger.logLevel = 'debug';
exports.logger.inspectDepth = 1;
exports.logger.Console = {
  level: 'info', timestamp: true
};
exports.logger.File = {
  level: 'debug', filename: dir_prefix +
      '/popbox.log', timestamp: true, json: false,
  maxsize: 10 * 1024 * 1024,
  maxFiles: 3
};

/**
 *
 * @type {Boolean}
 */
exports.slave = false;

/**
 *
 * @type {Boolean}
 */
exports.showDeployInformation = true;

/**
 *
 * @type {Array} ex. [{host:'localhost'}, {host:'localhost', port:'6789'}]
 */
//exports.redisServers = [{host:'localhost'}, {host:'localhost', port:'6789'}];
exports.redisServers = [
  {host: 'localhost', port: 6379}
];

/**
 * One to One relationship with redisServers
 * @type {Array} ex. [{host:'localhost'}, {host:'localhost', port:'6789'}]
 */
exports.masterRedisServers = [];

/**
 *
 * @type {Object} ex. { host:'hostname', port: 'port'}
 *
 */
exports.tranRedisServer = {host: 'localhost', port: 6379};

/**
 *
 * @type {Object} ex. { host:'hostname', port: 'port'}
 *
 */
exports.masterTranRedisServer = {};

/**
 *
 * @type {Number}
 */
exports.selectedDB = 0; //0..15 for   0 ->pre-production 1->test

/**
 *
 * @type {String}
 */
exports.dbKeyQueuePrefix = 'PB:Q|';

/**
 *
 * @type {String}
 */
exports.dbKeyTransPrefix = 'PB:T|';

/**
 *
 * @type {String}
 */
exports.dbKeyBlockingQueuePrefix = 'PB:B|';

/**
 *
 * @type {Object}
 */
exports.evLsnr = {};

/**
 *
 * @type {String}
 */
exports.evLsnr.mongoHost = 'localhost';

/**
 *
 * @type {Number}
 */
exports.evLsnr.mongoPort = 27017;

/**
 *
 * @type {String}
 */
exports.evLsnr.mongoDB = 'popbox';

/**
 *
 * @type {String}
 */
exports.evLsnr.collection = 'popbox_ev';

/**
 *
 * @type {Object}
 */
exports.agent = {};

/**
 * Maximum size of request
 * @type {Number}
 */
exports.agent.maxReqSize = '1mb';

/**
 * Maximum number of queues for transaction
 * @type {Number}
 */
exports.agent.maxNumQueues = 10000;

/**
 * Expiration date delay now+defaultExpireDelay seconds
 * @type {Number}
 */
exports.defaultExpireDelay = 3600;

/**
 * Maximum payload size
 * @type {Number}
 */
exports.agent.maxPayloadSize = 1024 * 1024;

/**
 *
 * @type {Number}
 */
exports.agent.maxMessages = 1000;

/**
 *
 * @type {Number}
 */
exports.agent.port = 3001;

/**
 * Provision timeout
 * @type {Number} seconds
 */
exports.agent.provTimeout = 3 * 60;

/**
 * Default pop timeout
 * @type {Number} seconds
 */
exports.agent.popTimeout = 5;

/**
 * Maximum pop timeout
 * @type {Number} seconds
 */
exports.agent.maxPopTimeout = 5 * 60;

/**
 * Additional time for the HTTP request (added to pop timeout)
 * @type {Number}  seconds
 */
exports.agent.graceTimeout = 60;

/**
 *
 * @type {Object}
 */
exports.cluster = {};

/**
 *
 * @type {Number} number of CPUS to be used in cluster mode (-1 for all)
 */
exports.cluster.numcpus = 0;

/**
 *
 * @type {Number} max value for expirationDate
 */
exports.MAX_TIMESTAMP = 2147483647; // 32-bit, 19 January 2038

/**
 *
 * @type {boolean}
 */
exports.enableSecure = false;

/**
 *
 * @type {String} absolute path for the certs and keys. Default will be chosen when empty.
 */
exports.agent.crtPath = '';

exports.pool = {};
/**
 *
 * @type {Number}
 */
exports.pool.maxElems = 10000;

/* generic event listener */
var gevLsnrMongo = 'localhost';
if (process.env.POPBOX_GEN_MONGO) {
  gevLsnrMongo = process.env.POPBOX_GEN_MONGO;
}
var gevLsnr = {};
gevLsnr.name = 'gevlsnr-state';
gevLsnr.event = 'NEWSTATE';
gevLsnr.mongoHost = gevLsnrMongo;
gevLsnr.mongoPort = 27017;
gevLsnr.mongoDB = 'popbox';
gevLsnr.collection = 'PopBoxState';
gevLsnr.filter = null;
gevLsnr.take = {transaction: 'transaction', state: 'state'};

var gevLsnrAction = {};
gevLsnrAction.name = 'gevlsnr-action';
gevLsnrAction.event = 'ACTION';
gevLsnrAction.mongoHost = gevLsnrMongo;
gevLsnrAction.mongoPort = 27017;
gevLsnrAction.mongoDB = 'popbox';
gevLsnrAction.collection = 'PopBoxAction';
gevLsnrAction.filter = null;
gevLsnrAction.take = {transaction: 'transaction', action: 'action'};
exports.evModules = [
  { module: './evCallbackLsnr'},
  { module: './gevLsnr', config: gevLsnr},
  { module: './gevLsnr', config: gevLsnrAction}
];

exports.connectLogger = {
  format: '[:date] :remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'
};

<commit_msg>More idiomatic default value for dir_prefix<commit_after>/*
 Copyright 2012 Telefonica Investigación y Desarrollo, S.A.U

 This file is part of PopBox.

 PopBox is free software: you can redistribute it and/or modify it under the
 terms of the GNU Affero General Public License as published by the Free
 Software Foundation, either version 3 of the License, or (at your option) any
 later version.
 PopBox is distributed in the hope that it will be useful, but WITHOUT ANY
 WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
 License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with PopBox. If not, seehttp://www.gnu.org/licenses/.

 For those usages not covered by the GNU Affero General Public License
 please contact with::dtc_support@tid.es
 */

var dir_prefix = process.env.POPBOX_DIR_PREFIX || './';

/**
 * Level for logger
 * debug
 * warning
 * error
 *
 * @type {String}
 */
exports.logger = {};
exports.logger.logLevel = 'debug';
exports.logger.inspectDepth = 1;
exports.logger.Console = {
  level: 'info', timestamp: true
};
exports.logger.File = {
  level: 'debug', filename: dir_prefix +
      '/popbox.log', timestamp: true, json: false,
  maxsize: 10 * 1024 * 1024,
  maxFiles: 3
};

/**
 *
 * @type {Boolean}
 */
exports.slave = false;

/**
 *
 * @type {Boolean}
 */
exports.showDeployInformation = true;

/**
 *
 * @type {Array} ex. [{host:'localhost'}, {host:'localhost', port:'6789'}]
 */
//exports.redisServers = [{host:'localhost'}, {host:'localhost', port:'6789'}];
exports.redisServers = [
  {host: 'localhost', port: 6379}
];

/**
 * One to One relationship with redisServers
 * @type {Array} ex. [{host:'localhost'}, {host:'localhost', port:'6789'}]
 */
exports.masterRedisServers = [];

/**
 *
 * @type {Object} ex. { host:'hostname', port: 'port'}
 *
 */
exports.tranRedisServer = {host: 'localhost', port: 6379};

/**
 *
 * @type {Object} ex. { host:'hostname', port: 'port'}
 *
 */
exports.masterTranRedisServer = {};

/**
 *
 * @type {Number}
 */
exports.selectedDB = 0; //0..15 for   0 ->pre-production 1->test

/**
 *
 * @type {String}
 */
exports.dbKeyQueuePrefix = 'PB:Q|';

/**
 *
 * @type {String}
 */
exports.dbKeyTransPrefix = 'PB:T|';

/**
 *
 * @type {String}
 */
exports.dbKeyBlockingQueuePrefix = 'PB:B|';

/**
 *
 * @type {Object}
 */
exports.evLsnr = {};

/**
 *
 * @type {String}
 */
exports.evLsnr.mongoHost = 'localhost';

/**
 *
 * @type {Number}
 */
exports.evLsnr.mongoPort = 27017;

/**
 *
 * @type {String}
 */
exports.evLsnr.mongoDB = 'popbox';

/**
 *
 * @type {String}
 */
exports.evLsnr.collection = 'popbox_ev';

/**
 *
 * @type {Object}
 */
exports.agent = {};

/**
 * Maximum size of request
 * @type {Number}
 */
exports.agent.maxReqSize = '1mb';

/**
 * Maximum number of queues for transaction
 * @type {Number}
 */
exports.agent.maxNumQueues = 10000;

/**
 * Expiration date delay now+defaultExpireDelay seconds
 * @type {Number}
 */
exports.defaultExpireDelay = 3600;

/**
 * Maximum payload size
 * @type {Number}
 */
exports.agent.maxPayloadSize = 1024 * 1024;

/**
 *
 * @type {Number}
 */
exports.agent.maxMessages = 1000;

/**
 *
 * @type {Number}
 */
exports.agent.port = 3001;

/**
 * Provision timeout
 * @type {Number} seconds
 */
exports.agent.provTimeout = 3 * 60;

/**
 * Default pop timeout
 * @type {Number} seconds
 */
exports.agent.popTimeout = 5;

/**
 * Maximum pop timeout
 * @type {Number} seconds
 */
exports.agent.maxPopTimeout = 5 * 60;

/**
 * Additional time for the HTTP request (added to pop timeout)
 * @type {Number}  seconds
 */
exports.agent.graceTimeout = 60;

/**
 *
 * @type {Object}
 */
exports.cluster = {};

/**
 *
 * @type {Number} number of CPUS to be used in cluster mode (-1 for all)
 */
exports.cluster.numcpus = 0;

/**
 *
 * @type {Number} max value for expirationDate
 */
exports.MAX_TIMESTAMP = 2147483647; // 32-bit, 19 January 2038

/**
 *
 * @type {boolean}
 */
exports.enableSecure = false;

/**
 *
 * @type {String} absolute path for the certs and keys. Default will be chosen when empty.
 */
exports.agent.crtPath = '';

exports.pool = {};
/**
 *
 * @type {Number}
 */
exports.pool.maxElems = 10000;

/* generic event listener */
var gevLsnrMongo = 'localhost';
if (process.env.POPBOX_GEN_MONGO) {
  gevLsnrMongo = process.env.POPBOX_GEN_MONGO;
}
var gevLsnr = {};
gevLsnr.name = 'gevlsnr-state';
gevLsnr.event = 'NEWSTATE';
gevLsnr.mongoHost = gevLsnrMongo;
gevLsnr.mongoPort = 27017;
gevLsnr.mongoDB = 'popbox';
gevLsnr.collection = 'PopBoxState';
gevLsnr.filter = null;
gevLsnr.take = {transaction: 'transaction', state: 'state'};

var gevLsnrAction = {};
gevLsnrAction.name = 'gevlsnr-action';
gevLsnrAction.event = 'ACTION';
gevLsnrAction.mongoHost = gevLsnrMongo;
gevLsnrAction.mongoPort = 27017;
gevLsnrAction.mongoDB = 'popbox';
gevLsnrAction.collection = 'PopBoxAction';
gevLsnrAction.filter = null;
gevLsnrAction.take = {transaction: 'transaction', action: 'action'};
exports.evModules = [
  { module: './evCallbackLsnr'},
  { module: './gevLsnr', config: gevLsnr},
  { module: './gevLsnr', config: gevLsnrAction}
];

exports.connectLogger = {
  format: '[:date] :remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'
};

<|endoftext|>


<commit_before>'esversion: 6'

var should = require("should");
var helper = require("../../../helper");
var PurchaseOrderManager = require("../../../../src/managers/purchasing/purchase-order-manager");
var PurchaseRequestManager = require("../../../../src/managers/purchasing/purchase-request-manager");
var purchaseRequestDataUtil = require("../../../data-util/purchasing/purchase-request-data-util");
var purchaseOrderDataUtil = require("../../../data-util/purchasing/purchase-order-data-util");
var purchaseOrderManager;
var purchaseRequestManager;
var purchaseRequest;
var purchaseOrderFromDataUtil;
var purchaseOrderId;
var purchaseOrder;

before('#00. connect db & create instance', function (done) {
    helper.getDb()
        .then(db => {
            purchaseRequestManager = new PurchaseRequestManager(db, {
                username: 'dev'
            });
            purchaseOrderManager = new PurchaseOrderManager(db, {
                username: 'dev'
            });

            done();
        })
        .catch(e => {
            done(e);
        });
});

it('#01. Create Purchase Request', function (done) {
    purchaseRequestDataUtil.getNewTestData()
        .then(data => {
            purchaseRequest = data;

            done();
        })
        .catch(e => {
            done(e);
        });
});

it('#02. should failed when create new purchase-order with unposted purchase-request', function (done) {
    purchaseOrderDataUtil.getNewData(purchaseRequest)
        .then((purchaseOrder) => {
            return purchaseOrderManager.create(purchaseOrder);
        })
        .then(po => {
            done(purchaseRequest, "purchase-request cannot be used to create purchase-order due unposted status");
        })
        .catch(e => {
            e.errors.should.have.property('purchaseRequestId');
            done();
        });
});

it('#03. should success when get new purchase-order data from util with posted purchase-request', function (done) {
    purchaseRequestManager.post([purchaseRequest])
        .then(pr => {
            purchaseRequest = pr[0];
            purchaseOrderDataUtil.getNewData(purchaseRequest)
                .then((data) => {
                    purchaseOrderFromDataUtil = data;
                    done();
                })
                .catch(e => {
                    done(e);
                });

        })
        .catch(e => {
            done(e);
        });
});

it('#04. should success when create new purchase-order with posted purchase-request', function (done) {
    purchaseOrderManager.create(purchaseOrderFromDataUtil)
        .then(id => {
            purchaseOrderId = id;
            done();
        })
        .catch(e => {
            done(e);
        });
});

it('#05. should success when validate purchase-order with posted purchase-request', function (done) {
    purchaseOrderManager.getSingleById(purchaseOrderId)
    .then(data => {
        purchaseOrder = data;
        done();
    })
    .catch(e => {
        done(e);
    });
});<commit_msg>update new test<commit_after>'esversion:6';

var should = require("should");
var helper = require("../../../helper");

var purchaseRequestDataUtil = require("../../../data-util/purchasing/purchase-request-data-util");
var validatePR = require("bateeq-models").validator.purchasing.purchaseRequest;
var PurchaseRequestManager = require("../../../../src/managers/purchasing/purchase-request-manager");
var purchaseRequestManager = null;
var purchaseRequest;

var purchaseOrderDataUtil = require("../../../data-util/purchasing/purchase-order-data-util");
var validatePO = require("bateeq-models").validator.purchasing.purchaseOrder;
var PurchaseOrderManager = require("../../../../src/managers/purchasing/purchase-order-manager");
var purchaseOrderManager = null;
var purchaseOrder;

before('#00. connect db', function (done) {
    helper.getDb()
        .then(db => {
            purchaseRequestManager = new PurchaseRequestManager(db, {
                username: 'dev'
            });
            purchaseOrderManager = new PurchaseOrderManager(db, {
                username: 'dev'
            });
            done();
        })
        .catch(e => {
            done(e);
        });
});

it('#01. should success when create new purchase-order from data util', function (done) {
    purchaseRequestDataUtil.getNewTestData()
        .then(pr => {
            purchaseRequest = pr;
            validatePR(purchaseRequest);
            done();
        })
        .catch(e => {
            done(e);
        });
});

it('#02. should failed when create new purchase-order with unposted purchase-request', function (done) {
    purchaseOrderDataUtil.getNewData(purchaseRequest)
        .then((purchaseOrder) => {
            return purchaseOrderManager.create(purchaseOrder);
        })
        .then(po => {
            done(purchaseRequest, "purchase-request cannot be used to create purchase-order due unposted status");
        })
        .catch(e => {
            e.errors.should.have.property('purchaseRequestId');
            done();
        });
});

it('#02. should success when create new purchase-order with posted purchase-request', function (done) {
    purchaseRequestManager.post([purchaseRequest])
        .then(pr => {
            purchaseRequest = pr[0];
            purchaseOrderDataUtil.getNewData(purchaseRequest)
                .then((purchaseOrder) => {
                    return purchaseOrderManager.create(purchaseOrder);
                })
                .then((id) => {
                    return purchaseOrderManager.getSingleById(id);
                })
                .then(po => {
                    purchaseOrder = po;
                    done();
                })
                .catch(e => {
                    done(e);
                });

        })
        .catch(e => {
            done(e);
        });
});<|endoftext|>


<commit_before>function initialize(io, ioClient, globals){
	var kerberos = ioClient.connect(globals.Kerberos, {reconnect: true});

	io.sockets.on('connection', function(socket){

		console.log('-' + socket.id);

		/// Welcome to the new client
		socket.emit('Welcome', {SocketId : socket.id});

		/*
		================
		Local functions
		*/

		/// Emit all cranes
		function sendHydraMessage(){
			socket.emit('Clapp.Hydra.Message', {Command : 'HydraCommand', Values : 1});
		}

		/*
		================
		Socket Intervals
		*/
		/// Emit every 5 seconds cranes
		setInterval(sendHydraMessage, 5000);

		/*
		================
		Templates for Socket.io
		*/
		/// Template for socket event
		//socket.on('', function(data){
		//  io.sockets.emit('Name', data);
		// socket.emit('ID', {Command: 'CommandID', Values:[{ID: socket.id}]});
		//});

	});

	console.log('Socket.io initialized');
}

exports.initialize = initialize;<commit_msg>Handled error<commit_after>function initialize(io, ioClient, globals){
	var kerberos = null;

	if(globals.Kerberos != undefined && globals.Kerberos.length > 0)
		kerberos = ioClient.connect(globals.Kerberos, {reconnect: true});

	io.sockets.on('connection', function(socket){

		console.log('-' + socket.id);

		/// Welcome to the new client
		socket.emit('Welcome', {SocketId : socket.id});

		/*
		================
		Local functions
		*/

		/// Emit all cranes
		function sendHydraMessage(){
			socket.emit('Clapp.Hydra.Message', {Command : 'HydraCommand', Values : 1});
		}

		/*
		================
		Socket Intervals
		*/
		/// Emit every 5 seconds cranes
		setInterval(sendHydraMessage, 5000);

		/*
		================
		Templates for Socket.io
		*/
		/// Template for socket event
		//socket.on('', function(data){
		//  io.sockets.emit('Name', data);
		// socket.emit('ID', {Command: 'CommandID', Values:[{ID: socket.id}]});
		//});

	});

	console.log('Socket.io initialized');
}

exports.initialize = initialize;<|endoftext|>


<commit_before>import Bot from 'node-telegram-bot';
import * as _ from 'lodash';
import {telegram, ifttt} from '../../configs';
import {ifttt as iftttTrigger} from '../../utils/triggers';

export default () => {
  const goodGirl = /Good.*girl/g;

  const bot = new Bot({
    token: telegram.token
  });

  /**
   * Gets command and trigger signal to switch heater on/off.
   *
   * @param {String} command - User command.
   * @param {Object} msg - Telegram message object.
   */
  const handleSwitch = (command, msg) => {
    const id = msg.chat.id;
    const firstName = msg.from.first_name;
    const authorized = _.includes(telegram.users, msg.from.username);
    const message = authorized ? `Got it, ${firstName}! Hacking into the heater.`
                               : 'Hold on Canary, this is above your pay rate.';

    if (authorized) {
      iftttTrigger(ifttt.events[command], ifttt.key);
    }

    bot.sendMessage({
      chat_id: id,
      text: message
    });
  };

  // Start capturing commands.
  bot.on('message', (msg) => {
    const commandText = _
        .chain(msg.text)
        .split('@', 1)
        .snakeCase()
        .value();

    const validCommand = _.includes(telegram.commands, commandText);

    if (validCommand) {
      handleSwitch(commandText, msg);
    }
  });

  bot.onText(goodGirl, (msg) => {
    const id = msg.chat.id;

    bot.sendMessage({
      chat_id: id,
      text: 'Good girl! \xF0\x9F\x99\x86'
    });
  });

  bot.enableAnalytics(telegram.botan);
  bot.start();

  console.log('Felicity is alive!');
};
<commit_msg>Fixing good girl behavior<commit_after>import Bot from 'node-telegram-bot';
import * as _ from 'lodash';
import {telegram, ifttt} from '../../configs';
import {ifttt as iftttTrigger} from '../../utils/triggers';

export default () => {
  const bot = new Bot({
    token: telegram.token
  });

  /**
   * Gets command and trigger signal to switch heater on/off.
   *
   * @param {String} command - User command.
   * @param {Object} msg - Telegram message object.
   */
  const handleSwitch = (command, msg) => {
    const id = msg.chat.id;
    const firstName = msg.from.first_name;
    const authorized = _.includes(telegram.users, msg.from.username);
    const message = authorized ? `Got it, ${firstName}! Hacking into the heater.`
                               : 'Hold on Canary, this is above your pay rate.';

    if (authorized) {
      iftttTrigger(ifttt.events[command], ifttt.key);
    }

    bot.sendMessage({
      chat_id: id,
      text: message
    });
  };

  /**
   * Handle other messages, for miscellaneous behavior.
   *
   * @param {Object} msg - Message object.
   */
  const handleOtherMessages = (msg) => {
    const goodGirl = /Good.*girl/g;

    if (goodGirl.test(msg.text)) {
      const id = msg.chat.id;

      bot.sendMessage({
        chat_id: id,
        text: 'Good girl! \xF0\x9F\x99\x86'
      });
    }
  };

  // Start capturing commands.
  bot.on('message', (msg) => {
    const commandText = _
        .chain(msg.text)
        .split('@', 1)
        .snakeCase()
        .value();

    const validCommand = _.includes(telegram.commands, commandText);

    if (validCommand) {
      handleSwitch(commandText, msg);
    } else {
      handleOtherMessages(msg);
    }
  });

  bot.enableAnalytics(telegram.botan);
  bot.start();

  console.log('Felicity is alive!');
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

var path = require("path");
var url = require("url");
var fs = require("fs");

// Local version replaces global one
try {
	var localWebpackDevServer = require.resolve(path.join(process.cwd(), "node_modules", "webpack-dev-server", "bin", "webpack-dev-server.js"));
	if(__filename !== localWebpackDevServer) {
		return require(localWebpackDevServer);
	}
} catch(e) {}

var Server = require("../lib/Server");
var webpack = require("webpack");

var optimist = require("optimist")

	.usage("webpack-dev-server " + require("../package.json").version + "\n" +
			"Usage: http://webpack.github.io/docs/webpack-dev-server.html")

	.boolean("lazy").describe("lazy")

	.boolean("info").describe("info").default("info", true)

	.boolean("quiet").describe("quiet")

	.boolean("inline").describe("inline", "Inline the webpack-dev-server logic into the bundle.")

	.boolean("https").describe("https")

	.string("key").describe("key", "Path to a SSL key.")

	.string("cert").describe("cert", "Path to a SSL certificate.")

	.string("cacert").describe("cacert", "Path to a SSL CA certificate.")

	.string("content-base").describe("content-base", "A directory or URL to serve HTML content from.")

	.string("content-base-target").describe("content-base-target", "Proxy requests to this target.")

	.boolean("history-api-fallback").describe("history-api-fallback", "Fallback to /index.html for Single Page Applications.")

	.describe("port", "The port").default("port", 8080)

	.describe("host", "The hostname/ip address the server will bind to").default("host", "localhost");

require("webpack/bin/config-optimist")(optimist);

var argv = optimist.argv;

var wpOpt = require("webpack/bin/convert-argv")(optimist, argv, { outputFilename: "/bundle.js" });
var firstWpOpt = Array.isArray(wpOpt) ? wpOpt[0] : wpOpt;

var options = wpOpt.devServer || firstWpOpt.devServer || {};

if(argv.host !== "localhost" || !options.host)
	options.host = argv.host;

if(argv.port !== 8080 || !options.port)
	options.port = argv.port;

if(!options.publicPath) {
	options.publicPath = firstWpOpt.output && firstWpOpt.output.publicPath || "";
	if(!/^(https?:)?\/\//.test(options.publicPath) && options.publicPath[0] !== "/")
		options.publicPath = "/" + options.publicPath;
}

if(!options.outputPath)
	options.outputPath = "/";
if(!options.filename)
	options.filename = firstWpOpt.output && firstWpOpt.output.filename;
[].concat(wpOpt).forEach(function(wpOpt) {
	wpOpt.output.path = "/";
});
if(!options.watchOptions)
	options.watchOptions = firstWpOpt.watchOptions;
if(!options.watchDelay && !options.watchOptions) // TODO remove in next major version
	options.watchDelay = firstWpOpt.watchDelay;
if(!options.hot)
	options.hot = argv["hot"];

if(argv["content-base"]) {
	options.contentBase = argv["content-base"];
	if(/^[0-9]$/.test(options.contentBase))
		options.contentBase = +options.contentBase;
	else if(!/^(https?:)?\/\//.test(options.contentBase))
		options.contentBase = path.resolve(options.contentBase);
} else if(argv["content-base-target"]) {
	options.contentBase = { target: argv["content-base-target"] };
} else if(!options.contentBase) {
	options.contentBase = process.cwd();
}
if(!options.stats) {
	options.stats = {
		cached: false,
		cachedAssets: false
	};
}

options.stats.colors = require("supports-color");

if(argv["lazy"])
	options.lazy = true;

if(!argv["info"])
	options.noInfo = true;

if(argv["quiet"])
	options.quiet = true;

if(argv["https"])
	options.https = true;

if(argv["cert"])
	options.cert = fs.readFileSync(path.resolve(argv["cert"]));

if(argv["key"])
	options.key = fs.readFileSync(path.resolve(argv["key"]));

if(argv["cacert"])
	options.cacert = fs.readFileSync(path.resolve(argv["cacert"]));

if(argv["inline"])
	options.inline = true;

if(argv["history-api-fallback"])
	options.historyApiFallback = true;

var protocol = options.https ? "https" : "http";

if(options.inline) {
	var devClient = [require.resolve("../client/") + "?" + protocol + "://" + options.host + ":" + options.port];

	if(options.hot)
		devClient.push("webpack/hot/dev-server");
	[].concat(wpOpt).forEach(function(wpOpt) {
		if(typeof wpOpt.entry === "object" && !Array.isArray(wpOpt.entry)) {
			Object.keys(wpOpt.entry).forEach(function(key) {
				wpOpt.entry[key] = devClient.concat(wpOpt.entry[key]);
			});
		} else {
			wpOpt.entry = devClient.concat(wpOpt.entry);
		}
	});
}

new Server(webpack(wpOpt), options).listen(options.port, options.host, function(err) {
	if(err) throw err;
	if(options.inline)
		console.log(protocol + "://" + options.host + ":" + options.port + "/");
	else
		console.log(protocol + "://" + options.host + ":" + options.port + "/webpack-dev-server/");
	console.log("webpack result is served from " + options.publicPath);
	if(typeof options.contentBase === "object")
		console.log("requests are proxied to " + options.contentBase.target);
	else
		console.log("content is served from " + options.contentBase);
	if(options.historyApiFallback)
		console.log("404s will fallback to /index.html");
});
<commit_msg>Correct console message when historyApiFallback is used with an `index` option.<commit_after>#!/usr/bin/env node

var path = require("path");
var url = require("url");
var fs = require("fs");

// Local version replaces global one
try {
	var localWebpackDevServer = require.resolve(path.join(process.cwd(), "node_modules", "webpack-dev-server", "bin", "webpack-dev-server.js"));
	if(__filename !== localWebpackDevServer) {
		return require(localWebpackDevServer);
	}
} catch(e) {}

var Server = require("../lib/Server");
var webpack = require("webpack");

var optimist = require("optimist")

	.usage("webpack-dev-server " + require("../package.json").version + "\n" +
			"Usage: http://webpack.github.io/docs/webpack-dev-server.html")

	.boolean("lazy").describe("lazy")

	.boolean("info").describe("info").default("info", true)

	.boolean("quiet").describe("quiet")

	.boolean("inline").describe("inline", "Inline the webpack-dev-server logic into the bundle.")

	.boolean("https").describe("https")

	.string("key").describe("key", "Path to a SSL key.")

	.string("cert").describe("cert", "Path to a SSL certificate.")

	.string("cacert").describe("cacert", "Path to a SSL CA certificate.")

	.string("content-base").describe("content-base", "A directory or URL to serve HTML content from.")

	.string("content-base-target").describe("content-base-target", "Proxy requests to this target.")

	.boolean("history-api-fallback").describe("history-api-fallback", "Fallback to /index.html for Single Page Applications.")

	.describe("port", "The port").default("port", 8080)

	.describe("host", "The hostname/ip address the server will bind to").default("host", "localhost");

require("webpack/bin/config-optimist")(optimist);

var argv = optimist.argv;

var wpOpt = require("webpack/bin/convert-argv")(optimist, argv, { outputFilename: "/bundle.js" });
var firstWpOpt = Array.isArray(wpOpt) ? wpOpt[0] : wpOpt;

var options = wpOpt.devServer || firstWpOpt.devServer || {};

if(argv.host !== "localhost" || !options.host)
	options.host = argv.host;

if(argv.port !== 8080 || !options.port)
	options.port = argv.port;

if(!options.publicPath) {
	options.publicPath = firstWpOpt.output && firstWpOpt.output.publicPath || "";
	if(!/^(https?:)?\/\//.test(options.publicPath) && options.publicPath[0] !== "/")
		options.publicPath = "/" + options.publicPath;
}

if(!options.outputPath)
	options.outputPath = "/";
if(!options.filename)
	options.filename = firstWpOpt.output && firstWpOpt.output.filename;
[].concat(wpOpt).forEach(function(wpOpt) {
	wpOpt.output.path = "/";
});
if(!options.watchOptions)
	options.watchOptions = firstWpOpt.watchOptions;
if(!options.watchDelay && !options.watchOptions) // TODO remove in next major version
	options.watchDelay = firstWpOpt.watchDelay;
if(!options.hot)
	options.hot = argv["hot"];

if(argv["content-base"]) {
	options.contentBase = argv["content-base"];
	if(/^[0-9]$/.test(options.contentBase))
		options.contentBase = +options.contentBase;
	else if(!/^(https?:)?\/\//.test(options.contentBase))
		options.contentBase = path.resolve(options.contentBase);
} else if(argv["content-base-target"]) {
	options.contentBase = { target: argv["content-base-target"] };
} else if(!options.contentBase) {
	options.contentBase = process.cwd();
}
if(!options.stats) {
	options.stats = {
		cached: false,
		cachedAssets: false
	};
}

options.stats.colors = require("supports-color");

if(argv["lazy"])
	options.lazy = true;

if(!argv["info"])
	options.noInfo = true;

if(argv["quiet"])
	options.quiet = true;

if(argv["https"])
	options.https = true;

if(argv["cert"])
	options.cert = fs.readFileSync(path.resolve(argv["cert"]));

if(argv["key"])
	options.key = fs.readFileSync(path.resolve(argv["key"]));

if(argv["cacert"])
	options.cacert = fs.readFileSync(path.resolve(argv["cacert"]));

if(argv["inline"])
	options.inline = true;

if(argv["history-api-fallback"])
	options.historyApiFallback = true;

var protocol = options.https ? "https" : "http";

if(options.inline) {
	var devClient = [require.resolve("../client/") + "?" + protocol + "://" + options.host + ":" + options.port];

	if(options.hot)
		devClient.push("webpack/hot/dev-server");
	[].concat(wpOpt).forEach(function(wpOpt) {
		if(typeof wpOpt.entry === "object" && !Array.isArray(wpOpt.entry)) {
			Object.keys(wpOpt.entry).forEach(function(key) {
				wpOpt.entry[key] = devClient.concat(wpOpt.entry[key]);
			});
		} else {
			wpOpt.entry = devClient.concat(wpOpt.entry);
		}
	});
}

new Server(webpack(wpOpt), options).listen(options.port, options.host, function(err) {
	if(err) throw err;
	if(options.inline)
		console.log(protocol + "://" + options.host + ":" + options.port + "/");
	else
		console.log(protocol + "://" + options.host + ":" + options.port + "/webpack-dev-server/");
	console.log("webpack result is served from " + options.publicPath);
	if(typeof options.contentBase === "object")
		console.log("requests are proxied to " + options.contentBase.target);
	else
		console.log("content is served from " + options.contentBase);
	if(options.historyApiFallback)
		console.log("404s will fallback to %s", options.historyApiFallback.index || "/index.html");
});
<|endoftext|>


<commit_before>/*! LAB.js (LABjs :: Loading And Blocking JavaScript)
    v1.0.4 (c) Kyle Simpson
    + Refactoring for Jasy (c) Sebastian Werner
    MIT License
*/

(function(global)
{
  // Ah-ha hush that fuss, feature inference is used to detect specific browsers
  // because the techniques used in LABjs have no known feature detection. If
  // you know of a feature test please contact me ASAP. Feature inference is used
  // instead of user agent sniffing because the UA string can be easily
  // spoofed and is not adequate for such a mission critical part of the code.
  var isOpera = global.opera && Object.prototype.toString.call(global.opera) == "[object Opera]";
  var isGecko = ("MozAppearance" in document.documentElement.style);

  // the following is a feature sniff for the ability to set async=false on dynamically created script elements, as proposed to the W3C
  // RE: http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
  var supportsScriptAsync = (document.createElement("script").async === true);

  // For memory leak protection
  var emptyFunction = new Function;

  //
  var append_to = {};
  var all_scripts = {};

  append_to["head"] = document.head || document.getElementsByTagName("head");
  append_to["body"] = document.getElementsByTagName("body");

  function isFunc(func) {
    return Object.prototype.toString.call(func) === "[object Function]";
  }

  // these ROOTs do not support file:/// usage, only http:// type usage
  var PAGEROOT = /^[^?#]*\//.exec(location.href)[0];

  // optional third / in the protocol portion of this regex so that LABjs doesn't blow up when used in file:/// usage
  var DOCROOT = /^\w+\:\/\/\/?[^\/]+/.exec(PAGEROOT)[0];

  function canonicalScriptURI(src)
  {
    var regex = /^\w+\:\/\//, ret;
    if (typeof src != "string") src = "";
    ret = (regex.test(src) ? "" : "") + src;
    return ((regex.test(ret) ? "" : (ret.charAt(0) === "/" ? DOCROOT : PAGEROOT)) + ret);
  }

  function sameDomain(src) {
    return (canonicalScriptURI(src).indexOf(DOCROOT) === 0);
  }

  var docScripts = document.getElementsByTagName("script");

  function scriptTagExists(uri)
  {
    // checks if a script uri has ever been loaded into this page's DOM
    var script, idx=-1;
    while (script = docScripts[++idx]) {
      if (typeof script.src == "string" && uri === canonicalScriptURI(script.src) && script.type !== "script/cache") return true;
    }
    return false;
  }

  function engine()
  {
    var opts =
    {
      // browsers like IE/Safari/Chrome can use the "cache" trick to preload
      cache : !(isGecko||isOpera),

      // FF(prior to FF4) & Opera preserve execution order with script tags automatically,
      // so just add all scripts as fast as possible. FF4 has async=false to do the same
      order : isGecko || isOpera || supportsScriptAsync,

      // which DOM object ("head" or "body") to append scripts to
      which : "head",

      // use various tricks for "preloading" scripts
      preload : true
    };

    var ready = false;
    var _which = opts.which;

    var waitFunc = emptyFunction;
    var scripts_loading = false;
    var first_pass = true;
    var scripts = {};
    var exec = [];
    var end_of_chain_check_interval = null;

    function isScriptLoaded(elem, scriptentry)
    {
      if ((elem.readyState && elem.readyState!=="complete" && elem.readyState!=="loaded") || scriptentry["done"]) { return false; }
      elem["onload"] = elem["onreadystatechange"] = null; // prevent memory leak
      return true;
    }

    function handleScriptLoad(elem, scriptentry, skipReadyCheck)
    {
      skipReadyCheck = !(!skipReadyCheck); // used to override ready check when script text was injected from XHR preload
      if (!skipReadyCheck && !(isScriptLoaded(elem,scriptentry))) return;
      scriptentry["done"] = true;

      for (var key in scripts) {
        if (scripts["hasOwnProperty"](key) && !(scripts[key]["done"])) return;
      }
      ready = true;
      waitFunc();
    }

    function loadTriggerExecute(scriptentry)
    {
      if (Object.prototype.toString.call(scriptentry.loadtrigger) === "[object Function]")
      {
        scriptentry["loadtrigger"]();
        scriptentry["loadtrigger"] = null; // prevent memory leak
      }
    }

    function handleScriptPreload(elem, scriptentry)
    {
      if (!isScriptLoaded(elem,scriptentry)) return;
      scriptentry["preloaddone"] = true;
      setTimeout(function(){
        append_to[scriptentry["which"]].removeChild(elem); // remove preload script node
        loadTriggerExecute(scriptentry);
      },0);
    }

    function handleXHRPreload(xhr, scriptentry)
    {
      if (xhr.readyState === 4) {
        xhr["onreadystatechange"] = emptyFunction; // fix a memory leak in IE
        scriptentry["preloaddone"] = true;
        setTimeout(function(){ loadTriggerExecute(scriptentry); },0);
      }
    }

    function createScriptTag(scriptentry, src, type, charset, onload, scriptText)
    {
      var _script_which = scriptentry["which"];

      // this setTimeout waiting "hack" prevents a nasty race condition browser hang (IE) when the document.write("<script defer=true>") type dom-ready hack is present in the page
      setTimeout(function()
      {
        if ("item" in append_to[_script_which]) { // check if ref is still a live node list
          if (!append_to[_script_which][0]) { // append_to node not yet ready
            setTimeout(arguments.callee,25); // try again in a little bit -- note, will recall the anonymous function in the outer setTimeout, not the parent createScriptTag()
            return;
          }
          append_to[_script_which] = append_to[_script_which][0]; // reassign from live node list ref to pure node ref -- avoids nasty IE bug where changes to DOM invalidate live node lists
        }
        var scriptElem = document.createElement("script");
        if (typeof type == "string") scriptElem.type = type;
        if (typeof charset == "string") scriptElem.charset = charset;

        // load script via 'src' attribute, set onload/onreadystatechange listeners
        if (Object.prototype.toString.call(onload) === "[object Function]")
        {
          scriptElem["onload"] = scriptElem["onreadystatechange"] = function(){
            onload(scriptElem,scriptentry);
          };

          scriptElem.src = src;

          if (supportsScriptAsync) {
            scriptElem.async = false;
          }
        }

        // only for appending to <head>, fix a bug in IE6 if <base> tag is present -- otherwise, insertBefore(...,null) acts just like appendChild()
        append_to[_script_which].insertBefore(scriptElem,(_script_which==="head"?append_to[_script_which].firstChild:null));

        // script text already avaiable from XHR preload, so just inject it
        if (typeof scriptText == "string")
        {
          scriptElem.text = scriptText;

          // manually call 'load' callback function, skipReadyCheck=true
          handleScriptLoad(scriptElem,scriptentry,true);
        }
      },0);
    }

    function loadScriptElem(scriptentry, src, type, charset) {
      all_scripts[scriptentry["srcuri"]] = true;
      createScriptTag(scriptentry,src,type,charset,handleScriptLoad);
    }

    function loadScriptCache(scriptentry, src, type, charset)
    {
      var args = arguments;
      if (first_pass && scriptentry["preloaddone"] == null) { // need to preload into cache
        scriptentry["preloaddone"] = false;
        createScriptTag(scriptentry,src,"script/cache",charset,handleScriptPreload); // fake mimetype causes a fetch into cache, but no execution
      }
      else if (!first_pass && scriptentry["preloaddone"] != null && !scriptentry["preloaddone"]) { // preload still in progress, make sure trigger is set for execution later
        scriptentry["loadtrigger"] = function(){loadScriptCache.apply(null,args);};
      }
      else if (!first_pass) { // preload done, so reload (from cache, hopefully!) as regular script element
        loadScriptElem.apply(null,args);
      }
    }

    function loadScriptXHR(scriptentry, src, type, charset)
    {
      var args = arguments, xhr;
      if (first_pass && scriptentry["preloaddone"] == null) { // need to preload
        scriptentry["preloaddone"] = false;
        xhr = scriptentry.xhr = (ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new global.XMLHttpRequest());
        xhr["onreadystatechange"] = function(){handleXHRPreload(xhr,scriptentry);};
        xhr.open("GET",src);
        xhr.send("");
      }
      else if (!first_pass && scriptentry["preloaddone"] != null && !scriptentry["preloaddone"]) {  // preload XHR still in progress, make sure trigger is set for execution later
        scriptentry["loadtrigger"] = function(){loadScriptXHR.apply(null,args);};
      }
      else if (!first_pass) { // preload done, so "execute" script via injection
        all_scripts[scriptentry["srcuri"]] = true;
        createScriptTag(scriptentry,src,type,charset,null,scriptentry.xhr.responseText);
        scriptentry.xhr = null;
      }
    }

    function loadScript(o)
    {

      var src = o.src, type = o.type, charset = o.charset,
        src_uri = canonicalScriptURI(src), scriptentry, same_domain = sameDomain(src_uri);
      if (typeof charset != "string") charset = null;

      if ((all_scripts[src_uri] != null) || (first_pass && scripts[src_uri]) || scriptTagExists(src_uri))
      {
        if (scripts[src_uri] != null && scripts[src_uri]["preloaddone"] && !scripts[src_uri]["done"] && same_domain) {
          // this script was preloaded via XHR, but is a duplicate, and dupes are not allowed
          handleScriptLoad(null,scripts[src_uri],true); // mark the entry as done and check if chain group is done
        }
        return;
      }
      if (scripts[src_uri] == null) scripts[src_uri] = {};
      scriptentry = scripts[src_uri];
      if (scriptentry["which"] == null) scriptentry["which"] = _which;
      scriptentry["done"] = false;
      scriptentry["srcuri"] = src_uri;
      scripts_loading = true;

      if (!opts.order && same_domain) loadScriptXHR(scriptentry,src_uri,type,charset);
      else if (!opts.order && opts.cache) loadScriptCache(scriptentry,src_uri,type,charset);
      else loadScriptElem(scriptentry,src_uri,type,charset);
    }

    function onlyQueue(execBody) {
      exec.push(execBody);
    }

    // helper for publicAPI functions below
    function queueAndExecute(execBody)
    {
      if (queueExec && !opts.order) onlyQueue(execBody);
      execBody();
    }

    function serializeArgs(args)
    {
      var sargs = [], idx;
      for (idx=-1; ++idx<args.length;) {
        if (Object.prototype.toString.call(args[idx]) === "[object Array]") sargs = sargs.concat(serializeArgs(args[idx]));
        else sargs[sargs.length] = args[idx];
      }
      return sargs;
    }

    var publicAPI =
    {
      script : function()
      {
        clearTimeout(end_of_chain_check_interval);
        var args = serializeArgs(arguments), use_engine = publicAPI, idx;

        queueAndExecute(function(){
          for (idx=-1; ++idx<args.length;) {
            loadScript((typeof args[idx] == "string") ? {src:args[idx]} : args[idx]);
          }
        });

        // hack to "detect" the end of the chain if a wait() is not the last call
        end_of_chain_check_interval = setTimeout(function()
        {
          first_pass = false;
        }, 5);
        return use_engine;
      },

      wait : function(func)
      {
        clearTimeout(end_of_chain_check_interval);
        first_pass = false;

        if (Object.prototype.toString.call(func) !== "[object Function]") {
          func = emptyFunction;
        }

        // On this current chain's waitFunc function, tack on call to trigger the queue for the *next* engine
        // in the chain, which will be executed when the current chain finishes loading
        var e = engine(true),  // 'true' tells the engine to be in queueing mode
          triggerNextChain = e.trigger, // store ref to e's trigger function for use by 'wfunc'
          wfunc = function(){ try { func(); } catch(err) {} triggerNextChain(); };
        delete e.trigger; // remove the 'trigger' property from e's public API, since only used internally
        var fn = function(){
          if (scripts_loading && !ready) waitFunc = wfunc;
          else wfunc();
        };

        if (queueExec && !scripts_loading) onlyQueue(fn);
        else queueAndExecute(fn);
        return e;
      }
    };

    if (queueExec)
    {
      // if queueing, return a function that the previous chain's waitFunc function can use to trigger this
      // engine's queue. NOTE: this trigger function is captured and removed from the public chain API before return
      publicAPI.trigger = function() {
        var fn, idx=-1;
        while (fn = exec[++idx]) fn();
        exec = [];
      };
    }

    return publicAPI;
  }

  // Export public methods
  global.LAB =
  {
    // will load one or more scripts
    script:function() {
      return engine().script.apply(null,arguments);
    },

    // will ensure that the chain's previous scripts are executed before execution of scripts in subsequent chain links
    wait:function() {
      return engine().wait.apply(null,arguments);
    }
  };

  /* The following "hack" was suggested by Andrea Giammarchi and adapted from: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html
     NOTE: this hack only operates in FF and then only in versions where document.readyState is not present (FF < 3.6?).

     The hack essentially "patches" the **page** that LABjs is loaded onto so that it has a proper conforming document.readyState, so that if a script which does
     proper and safe dom-ready detection is loaded onto a page, after dom-ready has passed, it will still be able to detect this state, by inspecting the now hacked
     document.readyState property. The loaded script in question can then immediately trigger any queued code executions that were waiting for the DOM to be ready.
     For instance, jQuery 1.4+ has been patched to take advantage of document.readyState, which is enabled by this hack. But 1.3.2 and before are **not** safe or
     fixed by this hack, and should therefore **not** be lazy-loaded by script loader tools such as LABjs.
  */
  if (document.readyState == null && document.addEventListener)
  {
    document.readyState = "loading";

    var handler = function()
    {
      document.removeEventListener("DOMContentLoaded", handler, false);
      document.readyState = "complete";
    };

    document.addEventListener("DOMContentLoaded", handler, false);
  }
})(window);<commit_msg>Removed LABJS copy. Switched to own implementation.<commit_after><|endoftext|>