<commit_before>/*!
 * OS.js - JavaScript Cloud/Web Desktop Platform
 *
 * Copyright (c) 2011-2016, Anders Evenrud <andersevenrud@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @author  Anders Evenrud <andersevenrud@gmail.com>
 * @licence Simplified BSD License
 */
(function() {
  'use strict';

  /////////////////////////////////////////////////////////////////////////////
  // DOM
  /////////////////////////////////////////////////////////////////////////////

  /**
   * Get element by ID
   *
   * @function $
   * @memberof OSjs.Utils
   *
   * @param   {String}    id      DOM Element ID
   *
   * @return  {Node}        Found element or null
   */
  OSjs.Utils.$ = function(id) {
    return document.getElementById(id);
  };

  /**
   * Remove unwanted characters from ID or className
   *
   * @function $safeName
   * @memberof OSjs.Utils
   *
   * @param   {String}    str     The name
   *
   * @return  {String}            The new name
   */
  OSjs.Utils.$safeName = function(str) {
    return (str || '').replace(/[^a-zA-Z0-9]/g, '_');
  };

  /**
   * Remove given element from parent
   *
   * @function $remove
   * @memberof OSjs.Utils
   *
   * @param   {Node}    node      The DOM Element
   */
  OSjs.Utils.$remove = function(node) {
    if ( node && node.parentNode ) {
      node.parentNode.removeChild(node);
    }
    return null;
  };

  /**
   * Empty this element (remove children)
   *
   * @function $empty
   * @memberof OSjs.Utils
   *
   * @param   {Node}    myNode      The DOM Element
   */
  OSjs.Utils.$empty = function(myNode) {
    if ( myNode ) {
      while (myNode.firstChild) {
        myNode.removeChild(myNode.firstChild);
      }
    }
  };

  /**
   * Get CSS style attribute
   *
   * @function $getStyle
   * @memberof OSjs.Utils
   *
   * @param   {Node}          oElm          The DOM Element
   * @param   {String}        strCssRule    The CSS rule to get
   *
   * @return  {String}                      Style attribute
   */
  OSjs.Utils.$getStyle = function(oElm, strCssRule) {
    var strValue = '';
    if ( document.defaultView && document.defaultView.getComputedStyle ) {
      strValue = document.defaultView.getComputedStyle(oElm, '').getPropertyValue(strCssRule);
    } else if ( oElm.currentStyle ) {
      strCssRule = strCssRule.replace(/\-(\w)/g, function(strMatch, p1) {
        return p1.toUpperCase();
      });
      strValue = oElm.currentStyle[strCssRule];
    }
    return strValue;
  };

  /**
   * Get element absolute position
   *
   * Modern browsers will return getBoundingClientRect()
   * See DOM documentation
   *
   * @function $position
   * @memberof OSjs.Utils
   *
   * @param   {Node}      el          The Element to find position of
   * @param   {Node}      [parentEl]  Parent to end loop in
   *
   * @return  {Object}                    The bounding box
   */
  OSjs.Utils.$position = function(el, parentEl) {
    if ( el ) {
      if ( parentEl ) {
        var result = {left:0, top:0, width: el.offsetWidth, height: el.offsetHeight};
        while ( true ) {
          result.left += el.offsetLeft;
          result.top  += el.offsetTop;
          if ( el.offsetParent ===  parentEl || el.offsetParent === null ) {
            break;
          }
          el = el.offsetParent;
        }
        return result;
      }
      return el.getBoundingClientRect();
    }
    return null;
  };

  /**
   * Traverses down to the parentnode validated by filter
   *
   * @function $parent
   * @memberof OSjs.Utils
   *
   * @param   {Node}            el        The Element to find position of
   * @param   {Function}        cb        The callback function => fn(node) return true/false here
   *
   * @return  {Node}            el        The DOM element
   */
  OSjs.Utils.$parent = function(el, cb) {
    var result = null;

    if ( el && cb ) {
      var current = el;
      while ( current.parentNode ) {
        if ( cb(current) ) {
          result = current;
          break;
        }
        current = current.parentNode;
      }
    }

    return result;
  };

  /**
   * Get the index of an element within a node
   *
   * @function $index
   * @memberof OSjs.Utils
   *
   * @param   {Node}      el          The Element to check
   * @param   {Node}      [parentEl]  Parent to end loop in
   *
   * @return  {Number}              The index
   */
  OSjs.Utils.$index = function(el, parentEl) {
    if ( el ) {
      parentEl = parentEl || el.parentNode;
      if ( parentEl ) {
        var nodeList = Array.prototype.slice.call(parentEl.children);
        var nodeIndex = nodeList.indexOf(el, parentEl);
        return nodeIndex;
      }
    }
    return -1;
  };

  /**
   * Selects range in a text field
   *
   * @function $selectRange
   * @memberof OSjs.Utils
   *
   * @param     {Node}      field     The DOM Element
   * @param     {Number}    start     Start position
   * @param     {Number}    end       End position
   */
  OSjs.Utils.$selectRange = function(field, start, end) {
    if ( !field ) {
      throw new Error('Cannot select range: missing element');
    }

    if ( typeof start === 'undefined' || typeof end === 'undefined' ) {
      throw new Error('Cannot select range: mising start/end');
    }

    if ( field.createTextRange ) {
      var selRange = field.createTextRange();
      selRange.collapse(true);
      selRange.moveStart('character', start);
      selRange.moveEnd('character', end);
      selRange.select();
      field.focus();
    } else if ( field.setSelectionRange ) {
      field.focus();
      field.setSelectionRange(start, end);
    } else if ( typeof field.selectionStart !== 'undefined' ) {
      field.selectionStart = start;
      field.selectionEnd = end;
      field.focus();
    }
  };

  /**
   * Add a className to a DOM Element
   *
   * @function $addClass
   * @memberof OSjs.Utils
   *
   * @param   {Node}      el      The dom Element
   * @param   {String}    name    The class name
   */
  OSjs.Utils.$addClass = function(el, name) {
    if ( el ) {
      name.split(' ').forEach(function(n) {
        el.classList.add(n);
      });
    }
  };

  /**
   * Remove a className from a DOM Element
   *
   * @function $removeClass
   * @memberof OSjs.Utils
   *
   * @param   {Node}      el      The dom Element
   * @param   {String}    name    The class name
   */
  OSjs.Utils.$removeClass = function(el, name) {
    if ( el ) {
      name.split(' ').forEach(function(n) {
        el.classList.remove(n);
      });
    }
  };

  /**
   * Check if a DOM Element has given className
   *
   * @function $hasClass
   * @memberof OSjs.Utils
   *
   * @param   {Node}      el      The dom Element
   * @param   {String}    name    The class name
   */
  OSjs.Utils.$hasClass = function(el, name) {
    if ( el && name ) {
      return name.split(' ').every(function(n) {
        return el.classList.contains(n);
      });
    }
    return false;
  };

  /**
   * Escapes the given string for HTML
   *
   * works sort of like PHPs htmlspecialchars()
   *
   * @function $escape
   * @memberof OSjs.Utils
   *
   * @param   {String}    str       Input
   *
   * @return  {String}              Escaped HTML
   */
  OSjs.Utils.$escape = function(str) {
    var div = document.createElement('div');
    div.appendChild(document.createTextNode(str));
    return div.innerHTML;
  };

  /**
   * Create a link stylesheet tag
   *
   * @function $createCSS
   * @memberof OSjs.Utils
   *
   * @param   {String}      src           The URL of resource
   * @param   {Function}    onload        onload callback
   * @param   {Function}    onerror       onerror callback
   *
   * @return  {Node}                The tag
   */
  OSjs.Utils.$createCSS = function(src, onload, onerror) {
    var link = document.createElement('link');
    link.setAttribute('rel', 'stylesheet');
    link.setAttribute('type', 'text/css');
    link.onload = onload || function() {};
    link.onerror = onerror || function() {};
    link.setAttribute('href', src);

    document.getElementsByTagName('head')[0].appendChild(link);

    return link;
  };

  /**
   * Create a script tag
   *
   * @function $createJS
   * @memberof OSjs.Utils
   *
   * @param   {String}      src                   The URL of resource
   * @param   {Function}    onreadystatechange    readystatechange callback
   * @param   {Function}    onload                onload callback
   * @param   {Function}    onerror               onerror callback
   * @param   {Object}      [attrs]               dict with optional arguments
   *
   * @return  {Node}                              The tag
   */
  OSjs.Utils.$createJS = function(src, onreadystatechange, onload, onerror, attrs) {
    var res = document.createElement('script');

    res.onreadystatechange = onreadystatechange || function() {};
    res.onerror = onerror || function() {};
    res.onload = onload || function() {};

    attrs = OSjs.Utils.mergeObject({
      type: 'text/javascript',
      charset: 'utf-9',
      src: src
    }, attrs || {});

    Object.keys(attrs).forEach(function(k) {
      res[k] = String(attrs[k]);
    });

    document.getElementsByTagName('head')[0].appendChild(res);

    return res;
  };

  /**
   * Check if event happened on a form element
   *
   * @function $isFormElement
   * @memberof OSjs.Utils
   *
   * @param   {Event}       ev      DOM Event
   * @param   {Array}       types   Array of types
   *
   * @return  {Boolean}             If is a form element
   */
  OSjs.Utils.$isFormElement = function(ev, types) {
    types = types || ['TEXTAREA', 'INPUT', 'SELECT'];

    var d = ev.srcElement || ev.target;
    if ( d ) {
      if ( types.indexOf(d.tagName.toUpperCase()) >= 0 ) {
        if ( !(d.readOnly || d.disabled) ) {
          return true;
        }
      }
    }
    return false;
  };

  /**
   * @function $isInput
   * @memberof OSjs.Utils
   * @alias OSjs.Utils.isFormElement
   * @deprecated Please use aliased method instead
   */
  OSjs.Utils.$isInput = function(ev) {
    console.warn('Utils::$isInput is deprecated', 'Use Utils::$isFormElement instead');
    return this.$isFormElement(ev);
  };

  /**
   * Set or Get element CSS
   *
   * @param {Node}                  el      DOM Node
   * @param {(String|Object)}       ink     CSS attribute name to get/set, or full dict to set
   * @param {(String|Number)}       [inv]   If previous argument was a string, this is the value that will be set
   *
   * @return {String} CSS attribute value
   *
   * @example
   * Utils.$css(element, {
   *  backgroundColor: '#000',
   *  'font-size': '14px' // You can also use CSS attributes like normal
   * });
   *
   * @example
   * Utils.$css(element, 'font-family', 'Arial');
   *
   * @example
   * Utils.$css(element, 'font-family'); // -> 'Arial'. Same as $getStyle
   *
   * @function $css
   * @memberof OSjs.Utils
   */
  OSjs.Utils.$css = function(el, ink, inv) {
    function rep(k) {
      return k.replace(/\-(\w)/g, function(strMatch, p1) {
        return p1.toUpperCase();
      });
    }

    var obj = {};
    if ( arguments.length === 2 ) {
      if ( typeof ink === 'string' ) {
        return el.parentNode ? OSjs.Utils.$getStyle(el, ink) : el.style[rep(ink)];
      }
      obj = ink;
    } else if ( arguments.length === 3 ) {
      obj[ink] = inv;
    }

    Object.keys(obj).forEach(function(k) {
      el.style[rep(k)] = String(obj[k]);
    });
  };

})();
<commit_msg>Utils: Fix typo<commit_after>/*!
 * OS.js - JavaScript Cloud/Web Desktop Platform
 *
 * Copyright (c) 2011-2016, Anders Evenrud <andersevenrud@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @author  Anders Evenrud <andersevenrud@gmail.com>
 * @licence Simplified BSD License
 */
(function() {
  'use strict';

  /////////////////////////////////////////////////////////////////////////////
  // DOM
  /////////////////////////////////////////////////////////////////////////////

  /**
   * Get element by ID
   *
   * @function $
   * @memberof OSjs.Utils
   *
   * @param   {String}    id      DOM Element ID
   *
   * @return  {Node}        Found element or null
   */
  OSjs.Utils.$ = function(id) {
    return document.getElementById(id);
  };

  /**
   * Remove unwanted characters from ID or className
   *
   * @function $safeName
   * @memberof OSjs.Utils
   *
   * @param   {String}    str     The name
   *
   * @return  {String}            The new name
   */
  OSjs.Utils.$safeName = function(str) {
    return (str || '').replace(/[^a-zA-Z0-9]/g, '_');
  };

  /**
   * Remove given element from parent
   *
   * @function $remove
   * @memberof OSjs.Utils
   *
   * @param   {Node}    node      The DOM Element
   */
  OSjs.Utils.$remove = function(node) {
    if ( node && node.parentNode ) {
      node.parentNode.removeChild(node);
    }
    return null;
  };

  /**
   * Empty this element (remove children)
   *
   * @function $empty
   * @memberof OSjs.Utils
   *
   * @param   {Node}    myNode      The DOM Element
   */
  OSjs.Utils.$empty = function(myNode) {
    if ( myNode ) {
      while (myNode.firstChild) {
        myNode.removeChild(myNode.firstChild);
      }
    }
  };

  /**
   * Get CSS style attribute
   *
   * @function $getStyle
   * @memberof OSjs.Utils
   *
   * @param   {Node}          oElm          The DOM Element
   * @param   {String}        strCssRule    The CSS rule to get
   *
   * @return  {String}                      Style attribute
   */
  OSjs.Utils.$getStyle = function(oElm, strCssRule) {
    var strValue = '';
    if ( document.defaultView && document.defaultView.getComputedStyle ) {
      strValue = document.defaultView.getComputedStyle(oElm, '').getPropertyValue(strCssRule);
    } else if ( oElm.currentStyle ) {
      strCssRule = strCssRule.replace(/\-(\w)/g, function(strMatch, p1) {
        return p1.toUpperCase();
      });
      strValue = oElm.currentStyle[strCssRule];
    }
    return strValue;
  };

  /**
   * Get element absolute position
   *
   * Modern browsers will return getBoundingClientRect()
   * See DOM documentation
   *
   * @function $position
   * @memberof OSjs.Utils
   *
   * @param   {Node}      el          The Element to find position of
   * @param   {Node}      [parentEl]  Parent to end loop in
   *
   * @return  {Object}                    The bounding box
   */
  OSjs.Utils.$position = function(el, parentEl) {
    if ( el ) {
      if ( parentEl ) {
        var result = {left:0, top:0, width: el.offsetWidth, height: el.offsetHeight};
        while ( true ) {
          result.left += el.offsetLeft;
          result.top  += el.offsetTop;
          if ( el.offsetParent ===  parentEl || el.offsetParent === null ) {
            break;
          }
          el = el.offsetParent;
        }
        return result;
      }
      return el.getBoundingClientRect();
    }
    return null;
  };

  /**
   * Traverses down to the parentnode validated by filter
   *
   * @function $parent
   * @memberof OSjs.Utils
   *
   * @param   {Node}            el        The Element to find position of
   * @param   {Function}        cb        The callback function => fn(node) return true/false here
   *
   * @return  {Node}            el        The DOM element
   */
  OSjs.Utils.$parent = function(el, cb) {
    var result = null;

    if ( el && cb ) {
      var current = el;
      while ( current.parentNode ) {
        if ( cb(current) ) {
          result = current;
          break;
        }
        current = current.parentNode;
      }
    }

    return result;
  };

  /**
   * Get the index of an element within a node
   *
   * @function $index
   * @memberof OSjs.Utils
   *
   * @param   {Node}      el          The Element to check
   * @param   {Node}      [parentEl]  Parent to end loop in
   *
   * @return  {Number}              The index
   */
  OSjs.Utils.$index = function(el, parentEl) {
    if ( el ) {
      parentEl = parentEl || el.parentNode;
      if ( parentEl ) {
        var nodeList = Array.prototype.slice.call(parentEl.children);
        var nodeIndex = nodeList.indexOf(el, parentEl);
        return nodeIndex;
      }
    }
    return -1;
  };

  /**
   * Selects range in a text field
   *
   * @function $selectRange
   * @memberof OSjs.Utils
   *
   * @param     {Node}      field     The DOM Element
   * @param     {Number}    start     Start position
   * @param     {Number}    end       End position
   */
  OSjs.Utils.$selectRange = function(field, start, end) {
    if ( !field ) {
      throw new Error('Cannot select range: missing element');
    }

    if ( typeof start === 'undefined' || typeof end === 'undefined' ) {
      throw new Error('Cannot select range: mising start/end');
    }

    if ( field.createTextRange ) {
      var selRange = field.createTextRange();
      selRange.collapse(true);
      selRange.moveStart('character', start);
      selRange.moveEnd('character', end);
      selRange.select();
      field.focus();
    } else if ( field.setSelectionRange ) {
      field.focus();
      field.setSelectionRange(start, end);
    } else if ( typeof field.selectionStart !== 'undefined' ) {
      field.selectionStart = start;
      field.selectionEnd = end;
      field.focus();
    }
  };

  /**
   * Add a className to a DOM Element
   *
   * @function $addClass
   * @memberof OSjs.Utils
   *
   * @param   {Node}      el      The dom Element
   * @param   {String}    name    The class name
   */
  OSjs.Utils.$addClass = function(el, name) {
    if ( el ) {
      name.split(' ').forEach(function(n) {
        el.classList.add(n);
      });
    }
  };

  /**
   * Remove a className from a DOM Element
   *
   * @function $removeClass
   * @memberof OSjs.Utils
   *
   * @param   {Node}      el      The dom Element
   * @param   {String}    name    The class name
   */
  OSjs.Utils.$removeClass = function(el, name) {
    if ( el ) {
      name.split(' ').forEach(function(n) {
        el.classList.remove(n);
      });
    }
  };

  /**
   * Check if a DOM Element has given className
   *
   * @function $hasClass
   * @memberof OSjs.Utils
   *
   * @param   {Node}      el      The dom Element
   * @param   {String}    name    The class name
   */
  OSjs.Utils.$hasClass = function(el, name) {
    if ( el && name ) {
      return name.split(' ').every(function(n) {
        return el.classList.contains(n);
      });
    }
    return false;
  };

  /**
   * Escapes the given string for HTML
   *
   * works sort of like PHPs htmlspecialchars()
   *
   * @function $escape
   * @memberof OSjs.Utils
   *
   * @param   {String}    str       Input
   *
   * @return  {String}              Escaped HTML
   */
  OSjs.Utils.$escape = function(str) {
    var div = document.createElement('div');
    div.appendChild(document.createTextNode(str));
    return div.innerHTML;
  };

  /**
   * Create a link stylesheet tag
   *
   * @function $createCSS
   * @memberof OSjs.Utils
   *
   * @param   {String}      src           The URL of resource
   * @param   {Function}    onload        onload callback
   * @param   {Function}    onerror       onerror callback
   *
   * @return  {Node}                The tag
   */
  OSjs.Utils.$createCSS = function(src, onload, onerror) {
    var link = document.createElement('link');
    link.setAttribute('rel', 'stylesheet');
    link.setAttribute('type', 'text/css');
    link.onload = onload || function() {};
    link.onerror = onerror || function() {};
    link.setAttribute('href', src);

    document.getElementsByTagName('head')[0].appendChild(link);

    return link;
  };

  /**
   * Create a script tag
   *
   * @function $createJS
   * @memberof OSjs.Utils
   *
   * @param   {String}      src                   The URL of resource
   * @param   {Function}    onreadystatechange    readystatechange callback
   * @param   {Function}    onload                onload callback
   * @param   {Function}    onerror               onerror callback
   * @param   {Object}      [attrs]               dict with optional arguments
   *
   * @return  {Node}                              The tag
   */
  OSjs.Utils.$createJS = function(src, onreadystatechange, onload, onerror, attrs) {
    var res = document.createElement('script');

    res.onreadystatechange = onreadystatechange || function() {};
    res.onerror = onerror || function() {};
    res.onload = onload || function() {};

    attrs = OSjs.Utils.mergeObject({
      type: 'text/javascript',
      charset: 'utf-8',
      src: src
    }, attrs || {});

    Object.keys(attrs).forEach(function(k) {
      res[k] = String(attrs[k]);
    });

    document.getElementsByTagName('head')[0].appendChild(res);

    return res;
  };

  /**
   * Check if event happened on a form element
   *
   * @function $isFormElement
   * @memberof OSjs.Utils
   *
   * @param   {Event}       ev      DOM Event
   * @param   {Array}       types   Array of types
   *
   * @return  {Boolean}             If is a form element
   */
  OSjs.Utils.$isFormElement = function(ev, types) {
    types = types || ['TEXTAREA', 'INPUT', 'SELECT'];

    var d = ev.srcElement || ev.target;
    if ( d ) {
      if ( types.indexOf(d.tagName.toUpperCase()) >= 0 ) {
        if ( !(d.readOnly || d.disabled) ) {
          return true;
        }
      }
    }
    return false;
  };

  /**
   * @function $isInput
   * @memberof OSjs.Utils
   * @alias OSjs.Utils.isFormElement
   * @deprecated Please use aliased method instead
   */
  OSjs.Utils.$isInput = function(ev) {
    console.warn('Utils::$isInput is deprecated', 'Use Utils::$isFormElement instead');
    return this.$isFormElement(ev);
  };

  /**
   * Set or Get element CSS
   *
   * @param {Node}                  el      DOM Node
   * @param {(String|Object)}       ink     CSS attribute name to get/set, or full dict to set
   * @param {(String|Number)}       [inv]   If previous argument was a string, this is the value that will be set
   *
   * @return {String} CSS attribute value
   *
   * @example
   * Utils.$css(element, {
   *  backgroundColor: '#000',
   *  'font-size': '14px' // You can also use CSS attributes like normal
   * });
   *
   * @example
   * Utils.$css(element, 'font-family', 'Arial');
   *
   * @example
   * Utils.$css(element, 'font-family'); // -> 'Arial'. Same as $getStyle
   *
   * @function $css
   * @memberof OSjs.Utils
   */
  OSjs.Utils.$css = function(el, ink, inv) {
    function rep(k) {
      return k.replace(/\-(\w)/g, function(strMatch, p1) {
        return p1.toUpperCase();
      });
    }

    var obj = {};
    if ( arguments.length === 2 ) {
      if ( typeof ink === 'string' ) {
        return el.parentNode ? OSjs.Utils.$getStyle(el, ink) : el.style[rep(ink)];
      }
      obj = ink;
    } else if ( arguments.length === 3 ) {
      obj[ink] = inv;
    }

    Object.keys(obj).forEach(function(k) {
      el.style[rep(k)] = String(obj[k]);
    });
  };

})();
<|endoftext|>


<commit_before>"use strict";

var util = require("substance-util");

var DefaultConfiguration = require('./default');

var ElifeConfiguration = function() {

};

ElifeConfiguration.Prototype = function() {

  // Resolves figure url
  // --------
  //

  this.enhanceFigure = function(state, node, element) {
    var graphic = element.querySelector("graphic");
    var url = graphic.getAttribute("xlink:href");

    // Example url to SVG: http://cdn.elifesciences.org/elife-articles/00768/svg/elife00768f001.svg
    url = [
      "http://cdn.elifesciences.org/elife-articles/",
      state.doc.id,
      "/svg/",
      url,
      ".svg"
    ].join('');

    node.url = url;
  };

  this.enhanceVideo = function(state, node, element) {
    var el = element.querySelector("media") || element;
    var href = element.getAttribute("xlink:href").split(".");
    var name = href[0];

    node.url = "http://static.movie-usa.glencoesoftware.com/mp4/10.7554/"+name+".mp4";
    node.url_ogv = "http://static.movie-usa.glencoesoftware.com/ogv/10.7554/"+name+".ogv";
    node.url_webm = "http://static.movie-usa.glencoesoftware.com/webm/10.7554/"+name+".webm";
    node.poster = "http://static.movie-usa.glencoesoftware.com/jpg/10.7554/"+name+".jpg";
  };

  // Add additional information to the info view
  // ---------
  //
  // Impact
  // Major datasets
  // Acknowledgements
  // Copyright

  this.enhanceInfo = function(converter, state, article) {
    var doc = state.doc;

    // Initialize the Article Info object
    var articleInfo = {
      "id": "articleinfo",
      "type": "paragraph",
      "children": []
    };
    var nodes = articleInfo.children;

    // Get the author's impact statement
    var meta = article.querySelectorAll("meta-value");
    var impact = meta[1];

    var h1 = {
      "type": "heading",
      "id": state.nextId("heading"),
      "level": 1,
      "content": "Impact",
    };
    doc.create(h1);
    nodes.push(h1.id);
    var t1 = {
      "type" : "text",
      "id" : state.nextId("text"),
      "content" : impact.textContent
    };
    doc.create(t1)
    nodes.push(t1.id)

    // Get copyright and license information
    var license = article.querySelector("permissions");
    if (license) {
      var h1 = {
        "type" : "heading",
        "id" : state.nextId("heading"),
        "level" : 1,
        "content" : "Copyright and License"
      };
      doc.create(h1);
      nodes.push(h1.id);

      var copyright = license.querySelector("copyright-statement");
      if (copyright) {
        var t1 = {
          "type" : "text",
          "id" : state.nextId("text"),
          "content" : copyright.textContent
        };
        doc.create(t1);
        nodes.push(t1.id);
      }
      var lic = license.querySelector("license");
      var children = util.dom.getChildren(lic);
      for (var i = 0;i < children.length;i++){
        var child = children[i];
        var type = util.dom.getNodeType(child);
        console.log(type)
        if (type === 'p' || type === 'license-p') {
          console.log('here')
          nodes.push(converter.paragraph(state, child));
        }
      }
    }

    // Get acknowledgements

    var ack = article.querySelector("ack");
    if (ack) {
      var h1 = {
        "type" : "heading",
        "id" : state.nextId("heading"),
        "level" : 1,
        "content" : "Acknowledgements"
      };
      doc.create(h1);
      nodes.push(h1.id);

      nodes.push(converter.paragraphGroup(state, util.dom.getChildren(ack)));
    }

    //nodes = nodes.concat(converter.bodyNodes(state, util.dom.getChildren(body)));
    doc.create(articleInfo);
    console.log(JSON.stringify(articleInfo));
    doc.show("info", articleInfo.id);
  };

  // Add Decision letter and author response
  // ---------

  this.enhanceArticle = function(converter, state, article) {

    var nodes = [];

    // Decision letter (if available)
    // -----------

    var articleCommentary = article.querySelector("#SA1");
    if (articleCommentary) {

      var heading = {
        id: state.nextId("heading"),
        type: "heading",
        level: 1,
        content: "Article Commentary"
      };
      doc.create(heading);
      nodes.push(heading);

      var heading = {
        id: state.nextId("heading"),
        type: "heading",
        level: 2,
        content: "Decision letter"
      };
      doc.create(heading);
      nodes.push(heading);

      var body = articleCommentary.querySelector("body");
      nodes = nodes.concat(converter.bodyNodes(state, util.dom.getChildren(body)));
    }

    // Author response
    // -----------

    var authorResponse = article.querySelector("#SA2");
    if (authorResponse) {

      var heading = {
        id: state.nextId("heading"),
        type: "heading",
        level: 2,
        content: "Author response"
      };
      doc.create(heading);
      nodes.push(heading);

      var body = authorResponse.querySelector("body");
      nodes = nodes.concat(converter.bodyNodes(state, util.dom.getChildren(body)));
    }

    // Show them off
    // ----------

    if (nodes.length > 0) {
      converter.show(state, nodes);
    }

    this.enhanceInfo(converter, state, article);
  };
};

ElifeConfiguration.Prototype.prototype = DefaultConfiguration.prototype;
ElifeConfiguration.prototype = new ElifeConfiguration.Prototype();
ElifeConfiguration.prototype.constructor = ElifeConfiguration;

module.exports = ElifeConfiguration;
<commit_msg>magic...<commit_after>"use strict";

var util = require("substance-util");

var DefaultConfiguration = require('./default');

var ElifeConfiguration = function() {

};

ElifeConfiguration.Prototype = function() {

  // Resolves figure url
  // --------
  //

  this.enhanceFigure = function(state, node, element) {
    var graphic = element.querySelector("graphic");
    var url = graphic.getAttribute("xlink:href");

    // Example url to SVG: http://cdn.elifesciences.org/elife-articles/00768/svg/elife00768f001.svg
    url = [
      "http://cdn.elifesciences.org/elife-articles/",
      state.doc.id,
      "/svg/",
      url,
      ".svg"
    ].join('');

    node.url = url;
  };

  this.enhanceVideo = function(state, node, element) {
    var el = element.querySelector("media") || element;
    var href = element.getAttribute("xlink:href").split(".");
    var name = href[0];

    node.url = "http://static.movie-usa.glencoesoftware.com/mp4/10.7554/"+name+".mp4";
    node.url_ogv = "http://static.movie-usa.glencoesoftware.com/ogv/10.7554/"+name+".ogv";
    node.url_webm = "http://static.movie-usa.glencoesoftware.com/webm/10.7554/"+name+".webm";
    node.poster = "http://static.movie-usa.glencoesoftware.com/jpg/10.7554/"+name+".jpg";
  };

  // Add additional information to the info view
  // ---------
  //
  // Impact
  // Major datasets
  // Acknowledgements
  // Copyright

  this.enhanceInfo = function(converter, state, article) {
    var doc = state.doc;

    // Initialize the Article Info object
    var articleInfo = {
      "id": "articleinfo",
      "type": "paragraph",
      "children": []
    };
    var nodes = articleInfo.children;

    // Get the author's impact statement
    var meta = article.querySelectorAll("meta-value");
    var impact = meta[1];

    var h1 = {
      "type": "heading",
      "id": state.nextId("heading"),
      "level": 1,
      "content": "Impact",
    };
    doc.create(h1);
    nodes.push(h1.id);
    var t1 = {
      "type" : "text",
      "id" : state.nextId("text"),
      "content" : impact.textContent
    };
    doc.create(t1)
    nodes.push(t1.id)

    // Get copyright and license information
    var license = article.querySelector("permissions");
    if (license) {
      var h1 = {
        "type" : "heading",
        "id" : state.nextId("heading"),
        "level" : 1,
        "content" : "Copyright and License"
      };
      doc.create(h1);
      nodes.push(h1.id);

      var copyright = license.querySelector("copyright-statement");
      if (copyright) {
        var t1 = {
          "type" : "text",
          "id" : state.nextId("text"),
          "content" : copyright.textContent
        };
        doc.create(t1);
        nodes.push(t1.id);
      }
      var lic = license.querySelector("license");
      nodes.push(converter.bodyNodes(state, util.dom.getChildren(lic)));
    }

    // Get acknowledgements

    var ack = article.querySelector("ack");
    if (ack) {
      var h1 = {
        "type" : "heading",
        "id" : state.nextId("heading"),
        "level" : 1,
        "content" : "Acknowledgements"
      };
      doc.create(h1);
      nodes.push(h1.id);

      nodes.push(converter.bodyNodes(state, util.dom.getChildren(ack)));
    }

    //nodes = nodes.concat(converter.bodyNodes(state, util.dom.getChildren(body)));
    doc.create(articleInfo);
    console.log(JSON.stringify(articleInfo));
    doc.show("info", articleInfo.id);
  };

  // Add Decision letter and author response
  // ---------

  this.enhanceArticle = function(converter, state, article) {

    var nodes = [];

    // Decision letter (if available)
    // -----------

    var articleCommentary = article.querySelector("#SA1");
    if (articleCommentary) {

      var heading = {
        id: state.nextId("heading"),
        type: "heading",
        level: 1,
        content: "Article Commentary"
      };
      doc.create(heading);
      nodes.push(heading);

      var heading = {
        id: state.nextId("heading"),
        type: "heading",
        level: 2,
        content: "Decision letter"
      };
      doc.create(heading);
      nodes.push(heading);

      var body = articleCommentary.querySelector("body");
      nodes = nodes.concat(converter.bodyNodes(state, util.dom.getChildren(body)));
    }

    // Author response
    // -----------

    var authorResponse = article.querySelector("#SA2");
    if (authorResponse) {

      var heading = {
        id: state.nextId("heading"),
        type: "heading",
        level: 2,
        content: "Author response"
      };
      doc.create(heading);
      nodes.push(heading);

      var body = authorResponse.querySelector("body");
      nodes = nodes.concat(converter.bodyNodes(state, util.dom.getChildren(body)));
    }

    // Show them off
    // ----------

    if (nodes.length > 0) {
      converter.show(state, nodes);
    }

    this.enhanceInfo(converter, state, article);
  };
};

ElifeConfiguration.Prototype.prototype = DefaultConfiguration.prototype;
ElifeConfiguration.prototype = new ElifeConfiguration.Prototype();
ElifeConfiguration.prototype.constructor = ElifeConfiguration;

module.exports = ElifeConfiguration;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { render } from 'react-dom';
import { Router, Route, Link, browserHistory } from 'react-router';
import * as common from 'chain-reaction.common';

import Home from '../Home';
import Sample from '../Sample';
import Login from '../Login';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.requireAuth = this.requireAuth.bind(this);
    this.handleChange = this.handleChange.bind(this);

    this.state = {
      unsubscribe: this.props.store.subscribe(this.handleChange)
    }
  }

  handleChange() {
    // Persist to localStorage
    var user = this.props.store.getState().user;
    if (user.status === 'authenticated') {
      localStorage['CR_PROFILE'] = JSON.stringify(user);
    }
  }

  componentWillMount() {
    if (localStorage['CR_PROFILE']) {
      var user = JSON.parse(localStorage['CR_PROFILE']);
      this.props.store.dispatch(common.actions.receiveLogin(user.email, {data: user.profile}));
    }
  }

  componentWillUnmount() {
    this.state.unsubscribe();
  }

  requireAuth(nextState, replace) {
    var store = this.props.store;
    if (store.getState().user.status !== 'authenticated') {
      replace({
        pathname: '/login',
        state: { nextPathname: nextState.location.pathname }
      });
    }
  }

  render() {
    return (
      <Router history={browserHistory}>
        <Route path="/" component={Home}></Route>
        <Route path="/login" component={Login}></Route>
        <Route path="/sample" component={Sample} onEnter={this.requireAuth}></Route>
        <Route path="*" component={Home}></Route>
      </Router>
    );
  }
}<commit_msg>Delete from localStorage if a user ever comes out of authentication<commit_after>import React, { Component } from 'react';
import { render } from 'react-dom';
import { Router, Route, Link, browserHistory } from 'react-router';
import * as common from 'chain-reaction.common';

import Home from '../Home';
import Sample from '../Sample';
import Login from '../Login';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.requireAuth = this.requireAuth.bind(this);
    this.handleChange = this.handleChange.bind(this);

    this.state = {
      unsubscribe: this.props.store.subscribe(this.handleChange)
    }
  }

  handleChange() {
    // Persist to localStorage
    var user = this.props.store.getState().user;
    if (user.status === 'authenticated') {
      localStorage['CR_PROFILE'] = JSON.stringify(user);
    } else {
      delete localStorage['CR_PROFILE'];
    }
  }

  componentWillMount() {
    if (localStorage['CR_PROFILE']) {
      var user = JSON.parse(localStorage['CR_PROFILE']);
      this.props.store.dispatch(common.actions.receiveLogin(user.email, {data: user.profile}));
    }
  }

  componentWillUnmount() {
    this.state.unsubscribe();
  }

  requireAuth(nextState, replace) {
    var store = this.props.store;
    if (store.getState().user.status !== 'authenticated') {
      replace({
        pathname: '/login',
        state: { nextPathname: nextState.location.pathname }
      });
    }
  }

  render() {
    return (
      <Router history={browserHistory}>
        <Route path="/" component={Home}></Route>
        <Route path="/login" component={Login}></Route>
        <Route path="/sample" component={Sample} onEnter={this.requireAuth}></Route>
        <Route path="*" component={Home}></Route>
      </Router>
    );
  }
}<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import {connect} from 'react-redux';
/* { import { Link } from 'react-router'; } */
/* { import { CounterButton } from 'components'; } */
import config from '../../config';
import Helmet from 'react-helmet';
import Global from 'react-global';

@connect(
  state => ({ userLoggedIn: 'wis' })
)

export default class Home extends Component {

  static propTypes = {
    userLoggedIn: PropTypes.string
  }

  render() {
    const styles = require('./Home.scss');
    const {userLoggedIn} = this.props;
    // require the logo image both from client and server
    const logoImage = require('./logo.png');
    return (

        <Helmet title="Home"/>

                Global.get('FOO')

{config.app.title}

{config.app.description}

{config.app.subdescription}

          { /* {

            <CounterButton multireducerKey="counter1"/>
            <CounterButton multireducerKey="counter2"/>
            <CounterButton multireducerKey="counter3"/>

          } */
          }

Neuste Blogeinträge

            React-Applikation produktiv auf Heroku publizieren (Node.js, Express.js, Heroku)

    );
  }
}
<commit_msg>new try v5.10aaaasssss<commit_after>import React, { Component, PropTypes } from 'react';
import {connect} from 'react-redux';
/* { import { Link } from 'react-router'; } */
/* { import { CounterButton } from 'components'; } */
import config from '../../config';
import Helmet from 'react-helmet';
import Global from 'react-global';

@connect(
  state => ({ userLoggedIn: 'wis' })
)

export default class Home extends Component {

  static propTypes = {
    userLoggedIn: PropTypes.string
  }

  render() {
    const styles = require('./Home.scss');
    const {userLoggedIn} = this.props;
    // require the logo image both from client and server
    const logoImage = require('./logo.png');
    return (

        <Helmet title="Home"/>

                { Global.get('FOO') }

{config.app.title}

{config.app.description}

{config.app.subdescription}

          { /* {

            <CounterButton multireducerKey="counter1"/>
            <CounterButton multireducerKey="counter2"/>
            <CounterButton multireducerKey="counter3"/>

          } */
          }

Neuste Blogeinträge

            React-Applikation produktiv auf Heroku publizieren (Node.js, Express.js, Heroku)

    );
  }
}
<|endoftext|>


<commit_before>var vows = require('vows')
  , assert = require('assert')
  , fs = require('fs');

assertDeepSimilar = function(res, exp){
  for (var i = 0; i < res.length; i++){
 //   res[i] = Math.round(res[i]/100)*100;
  }
  assert.deepEqual(res, exp)
}

assertWithinRange = function(res, exp, range){
  assert.ok((res - exp) < range || (res - exp) > -range, "Not within range:" + res + " (" + exp + "+- " + range + ")")
}

assertWithinRanges = function(res, exp, range){
  for (var i =0; i<res.length; i++){
    assertWithinRange(res[i], exp[i], range);
  }
}

vows.describe('Smoke Tests OpenCV').addBatch({
	  "Importing": {

    	topic: require('../lib/opencv')

      , "returns obj": function(topic){
        assert.ok(!!topic)
      }

    	, '.version' : function(topic){
    		assert.ok(!!topic.version)
    	  }

    	, '.Point imports': function(topic){
    		assert.ok(!!topic.Point)
    	}

      , '.Matrix imports': function(topic){
        assert.ok(!!topic.Matrix)
      }

      , 'importing library multiple times is ok' : function(){
        var cv1 = require('../lib/opencv')
          , cv2 = require('../lib/opencv')
          cv1.readImage('./examples/mona.png', function(){});
          cv2.readImage('./examples/mona.png', function(){});
      }
    }

  , "Point" : {
    topic : require('../lib/opencv')

    , 'constructor' : function(cv){
      assert.ok(!!new cv.Point(1, 2))
      assert.throws(function () { cv.Point(1, 2)}, TypeError); // cannot call without new
    }

    , 'accessors' : function(cv){
        assert.equal(new cv.Point(1, 2).x, 1)
        assert.equal(new cv.Point(1, 2).y, 2)
        assert.equal(Math.round(new cv.Point(1.1, 2).x * 100), 110)
        assert.equal(Math.round(new cv.Point(1.2, 2.75).y *100), 275)

        assert.throws(function () {new cv.Point(1.1, 2).x = 5}, Error); // Points are immutable
        assert.throws(function () {new cv.Point(1.1, 2).y = 5}, Error); // Points are immutable

    }

    , '.dot': function(cv){
      var p1 = new cv.Point(3, 6)
        , p2 = new cv.Point(5, 7)

      assert.ok(p1.dot);
      assert.equal(p1.dot(p2), 57);

    }

    , '.inside' : function(){}
  }

  , "Matrix": {
    topic : require('../lib/opencv')

    , "constructor" : function(cv){
      assert.ok(cv.Matrix);
      assert.ok(new cv.Matrix);
      assert.ok(new cv.Matrix(1,2));
    }

    , "set/row" : function(cv){
      var mat = new cv.Matrix(1, 2);
      mat.set(0,0,3)
      mat.set(0,1,5000)
      assert.deepEqual(mat.row(0), [3,5000]);
    }

    , "get/set" : function(cv){
       var mat = new cv.Matrix(1,2);
       assert.equal(mat.set(0,0,3), undefined);
       assert.equal(mat.get(0,0), 3);
    }

    , ".width" : function(cv){
      var mat = new cv.Matrix(6,7);
      assert.equal(mat.width(), 7);
    }

    , ".height" : function(cv){
      var mat = new cv.Matrix(6,7);
      assert.equal(mat.height(), 6);
    }

    , ".size" : function(cv){
      var mat = new cv.Matrix(6,7);
      assert.deepEqual(mat.size(), [6, 7]);
    }

    , "resize" : function(cv){
      var mat = new cv.Matrix(6,7);
      assert.equal(mat.width(), 7);
      mat.resize(8,9);
      assert.equal(mat.width(), 8);

    }

    , 'row' : function(cv){
      var mat = new cv.Matrix.Eye(4,4)
      assertDeepSimilar(mat.row(1), [0,1,0,0])
      assertDeepSimilar(mat.row(2), [0,0,1,0])
    }

    , 'col' : function(cv){
      var mat = new cv.Matrix.Eye(4,4);
      assertDeepSimilar(mat.col(1), [0,1,0,0])
      assertDeepSimilar(mat.col(2), [0,0,1,0])
    }

    , "empty": function(cv){
      assert.equal(new cv.Matrix().empty(), true);
    }

    , "toBuffer": function(cv){
        var buf = fs.readFileSync('./examples/mona.png')

        cv.readImage(buf.slice(0), function(err, mat){
          var buf0 = mat.toBuffer()

          assert.ok(buf0);
        //assert.equal(buf.toString('base64'), buf0.toString('base64'));
        })

    }

    , "toBuffer Async": {
      topic: function(cv){
          var buf = fs.readFileSync('./examples/mona.png')
            , cb = this.callback
          cv.readImage(buf.slice(0), function(err, mat){
            var buff = mat.toBuffer(function(){
              cb.apply(this, arguments)
            })
          })
        }
    ,  'gives a buffer' : function(e, res){
        assert.ok(!e)
        assert.ok(res);
        assert.ok(res.length > 100);
      }
    }

    , "detectObject": {

     topic : function(){
        var cv = require('../lib/opencv')
          , cb = this.callback

        cv.readImage("./examples/mona.png", function(err, im){
          im.detectObject(cv.FACE_CASCADE, {}, cb)
        })
      }

      , "finds face": function(err, faces){
          assert.isNull(err);
          assert.isArray(faces);
          assert.equal(faces.length, 1)
      }
    }

    , ".absDiff" : function(cv){
      var mat1 = new cv.Matrix(1,1);
      mat1.set(0,0, 0);

      var mat2 = new cv.Matrix(1,1);
      mat2.set(0,0, 1);

      var diff = new cv.Matrix(1,1);
      diff.absDiff(mat1, mat2);

      assert.equal(diff.get(0,0), 1);
    }

    , ".bitwiseXor" : function(cv) {
      var mat1 = new cv.Matrix(1,1);
      mat1.set(0,0, 1);

      var mat2 = new cv.Matrix(1,1);
      mat2.set(0,0, 1);

      var xored = new cv.Matrix(1,1);
      xored.bitwiseXor(mat1, mat2);

      assert.equal(xored.get(0,0), 0);
    }

    , ".countNonZero": function(cv) {
      cv.readImage("./examples/mona.png", function(err, im) {
          assert.ok(im);

          im.convertGrayscale();
          assert.equal(im.countNonZero(), 378000);
      });
    }

  }

  , "Image" : {
    topic : require('../lib/opencv')

    , ".readImage from file": function(cv){
      cv.readImage("./examples/mona.png", function(err, im){
        assert.ok(im);
        assert.equal(im.width(), 500);
        assert.equal(im.height(), 756)
        assert.equal(im.empty(), false)
      })
    }

    , ".readImage from buffer" : function(cv){
      cv.readImage(fs.readFileSync('./examples/mona.png'), function(err, im){
        assert.ok(im);
        assert.equal(im.width(), 500);
        assert.equal(im.height(), 756)
        assert.equal(im.empty(), false)
      })

    }

  }

  , "CascadeClassifier": {
    topic : require('../lib/opencv')

    , "constructor" : function(cv){
      assert.ok(new cv.CascadeClassifier("./data/haarcascade_frontalface_alt.xml"))
    }

    , "face detection": {
      topic : function(){
        var cv = require('../lib/opencv')
          , self = this

        cv.readImage("./examples/mona.png", function(err, im){
          cascade = new cv.CascadeClassifier("./data/haarcascade_frontalface_alt.xml");
          cascade.detectMultiScale(im, self.callback)//, 1.1, 2, [30, 30]);
        })

      }

      , "finds face": function(err, faces){
          assert.isNull(err);
          assert.isArray(faces);
          assert.equal(faces.length, 1)

      }
    }

  }

  , "ImageDataStream" : {
    topic : require('../lib/opencv')

    , "pipe" : {
      topic : function(cv){
        var s = new cv.ImageDataStream()
          , self = this
        s.on('load', function(im){
          assert.ok(im)
          assert.equal(im.empty(), false);
          self.callback()
        })
        fs.createReadStream('./examples/mona.png').pipe(s);
      }

      , "loaded" : function(im){
        //assert.ok(im)
        //assert.equal(im.empty(), false);
      }
    }

  }
  , "ImageStream" :{
    topic : require('../lib/opencv')
    , "write" : {
      topic: function(cv){
        var s = new cv.ImageStream()
          , im = fs.readFileSync('./examples/mona.png')
          , self = this;

        s.on('data', function(m){
          self.callback(null, m)
        })
        s.write(im);
      }
      , "receives data" : function(mat){
        assert.deepEqual(mat.size(), [756,500])
      }
    }

  }
  , "ObjectDetectionStream" :{
    topic : require('../lib/opencv')

  }

  , "CamShift" : {

     "Can Create and Track" : {
      topic : function(){
        var cv = require('../lib/opencv')
          , self = this

        cv.readImage('./examples/coin1.jpg', function(e, im){
          cv.readImage('./examples/coin2.jpg', function(e, im2){
            self.callback(im, im2, cv)
          })
        })
      }

      , "create TrackedObject" : function(im, im2, cv){
        var tracked = new cv.TrackedObject(im, [420, 110, 490, 170]);
        assert.ok(tracked);
      }

      , "use TrackedObject.track" : function(im, im2, cv){
          var tracked = new cv.TrackedObject(im, [420, 110, 490, 170], {channel: 'v'});
          assertWithinRanges(tracked.track(im2), [386, 112, 459, 166], 10);
      }
    }

  }

}).export(module);
<commit_msg>combine absDiff and countNonZero tests<commit_after>var vows = require('vows')
  , assert = require('assert')
  , fs = require('fs');

assertDeepSimilar = function(res, exp){
  for (var i = 0; i < res.length; i++){
 //   res[i] = Math.round(res[i]/100)*100;
  }
  assert.deepEqual(res, exp)
}

assertWithinRange = function(res, exp, range){
  assert.ok((res - exp) < range || (res - exp) > -range, "Not within range:" + res + " (" + exp + "+- " + range + ")")
}

assertWithinRanges = function(res, exp, range){
  for (var i =0; i<res.length; i++){
    assertWithinRange(res[i], exp[i], range);
  }
}

vows.describe('Smoke Tests OpenCV').addBatch({
	  "Importing": {

    	topic: require('../lib/opencv')

      , "returns obj": function(topic){
        assert.ok(!!topic)
      }

    	, '.version' : function(topic){
    		assert.ok(!!topic.version)
    	  }

    	, '.Point imports': function(topic){
    		assert.ok(!!topic.Point)
    	}

      , '.Matrix imports': function(topic){
        assert.ok(!!topic.Matrix)
      }

      , 'importing library multiple times is ok' : function(){
        var cv1 = require('../lib/opencv')
          , cv2 = require('../lib/opencv')
          cv1.readImage('./examples/mona.png', function(){});
          cv2.readImage('./examples/mona.png', function(){});
      }
    }

  , "Point" : {
    topic : require('../lib/opencv')

    , 'constructor' : function(cv){
      assert.ok(!!new cv.Point(1, 2))
      assert.throws(function () { cv.Point(1, 2)}, TypeError); // cannot call without new
    }

    , 'accessors' : function(cv){
        assert.equal(new cv.Point(1, 2).x, 1)
        assert.equal(new cv.Point(1, 2).y, 2)
        assert.equal(Math.round(new cv.Point(1.1, 2).x * 100), 110)
        assert.equal(Math.round(new cv.Point(1.2, 2.75).y *100), 275)

        assert.throws(function () {new cv.Point(1.1, 2).x = 5}, Error); // Points are immutable
        assert.throws(function () {new cv.Point(1.1, 2).y = 5}, Error); // Points are immutable

    }

    , '.dot': function(cv){
      var p1 = new cv.Point(3, 6)
        , p2 = new cv.Point(5, 7)

      assert.ok(p1.dot);
      assert.equal(p1.dot(p2), 57);

    }

    , '.inside' : function(){}
  }

  , "Matrix": {
    topic : require('../lib/opencv')

    , "constructor" : function(cv){
      assert.ok(cv.Matrix);
      assert.ok(new cv.Matrix);
      assert.ok(new cv.Matrix(1,2));
    }

    , "set/row" : function(cv){
      var mat = new cv.Matrix(1, 2);
      mat.set(0,0,3)
      mat.set(0,1,5000)
      assert.deepEqual(mat.row(0), [3,5000]);
    }

    , "get/set" : function(cv){
       var mat = new cv.Matrix(1,2);
       assert.equal(mat.set(0,0,3), undefined);
       assert.equal(mat.get(0,0), 3);
    }

    , ".width" : function(cv){
      var mat = new cv.Matrix(6,7);
      assert.equal(mat.width(), 7);
    }

    , ".height" : function(cv){
      var mat = new cv.Matrix(6,7);
      assert.equal(mat.height(), 6);
    }

    , ".size" : function(cv){
      var mat = new cv.Matrix(6,7);
      assert.deepEqual(mat.size(), [6, 7]);
    }

    , "resize" : function(cv){
      var mat = new cv.Matrix(6,7);
      assert.equal(mat.width(), 7);
      mat.resize(8,9);
      assert.equal(mat.width(), 8);

    }

    , 'row' : function(cv){
      var mat = new cv.Matrix.Eye(4,4)
      assertDeepSimilar(mat.row(1), [0,1,0,0])
      assertDeepSimilar(mat.row(2), [0,0,1,0])
    }

    , 'col' : function(cv){
      var mat = new cv.Matrix.Eye(4,4);
      assertDeepSimilar(mat.col(1), [0,1,0,0])
      assertDeepSimilar(mat.col(2), [0,0,1,0])
    }

    , "empty": function(cv){
      assert.equal(new cv.Matrix().empty(), true);
    }

    , "toBuffer": function(cv){
        var buf = fs.readFileSync('./examples/mona.png')

        cv.readImage(buf.slice(0), function(err, mat){
          var buf0 = mat.toBuffer()

          assert.ok(buf0);
        //assert.equal(buf.toString('base64'), buf0.toString('base64'));
        })

    }

    , "toBuffer Async": {
      topic: function(cv){
          var buf = fs.readFileSync('./examples/mona.png')
            , cb = this.callback
          cv.readImage(buf.slice(0), function(err, mat){
            var buff = mat.toBuffer(function(){
              cb.apply(this, arguments)
            })
          })
        }
    ,  'gives a buffer' : function(e, res){
        assert.ok(!e)
        assert.ok(res);
        assert.ok(res.length > 100);
      }
    }

    , "detectObject": {

     topic : function(){
        var cv = require('../lib/opencv')
          , cb = this.callback

        cv.readImage("./examples/mona.png", function(err, im){
          im.detectObject(cv.FACE_CASCADE, {}, cb)
        })
      }

      , "finds face": function(err, faces){
          assert.isNull(err);
          assert.isArray(faces);
          assert.equal(faces.length, 1)
      }
    }

    , ".absDiff" : function(cv) {
      cv.readImage("./examples/mona.png", function(err, im) {
        cv.readImage("./examples/mona.png", function(err, im2){
          assert.ok(im);
          assert.ok(im2);

          var diff = new cv.Matrix(im.width(), im.height());
          diff.absDiff(im, im2);

          diff.convertGrayscale();
          assert.equal(diff.countNonZero(), 0);
        });
      });
    }

    , ".bitwiseXor" : function(cv) {
      var mat1 = new cv.Matrix(1,1);
      mat1.set(0,0, 1);

      var mat2 = new cv.Matrix(1,1);
      mat2.set(0,0, 1);

      var xored = new cv.Matrix(1,1);
      xored.bitwiseXor(mat1, mat2);

      assert.equal(xored.get(0,0), 0);
    }

  }

  , "Image" : {
    topic : require('../lib/opencv')

    , ".readImage from file": function(cv){
      cv.readImage("./examples/mona.png", function(err, im){
        assert.ok(im);
        assert.equal(im.width(), 500);
        assert.equal(im.height(), 756)
        assert.equal(im.empty(), false)
      })
    }

    , ".readImage from buffer" : function(cv){
      cv.readImage(fs.readFileSync('./examples/mona.png'), function(err, im){
        assert.ok(im);
        assert.equal(im.width(), 500);
        assert.equal(im.height(), 756)
        assert.equal(im.empty(), false)
      })

    }

  }

  , "CascadeClassifier": {
    topic : require('../lib/opencv')

    , "constructor" : function(cv){
      assert.ok(new cv.CascadeClassifier("./data/haarcascade_frontalface_alt.xml"))
    }

    , "face detection": {
      topic : function(){
        var cv = require('../lib/opencv')
          , self = this

        cv.readImage("./examples/mona.png", function(err, im){
          cascade = new cv.CascadeClassifier("./data/haarcascade_frontalface_alt.xml");
          cascade.detectMultiScale(im, self.callback)//, 1.1, 2, [30, 30]);
        })

      }

      , "finds face": function(err, faces){
          assert.isNull(err);
          assert.isArray(faces);
          assert.equal(faces.length, 1)

      }
    }

  }

  , "ImageDataStream" : {
    topic : require('../lib/opencv')

    , "pipe" : {
      topic : function(cv){
        var s = new cv.ImageDataStream()
          , self = this
        s.on('load', function(im){
          assert.ok(im)
          assert.equal(im.empty(), false);
          self.callback()
        })
        fs.createReadStream('./examples/mona.png').pipe(s);
      }

      , "loaded" : function(im){
        //assert.ok(im)
        //assert.equal(im.empty(), false);
      }
    }

  }
  , "ImageStream" :{
    topic : require('../lib/opencv')
    , "write" : {
      topic: function(cv){
        var s = new cv.ImageStream()
          , im = fs.readFileSync('./examples/mona.png')
          , self = this;

        s.on('data', function(m){
          self.callback(null, m)
        })
        s.write(im);
      }
      , "receives data" : function(mat){
        assert.deepEqual(mat.size(), [756,500])
      }
    }

  }
  , "ObjectDetectionStream" :{
    topic : require('../lib/opencv')

  }

  , "CamShift" : {

     "Can Create and Track" : {
      topic : function(){
        var cv = require('../lib/opencv')
          , self = this

        cv.readImage('./examples/coin1.jpg', function(e, im){
          cv.readImage('./examples/coin2.jpg', function(e, im2){
            self.callback(im, im2, cv)
          })
        })
      }

      , "create TrackedObject" : function(im, im2, cv){
        var tracked = new cv.TrackedObject(im, [420, 110, 490, 170]);
        assert.ok(tracked);
      }

      , "use TrackedObject.track" : function(im, im2, cv){
          var tracked = new cv.TrackedObject(im, [420, 110, 490, 170], {channel: 'v'});
          assertWithinRanges(tracked.track(im2), [386, 112, 459, 166], 10);
      }
    }

  }

}).export(module);
<|endoftext|>


<commit_before>import OlOverviewMap from 'ol/control/OverviewMap'

import { RewireMixin } from './RewireMixin'
import { ListenerOrganizerMixin } from '../ListenerOrganizerMixin'
import { mixin } from '../utilities'

import '../../less/overviewmap.less'
import { copyDeep } from '../utilitiesObject.js'

/**
 * @typedef {g4uControlOptions} OverviewMapOptions
 * @property {Localizable} [tipLabel]
 * @property {ol.layer.Group} [layerGroup]
 */

/**
 * @extends Control
 */
export class OverviewMap extends mixin(mixin(OlOverviewMap, RewireMixin), ListenerOrganizerMixin) {
  /**
   * @param {OverviewMapOptions} [options={}]
   */
  constructor (options = {}) {
    if (options.hasOwnProperty('title')) {
      options.tipLabel = options.localiser.selectL10N(options.title)
    } else {
      options.tipLabel = (options.hasOwnProperty('tipLabel'))
        ? options.localiser.selectL10N(options.tipLabel)
        : options.localiser.localiseUsingDictionary('OverviewMap tipLabel')
    }

    options.layers = []

    super(options)
  }

  setMap (map) {
    if (this.getMap()) {
      this.detachAllListeners()
    }
    super.setMap(map)
    if (map) {
      const view = map.getView()

      const layerConfigs = copyDeep(map.get('layerConfig').layers.filter(l => l.overview))

      for (const options of layerConfigs) {
        const layer = map.get('layerFactory').createLayer(options)
        this.getOverviewMap().addLayer(layer)
        const matchedLayer = map.getLayerGroup().getLayerById(options.id)
        if (options.overview === 'always') {
          layer.setVisible(true)
        } else {
          matchedLayer.on('change:visible', () => {
            layer.setVisible(matchedLayer.getVisible())
          })
        }
      }

      let $overviewmap = this.get$Element().find('.ol-overviewmap-map')

      $overviewmap = $overviewmap.add($overviewmap.find('.ol-overviewmap-box'))

      let dontClick = false

      this.listenAt($overviewmap).on('click', e => {
        if (!dontClick) {
          view.setCenter(this.getOverviewMap().getEventCoordinate(e))
        }
      })

      let mouseDown = false

      this.listenAt($overviewmap).on('mousedown', () => {
        dontClick = false
        mouseDown = true
      })

      this.listenAt($overviewmap).on('mouseup', () => {
        mouseDown = false
      })

      this.listenAt($overviewmap).on('mousemove', e => {
        if (mouseDown) {
          view.setCenter(this.getOverviewMap().getEventCoordinate(e))
        }
      })

      this.getOverviewMap().getView().on('change:center', () => {
        mouseDown = false
        dontClick = true
      })

      const $button = this.get$Element().find('button')
      this.listenAt($button).on('click', () => this.dispatchEvent('change:size'))
    }
  }

  afterPositioning () {
    this.getOverviewMap().updateSize()
  }
}
<commit_msg>fixed overview map<commit_after>import OlOverviewMap from 'ol/control/OverviewMap'

import { RewireMixin } from './RewireMixin'
import { ListenerOrganizerMixin } from '../ListenerOrganizerMixin'
import { mixin } from '../utilities'

import '../../less/overviewmap.less'
import { copyDeep } from '../utilitiesObject.js'

/**
 * @typedef {g4uControlOptions} OverviewMapOptions
 * @property {Localizable} [tipLabel]
 * @property {ol.layer.Group} [layerGroup]
 */

/**
 * @extends Control
 */
export class OverviewMap extends mixin(mixin(OlOverviewMap, RewireMixin), ListenerOrganizerMixin) {
  /**
   * @param {OverviewMapOptions} [options={}]
   */
  constructor (options = {}) {
    if (options.hasOwnProperty('title')) {
      options.tipLabel = options.localiser.selectL10N(options.title)
    } else {
      options.tipLabel = (options.hasOwnProperty('tipLabel'))
        ? options.localiser.selectL10N(options.tipLabel)
        : options.localiser.localiseUsingDictionary('OverviewMap tipLabel')
    }

    options.layers = []

    super(options)
  }

  setMap (map) {
    if (this.getMap()) {
      this.detachAllListeners()
    }
    super.setMap(map)
    if (map) {
      const view = map.getView()

      const layerConfigs = copyDeep(map.get('layerConfig').layers.filter(l => l.overview))

      for (const options of layerConfigs) {
        const layer = map.get('layerFactory').createLayer(options)
        this.getOverviewMap().addLayer(layer)
        const matchedLayer = map.getLayerGroup().getLayerById(options.id)
        if (options.overview === 'always') {
          layer.setVisible(true)
        } else {
          matchedLayer.on('change:visible', () => {
            layer.setVisible(matchedLayer.getVisible())
          })
        }
      }

      this.listenAt(this.getOverviewMap()).on('click', e => {
        view.setCenter(e.coordinate)
      })

      const $button = this.get$Element().find('button')
      this.listenAt($button).on('click', () => this.dispatchEvent('change:size'))
    }
  }

  afterPositioning () {
    this.getOverviewMap().updateSize()
  }
}
<|endoftext|>


<commit_before>const VolumeInterface = require('./util/VolumeInterface');
const Prism = require('prism-media');
const OpusEncoders = require('./opus/OpusEngineList');
const Collection = require('../../util/Collection');

const ffmpegArguments = [
  '-analyzeduration', '0',
  '-loglevel', '0',
  '-f', 's16le',
  '-ar', '48000',
  '-ac', '2',
];

/**
 * A voice broadcast can be played across multiple voice connections for improved shared-stream efficiency.
 *
 * Example usage:
 * ```js
 * const broadcast = client.createVoiceBroadcast();
 * broadcast.playFile('./music.mp3');
 * // play "music.mp3" in all voice connections that the client is in
 * for (const connection of client.voiceConnections.values()) {
 *   connection.playBroadcast(broadcast);
 * }
 * ```
 * @implements {VolumeInterface}
 */
class VoiceBroadcast extends VolumeInterface {
  constructor(client) {
    super();
    /**
     * The client that created the broadcast
     * @type {Client}
     */
    this.client = client;
    this._dispatchers = new Collection();
    this._encoders = new Collection();
    /**
     * The audio transcoder that this broadcast uses
     * @type {Prism}
     */
    this.prism = new Prism();
    /**
     * The current audio transcoder that is being used
     * @type {Object}
     */
    this.currentTranscoder = null;
    this.tickInterval = null;
    this._volume = 1;
  }

  /**
   * An array of subscribed dispatchers
   * @type {StreamDispatcher[]}
   * @readonly
   */
  get dispatchers() {
    let d = [];
    for (const container of this._dispatchers.values()) {
      d = d.concat(Array.from(container.values()));
    }
    return d;
  }

  get _playableStream() {
    const currentTranscoder = this.currentTranscoder;
    if (!currentTranscoder) return null;
    const transcoder = currentTranscoder.transcoder;
    const options = currentTranscoder.options;
    return (transcoder && transcoder.output) || options.stream;
  }

  unregisterDispatcher(dispatcher, old) {
    const volume = old || dispatcher.volume;

    /**
     * Emitted whenever a stream dispatcher unsubscribes from the broadcast.
     * @event VoiceBroadcast#unsubscribe
     * @param {StreamDispatcher} dispatcher The unsubscribed dispatcher
     */
    this.emit('unsubscribe', dispatcher);
    for (const container of this._dispatchers.values()) {
      container.delete(dispatcher);

      if (!container.size) {
        this._encoders.get(volume).destroy();
        this._dispatchers.delete(volume);
        this._encoders.delete(volume);
      }
    }
  }

  registerDispatcher(dispatcher) {
    if (!this._dispatchers.has(dispatcher.volume)) {
      this._dispatchers.set(dispatcher.volume, new Set());
      this._encoders.set(dispatcher.volume, OpusEncoders.fetch());
    }
    const container = this._dispatchers.get(dispatcher.volume);
    if (!container.has(dispatcher)) {
      container.add(dispatcher);
      dispatcher.once('end', () => this.unregisterDispatcher(dispatcher));
      dispatcher.on('volumeChange', (o, n) => {
        this.unregisterDispatcher(dispatcher, o);
        if (!this._dispatchers.has(n)) {
          this._dispatchers.set(n, new Set());
          this._encoders.set(n, OpusEncoders.fetch());
        }
        this._dispatchers.get(n).add(dispatcher);
      });
      /**
       * Emitted whenever a stream dispatcher subscribes to the broadcast.
       * @event VoiceBroadcast#subscribe
       * @param {StreamDispatcher} dispatcher The subscribed dispatcher
       */
      this.emit('subscribe', dispatcher);
    }
  }

  killCurrentTranscoder() {
    if (this.currentTranscoder) {
      if (this.currentTranscoder.transcoder) this.currentTranscoder.transcoder.kill();
      this.currentTranscoder = null;
      this.emit('end');
    }
  }

  /**
   * Plays any audio stream across the broadcast.
   * @param {ReadableStream} stream The audio stream to play
   * @param {StreamOptions} [options] Options for playing the stream
   * @returns {VoiceBroadcast}
   * @example
   * // Play streams using ytdl-core
   * const ytdl = require('ytdl-core');
   * const streamOptions = { seek: 0, volume: 1 };
   * const broadcast = client.createVoiceBroadcast();
   *
   * voiceChannel.join()
   *  .then(connection => {
   *    const stream = ytdl('https://www.youtube.com/watch?v=XAWgeLF9EVQ', { filter : 'audioonly' });
   *    broadcast.playStream(stream);
   *    const dispatcher = connection.playBroadcast(broadcast);
   *  })
   *  .catch(console.error);
   */
  playStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) {
    const options = { seek, volume, passes, stream };
    return this._playTranscodable(stream, options);
  }

  /**
   * Play the given file in the voice connection.
   * @param {string} file The absolute path to the file
   * @param {StreamOptions} [options] Options for playing the stream
   * @returns {StreamDispatcher}
   * @example
   * // Play files natively
   * const broadcast = client.createVoiceBroadcast();
   *
   * voiceChannel.join()
   *  .then(connection => {
   *    broadcast.playFile('C:/Users/Discord/Desktop/music.mp3');
   *    const dispatcher = connection.playBroadcast(broadcast);
   *  })
   *  .catch(console.error);
   */
  playFile(file, { seek = 0, volume = 1, passes = 1 } = {}) {
    const options = { seek, volume, passes };
    return this._playTranscodable(`file:${file}`, options);
  }

  _playTranscodable(media, options) {
    OpusEncoders.guaranteeOpusEngine();

    this.killCurrentTranscoder();
    const transcoder = this.prism.transcode({
      type: 'ffmpeg',
      media,
      ffmpegArguments: ffmpegArguments.concat(['-ss', String(options.seek)]),
    });
    /**
     * Emitted whenever an error occurs.
     * @event VoiceBroadcast#error
     * @param {Error} error The error that occurred
     */
    transcoder.once('error', e => {
      if (this.listenerCount('error') > 0) this.emit('error', e);
      /**
       * Emitted whenever the VoiceBroadcast has any warnings.
       * @event VoiceBroadcast#warn
       * @param {string|Error} warning The warning that was raised
       */
      else this.emit('warn', e);
    });
    /**
     * Emitted once the broadcast (the audio stream) ends.
     * @event VoiceBroadcast#end
     */
    transcoder.once('end', () => this.killCurrentTranscoder());
    this.currentTranscoder = {
      transcoder,
      options,
    };
    transcoder.output.once('readable', () => this._startPlaying());
    return this;
  }

  /**
   * Plays a stream of 16-bit signed stereo PCM at 48KHz.
   * @param {ReadableStream} stream The audio stream to play
   * @param {StreamOptions} [options] Options for playing the stream
   * @returns {VoiceBroadcast}
   */
  playConvertedStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) {
    OpusEncoders.guaranteeOpusEngine();

    this.killCurrentTranscoder();
    const options = { seek, volume, passes, stream };
    this.currentTranscoder = { options };
    stream.once('readable', () => this._startPlaying());
    return this;
  }

  /**
   * Plays an Opus encoded stream at 48KHz.
   * <warn>Note that inline volume is not compatible with this method.</warn>
   * @param {ReadableStream} stream The Opus audio stream to play
   * @param {StreamOptions} [options] Options for playing the stream
   * @returns {StreamDispatcher}
   */
  playOpusStream(stream, { seek = 0, passes = 1 } = {}) {
    const options = { seek, passes, stream };
    this.currentTranscoder = { options, opus: true };
    stream.once('readable', () => this._startPlaying());
    return this;
  }

  /**
   * Play an arbitrary input that can be [handled by ffmpeg](https://ffmpeg.org/ffmpeg-protocols.html#Description)
   * @param {string} input The arbitrary input
   * @param {StreamOptions} [options] Options for playing the stream
   * @returns {VoiceBroadcast}
   */
  playArbitraryInput(input, { seek = 0, volume = 1, passes = 1 } = {}) {
    this.guaranteeOpusEngine();

    const options = { seek, volume, passes, input };
    return this._playTranscodable(input, options);
  }

  /**
   * Pauses the entire broadcast - all dispatchers also pause.
   */
  pause() {
    this.paused = true;
    for (const container of this._dispatchers.values()) {
      for (const dispatcher of container.values()) {
        dispatcher.pause();
      }
    }
  }

  /**
   * Resumes the entire broadcast - all dispatchers also resume.
   */
  resume() {
    this.paused = false;
    for (const container of this._dispatchers.values()) {
      for (const dispatcher of container.values()) {
        dispatcher.resume();
      }
    }
  }

  guaranteeOpusEngine() {
    if (!this.opusEncoder) throw new Error('Couldn\'t find an Opus engine.');
  }

  _startPlaying() {
    if (this.tickInterval) clearInterval(this.tickInterval);
    // Old code?
    // this.tickInterval = this.client.setInterval(this.tick.bind(this), 20);
    this._startTime = Date.now();
    this._count = 0;
    this._pausedTime = 0;
    this._missed = 0;
    this.tick();
  }

  tick() {
    if (!this._playableStream) return;
    if (this.paused) {
      this._pausedTime += 20;
      setTimeout(() => this.tick(), 20);
      return;
    }

    const opus = this.currentTranscoder.opus;
    const buffer = this.readStreamBuffer();

    if (!buffer) {
      this._missed++;
      if (this._missed < 5) {
        this._pausedTime += 200;
        setTimeout(() => this.tick(), 200);
      } else {
        this.killCurrentTranscoder();
      }
      return;
    }

    this._missed = 0;

    let packetMatrix = {};

    const getOpusPacket = volume => {
      if (packetMatrix[volume]) return packetMatrix[volume];

      const opusEncoder = this._encoders.get(volume);
      const opusPacket = opusEncoder.encode(this.applyVolume(buffer, this._volume * volume));
      packetMatrix[volume] = opusPacket;
      return opusPacket;
    };

    for (const dispatcher of this.dispatchers) {
      if (opus) {
        dispatcher.processPacket(buffer);
        continue;
      }

      const volume = dispatcher.volume;
      dispatcher.processPacket(getOpusPacket(volume));
    }

    const next = 20 + (this._startTime + this._pausedTime + (this._count * 20) - Date.now());
    this._count++;
    setTimeout(() => this.tick(), next);
  }

  readStreamBuffer() {
    const opus = this.currentTranscoder.opus;
    const bufferLength = (opus ? 80 : 1920) * 2;
    let buffer = this._playableStream.read(bufferLength);
    if (opus) return buffer;
    if (!buffer) return null;

    if (buffer.length !== bufferLength) {
      const newBuffer = Buffer.alloc(bufferLength).fill(0);
      buffer.copy(newBuffer);
      buffer = newBuffer;
    }

    return buffer;
  }

  /**
   * Stop the current stream from playing without unsubscribing dispatchers.
   */
  end() {
    this.killCurrentTranscoder();
  }

  /**
   * End the current broadcast, all subscribed dispatchers will also end.
   */
  destroy() {
    this.end();
    for (const container of this._dispatchers.values()) {
      for (const dispatcher of container.values()) {
        dispatcher.destroy('end', 'broadcast ended');
      }
    }
  }
}

module.exports = VoiceBroadcast;
<commit_msg>Remove unused VoiceBroadcast#guaranteeOpusEngine (fixes #1556) (#1563)<commit_after>const VolumeInterface = require('./util/VolumeInterface');
const Prism = require('prism-media');
const OpusEncoders = require('./opus/OpusEngineList');
const Collection = require('../../util/Collection');

const ffmpegArguments = [
  '-analyzeduration', '0',
  '-loglevel', '0',
  '-f', 's16le',
  '-ar', '48000',
  '-ac', '2',
];

/**
 * A voice broadcast can be played across multiple voice connections for improved shared-stream efficiency.
 *
 * Example usage:
 * ```js
 * const broadcast = client.createVoiceBroadcast();
 * broadcast.playFile('./music.mp3');
 * // play "music.mp3" in all voice connections that the client is in
 * for (const connection of client.voiceConnections.values()) {
 *   connection.playBroadcast(broadcast);
 * }
 * ```
 * @implements {VolumeInterface}
 */
class VoiceBroadcast extends VolumeInterface {
  constructor(client) {
    super();
    /**
     * The client that created the broadcast
     * @type {Client}
     */
    this.client = client;
    this._dispatchers = new Collection();
    this._encoders = new Collection();
    /**
     * The audio transcoder that this broadcast uses
     * @type {Prism}
     */
    this.prism = new Prism();
    /**
     * The current audio transcoder that is being used
     * @type {Object}
     */
    this.currentTranscoder = null;
    this.tickInterval = null;
    this._volume = 1;
  }

  /**
   * An array of subscribed dispatchers
   * @type {StreamDispatcher[]}
   * @readonly
   */
  get dispatchers() {
    let d = [];
    for (const container of this._dispatchers.values()) {
      d = d.concat(Array.from(container.values()));
    }
    return d;
  }

  get _playableStream() {
    const currentTranscoder = this.currentTranscoder;
    if (!currentTranscoder) return null;
    const transcoder = currentTranscoder.transcoder;
    const options = currentTranscoder.options;
    return (transcoder && transcoder.output) || options.stream;
  }

  unregisterDispatcher(dispatcher, old) {
    const volume = old || dispatcher.volume;

    /**
     * Emitted whenever a stream dispatcher unsubscribes from the broadcast.
     * @event VoiceBroadcast#unsubscribe
     * @param {StreamDispatcher} dispatcher The unsubscribed dispatcher
     */
    this.emit('unsubscribe', dispatcher);
    for (const container of this._dispatchers.values()) {
      container.delete(dispatcher);

      if (!container.size) {
        this._encoders.get(volume).destroy();
        this._dispatchers.delete(volume);
        this._encoders.delete(volume);
      }
    }
  }

  registerDispatcher(dispatcher) {
    if (!this._dispatchers.has(dispatcher.volume)) {
      this._dispatchers.set(dispatcher.volume, new Set());
      this._encoders.set(dispatcher.volume, OpusEncoders.fetch());
    }
    const container = this._dispatchers.get(dispatcher.volume);
    if (!container.has(dispatcher)) {
      container.add(dispatcher);
      dispatcher.once('end', () => this.unregisterDispatcher(dispatcher));
      dispatcher.on('volumeChange', (o, n) => {
        this.unregisterDispatcher(dispatcher, o);
        if (!this._dispatchers.has(n)) {
          this._dispatchers.set(n, new Set());
          this._encoders.set(n, OpusEncoders.fetch());
        }
        this._dispatchers.get(n).add(dispatcher);
      });
      /**
       * Emitted whenever a stream dispatcher subscribes to the broadcast.
       * @event VoiceBroadcast#subscribe
       * @param {StreamDispatcher} dispatcher The subscribed dispatcher
       */
      this.emit('subscribe', dispatcher);
    }
  }

  killCurrentTranscoder() {
    if (this.currentTranscoder) {
      if (this.currentTranscoder.transcoder) this.currentTranscoder.transcoder.kill();
      this.currentTranscoder = null;
      this.emit('end');
    }
  }

  /**
   * Plays any audio stream across the broadcast.
   * @param {ReadableStream} stream The audio stream to play
   * @param {StreamOptions} [options] Options for playing the stream
   * @returns {VoiceBroadcast}
   * @example
   * // Play streams using ytdl-core
   * const ytdl = require('ytdl-core');
   * const streamOptions = { seek: 0, volume: 1 };
   * const broadcast = client.createVoiceBroadcast();
   *
   * voiceChannel.join()
   *  .then(connection => {
   *    const stream = ytdl('https://www.youtube.com/watch?v=XAWgeLF9EVQ', { filter : 'audioonly' });
   *    broadcast.playStream(stream);
   *    const dispatcher = connection.playBroadcast(broadcast);
   *  })
   *  .catch(console.error);
   */
  playStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) {
    const options = { seek, volume, passes, stream };
    return this._playTranscodable(stream, options);
  }

  /**
   * Play the given file in the voice connection.
   * @param {string} file The absolute path to the file
   * @param {StreamOptions} [options] Options for playing the stream
   * @returns {StreamDispatcher}
   * @example
   * // Play files natively
   * const broadcast = client.createVoiceBroadcast();
   *
   * voiceChannel.join()
   *  .then(connection => {
   *    broadcast.playFile('C:/Users/Discord/Desktop/music.mp3');
   *    const dispatcher = connection.playBroadcast(broadcast);
   *  })
   *  .catch(console.error);
   */
  playFile(file, { seek = 0, volume = 1, passes = 1 } = {}) {
    const options = { seek, volume, passes };
    return this._playTranscodable(`file:${file}`, options);
  }

  _playTranscodable(media, options) {
    OpusEncoders.guaranteeOpusEngine();

    this.killCurrentTranscoder();
    const transcoder = this.prism.transcode({
      type: 'ffmpeg',
      media,
      ffmpegArguments: ffmpegArguments.concat(['-ss', String(options.seek)]),
    });
    /**
     * Emitted whenever an error occurs.
     * @event VoiceBroadcast#error
     * @param {Error} error The error that occurred
     */
    transcoder.once('error', e => {
      if (this.listenerCount('error') > 0) this.emit('error', e);
      /**
       * Emitted whenever the VoiceBroadcast has any warnings.
       * @event VoiceBroadcast#warn
       * @param {string|Error} warning The warning that was raised
       */
      else this.emit('warn', e);
    });
    /**
     * Emitted once the broadcast (the audio stream) ends.
     * @event VoiceBroadcast#end
     */
    transcoder.once('end', () => this.killCurrentTranscoder());
    this.currentTranscoder = {
      transcoder,
      options,
    };
    transcoder.output.once('readable', () => this._startPlaying());
    return this;
  }

  /**
   * Plays a stream of 16-bit signed stereo PCM at 48KHz.
   * @param {ReadableStream} stream The audio stream to play
   * @param {StreamOptions} [options] Options for playing the stream
   * @returns {VoiceBroadcast}
   */
  playConvertedStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) {
    OpusEncoders.guaranteeOpusEngine();

    this.killCurrentTranscoder();
    const options = { seek, volume, passes, stream };
    this.currentTranscoder = { options };
    stream.once('readable', () => this._startPlaying());
    return this;
  }

  /**
   * Plays an Opus encoded stream at 48KHz.
   * <warn>Note that inline volume is not compatible with this method.</warn>
   * @param {ReadableStream} stream The Opus audio stream to play
   * @param {StreamOptions} [options] Options for playing the stream
   * @returns {StreamDispatcher}
   */
  playOpusStream(stream, { seek = 0, passes = 1 } = {}) {
    const options = { seek, passes, stream };
    this.currentTranscoder = { options, opus: true };
    stream.once('readable', () => this._startPlaying());
    return this;
  }

  /**
   * Play an arbitrary input that can be [handled by ffmpeg](https://ffmpeg.org/ffmpeg-protocols.html#Description)
   * @param {string} input The arbitrary input
   * @param {StreamOptions} [options] Options for playing the stream
   * @returns {VoiceBroadcast}
   */
  playArbitraryInput(input, { seek = 0, volume = 1, passes = 1 } = {}) {
    const options = { seek, volume, passes, input };
    return this._playTranscodable(input, options);
  }

  /**
   * Pauses the entire broadcast - all dispatchers also pause.
   */
  pause() {
    this.paused = true;
    for (const container of this._dispatchers.values()) {
      for (const dispatcher of container.values()) {
        dispatcher.pause();
      }
    }
  }

  /**
   * Resumes the entire broadcast - all dispatchers also resume.
   */
  resume() {
    this.paused = false;
    for (const container of this._dispatchers.values()) {
      for (const dispatcher of container.values()) {
        dispatcher.resume();
      }
    }
  }

  _startPlaying() {
    if (this.tickInterval) clearInterval(this.tickInterval);
    // Old code?
    // this.tickInterval = this.client.setInterval(this.tick.bind(this), 20);
    this._startTime = Date.now();
    this._count = 0;
    this._pausedTime = 0;
    this._missed = 0;
    this.tick();
  }

  tick() {
    if (!this._playableStream) return;
    if (this.paused) {
      this._pausedTime += 20;
      setTimeout(() => this.tick(), 20);
      return;
    }

    const opus = this.currentTranscoder.opus;
    const buffer = this.readStreamBuffer();

    if (!buffer) {
      this._missed++;
      if (this._missed < 5) {
        this._pausedTime += 200;
        setTimeout(() => this.tick(), 200);
      } else {
        this.killCurrentTranscoder();
      }
      return;
    }

    this._missed = 0;

    let packetMatrix = {};

    const getOpusPacket = volume => {
      if (packetMatrix[volume]) return packetMatrix[volume];

      const opusEncoder = this._encoders.get(volume);
      const opusPacket = opusEncoder.encode(this.applyVolume(buffer, this._volume * volume));
      packetMatrix[volume] = opusPacket;
      return opusPacket;
    };

    for (const dispatcher of this.dispatchers) {
      if (opus) {
        dispatcher.processPacket(buffer);
        continue;
      }

      const volume = dispatcher.volume;
      dispatcher.processPacket(getOpusPacket(volume));
    }

    const next = 20 + (this._startTime + this._pausedTime + (this._count * 20) - Date.now());
    this._count++;
    setTimeout(() => this.tick(), next);
  }

  readStreamBuffer() {
    const opus = this.currentTranscoder.opus;
    const bufferLength = (opus ? 80 : 1920) * 2;
    let buffer = this._playableStream.read(bufferLength);
    if (opus) return buffer;
    if (!buffer) return null;

    if (buffer.length !== bufferLength) {
      const newBuffer = Buffer.alloc(bufferLength).fill(0);
      buffer.copy(newBuffer);
      buffer = newBuffer;
    }

    return buffer;
  }

  /**
   * Stop the current stream from playing without unsubscribing dispatchers.
   */
  end() {
    this.killCurrentTranscoder();
  }

  /**
   * End the current broadcast, all subscribed dispatchers will also end.
   */
  destroy() {
    this.end();
    for (const container of this._dispatchers.values()) {
      for (const dispatcher of container.values()) {
        dispatcher.destroy('end', 'broadcast ended');
      }
    }
  }
}

module.exports = VoiceBroadcast;
<|endoftext|>


<commit_before>var _ = require('../util')
var Watcher = require('../watcher')

/**
 * Possible permutations:
 *
 * - literal:
 *   v-component="comp"
 *
 * - dynamic:
 *   v-component="{{currentView}}"
 *
 * - conditional:
 *   v-component="comp" v-if="abc"
 *
 * - dynamic + conditional:
 *   v-component="{{currentView}}" v-if="abc"
 *
 */

module.exports = {

  isLiteral: true,

  bind: function () {
    if (!this.el.__vue__) {
      // create a ref anchor
      this.ref = document.createComment('v-component')
      _.before(this.ref, this.el)
      _.remove(this.el)
      // check v-if conditionals
      this.checkIf()
      // if static, build right now.
      if (!this._isDynamicLiteral) {
        this.resolveCtor(this.expression)
        this.build()
      }
    } else {
      _.warn(
        'v-component ' + this.expression + ' cannot be ' +
        'used on an already mounted instance.'
      )
    }
  },

  checkIf: function () {
    var condition = _.attr(this.el, 'if')
    if (condition !== null) {
      this.ifWatcher = new Watcher(
        this.vm,
        condition,
        this.ifCallback,
        this
      )
      this.active = this.ifWatcher.value
    } else {
      this.active = true
    }
  },

  ifCallback: function (value) {
    if (value) {
      this.active = true
      this.build()
    } else {
      this.active = false
      this.unbuild(true)
    }
  },

  resolveCtor: function (id) {
    var registry = this.vm.$options.components
    this.Ctor = registry[id]
    if (!this.Ctor) {
      _.warn('Failed to resolve component: ' + id)
    }
  },

  build: function () {
    if (this.active && this.Ctor && !this.childVM) {
      this.childVM = new this.Ctor({
        el: this.el.cloneNode(true),
        parent: this.vm
      })
      this.childVM.$before(this.ref)
    }
  },

  unbuild: function (remove) {
    if (this.childVM) {
      this.childVM.$destroy(remove)
      this.childVM = null
    }
  },

  update: function (value) {
    this.unbuild(true)
    if (value) {
      this.resolveCtor(value)
      this.build()
    }
  },

  unbind: function () {
    this.unbuild()
    if (this.ifWatcher) {
      this.ifWatcher.teardown()
    }
  }

}<commit_msg>keep-alive option for v-component<commit_after>var _ = require('../util')
var Watcher = require('../watcher')

module.exports = {

  isLiteral: true,

  /**
   * Setup. Need to check a few possible permutations:
   *
   * - literal:
   *   v-component="comp"
   *
   * - dynamic:
   *   v-component="{{currentView}}"
   *
   * - conditional:
   *   v-component="comp" v-if="abc"
   *
   * - dynamic + conditional:
   *   v-component="{{currentView}}" v-if="abc"
   */

  bind: function () {
    if (!this.el.__vue__) {
      // create a ref anchor
      this.ref = document.createComment('v-component')
      _.before(this.ref, this.el)
      _.remove(this.el)
      // check v-if conditionals
      this.checkIf()
      // check keep-alive options
      this.checkKeepAlive()
      // if static, build right now.
      if (!this._isDynamicLiteral) {
        this.resolveCtor(this.expression)
        this.build()
      }
    } else {
      _.warn(
        'v-component ' + this.expression + ' cannot be ' +
        'used on an already mounted instance.'
      )
    }
  },

  /**
   * Check if v-component is being used together with v-if.
   * If yes, we created a watcher for the v-if value and
   * react to its value change in `this.ifCallback`.
   */

  checkIf: function () {
    var condition = _.attr(this.el, 'if')
    if (condition !== null) {
      this.ifWatcher = new Watcher(
        this.vm,
        condition,
        this.ifCallback,
        this
      )
      this.active = this.ifWatcher.value
    } else {
      this.active = true
    }
  },

  /**
   * Callback when v-if value changes.
   * Marks the active flag.
   *
   * @param {*} value
   */

  ifCallback: function (value) {
    if (value) {
      this.active = true
      this.build()
    } else {
      this.active = false
      this.unbuild(true)
    }
  },

  /**
   * Check if the "keep-alive" flag is present.
   * If yes, instead of destroying the active vm when
   * hiding (v-if) or switching (dynamic literal) it,
   * we simply remove it from the DOM and save it in a
   * cache object, with its constructor id as the key.
   */

  checkKeepAlive: function () {
    // check keep-alive flag
    this.keepAlive = this.el.hasAttribute('keep-alive')
    if (this.keepAlive) {
      this.cache = Object.create(null)
    }
  },

  /**
   * Resolve the component constructor to use when creating
   * the child vm. If the component id is empty string, the
   * default 'Vue' constructor will be used.
   */

  resolveCtor: function (id) {
    if (id === '') {
      this.id = '__vue__'
      this.Ctor = _.Vue
    } else {
      this.id = id
      this.Ctor = this.vm.$options.components[id]
      if (!this.Ctor) {
        _.warn('Failed to resolve component: ' + id)
      }
    }
  },

  /**
   * Instantiate/insert a new child vm.
   * If keep alive and has cached instance, insert that
   * instance; otherwise build a new one and cache it.
   */

  build: function () {
    if (!this.active) {
      return
    }
    if (this.keepAlive) {
      var vm = this.cache[this.id]
      if (vm) {
        this.childVM = vm
        vm.$before(this.ref)
        return
      }
    }
    if (this.Ctor && !this.childVM) {
      this.childVM = new this.Ctor({
        el: this.el.cloneNode(true),
        parent: this.vm
      })
      this.cache[this.id] = this.childVM
      this.childVM.$before(this.ref)
    }
  },

  /**
   * Teardown the active vm.
   * If keep alive, simply remove it; otherwise destroy it.
   *
   * @param {Boolean} remove
   */

  unbuild: function (remove) {
    if (!this.childVM) {
      return
    }
    if (this.keepAlive) {
      if (remove) {
        this.childVM.$remove()
      }
    } else {
      this.childVM.$destroy(remove)
    }
    this.childVM = null
  },

  /**
   * Update callback for the dynamic literal scenario,
   * e.g. v-component="{{view}}"
   */

  update: function (value) {
    this.unbuild(true)
    if (value) {
      this.resolveCtor(value)
      this.build()
    }
  },

  /**
   * Unbind.
   * Make sure keepAlive is set to false so that the
   * instance is always destroyed. Teardown v-if watcher
   * if present.
   */

  unbind: function () {
    this.keepAlive = false
    this.unbuild()
    if (this.ifWatcher) {
      this.ifWatcher.teardown()
    }
  }

}<|endoftext|>


<commit_before>class Dock {

    static getSide(el) {

        return $(el).parent().attr('class').split(' ')[2];

    }

    static getNodeId(el) {

        return $(el).parents('.container').attr('class').split(' ')[1];

    }

    static getId(el) {

        return $(el).parents('.parameter').attr('class').split(' ')[1]

    }

}
<commit_msg>removed unused class dock.js<commit_after><|endoftext|>