<commit_before>/*******************************************************************************
Open Source Initiative OSI - The MIT License (MIT):Licensing
[OSI Approved License]
The MIT License (MIT)

Copyright (c) Sean McGregor

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

*******************************************************************************/

/******************************************************************************
Transforming the Greasemonkey userscript to extension javascript should be fairly straight forward -
       Copy the greasemonkey userscript(privateweb.user.js) and paste it into privly.js.
       Change all '$' references to 'jQ'.
******************************************************************************/

var privly = {

  //Matches:
  //              http://
  //              https://
  //                        priv.ly/textAndNumbers/any/number/of/times
  //
  //also matches localhost:3000
  privlyReferencesRegex: /\b(https?:\/\/){0,1}(priv\.ly|localhost:3000)(\/\w*){2,}\b/gi,

  // Takes a domain with an optional http(s) in front and returns a fully formed domain name
  makeHref: function(domain)
  {
    var hasHTTPRegex = /^((https?)\:\/\/)/i
    if(!hasHTTPRegex.test(domain))
        domain = "http://" + domain;
    return domain;
  },

  //Make plain text links into anchor elements
  createLinks: function()
  {
      /*************************************************************************
      Inspired by Linkify script:
        http://downloads.mozdev.org/greasemonkey/linkify.user.js

      Originally written by Anthony Lieuallen of http://arantius.com/
      Licensed for unlimited modification and redistribution as long as
      this notice is kept intact.
      **************************************************************************/

      var excludeParents = ["a", "applet", "button", "code", "form",
                             "input", "option", "script", "select", "meta",
                             "style", "textarea", "title"];
      var excludedParentsString = excludeParents.join(" or parent::");
      var xpathExpression = ".//text()[not(parent:: " + excludedParentsString +")]";

      textNodes = document.evaluate(xpathExpression, document.body, null,
                                    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);

      for(var i=0; i < textNodes.snapshotLength; i++){
          item = textNodes.snapshotItem(i);

          var itemText = item.nodeValue;

          if(privly.privlyReferencesRegex.test(itemText)){
              var span = document.createElement("span");
              var lastLastIndex = 0;
              privly.privlyReferencesRegex.lastIndex = 0;
              for(var results = null; results = privly.privlyReferencesRegex.exec(itemText); ){
                  var href = results[0];
                  span.appendChild(document.createTextNode(itemText.substring(lastLastIndex, results.index)));

                  var text = (href.indexOf(" ")==0)?href.substring(1):href;

                  var href = privly.makeHref(text);

                  var a = document.createElement("a");
                  a.setAttribute("href", href);
                  a.appendChild(document.createTextNode(text.substring(0,4).toLowerCase()+text.substring(4)));
                  if(href.indexOf(" ")==0)
                      span.appendChild(document.createTextNode(" "));
                  span.appendChild(a);
                  lastLastIndex = privly.privlyReferencesRegex.lastIndex;
              }
              span.appendChild(document.createTextNode(itemText.substring(lastLastIndex)));
              item.parentNode.replaceChild(span, item);
          }
      }
  },

  //Checks link attributes and text for privly links without the proper href attribute.
  //Twitter and other hosts change links so they can collect click events.
  correctIndirection: function()
  {
    var allLinks = jQ("a");
    allLinks.each(function() {
        thisLink = jQ(this);
        linkBody = thisLink.html();
        if (privly.privlyReferencesRegex.test(linkBody)) {
          var href = thisLink.attr("href");
          // If the href is not present or is on a different domain
          if(href.indexOf("priv.ly/posts/") == -1 || href.indexOf("priv.ly/posts/") > 9)
          {
            privly.privlyReferencesRegex.lastIndex = 0;
            var results = privly.privlyReferencesRegex.exec(linkBody);
            var newHref = privly.makeHref(results[0]);
            thisLink.attr("href", newHref);
          }
        }
    });
  },

  nextAvailableFrameID: 0,

  // Replace a jQuery anchor element with its referenced content.
  replaceLink: function(currentObject)
  {

    var linkUrl = currentObject.attr("href");
    var postId = linkUrl.substr(linkUrl.indexOf("/posts")+7);

    iframe = jQ('<iframe />', {"frameborder":"0",
      "vspace":"0",
      "hspace":"0",
      "name":"privlyiframe",
      "width":"100%",
      "marginwidth":"0",
      "marginheight":"0",
      "src":linkUrl + ".iframe?frame_id=" + privly.nextAvailableFrameID,
      "id":"ifrm"+privly.nextAvailableFrameID});
    privly.nextAvailableFrameID++;
    iframe.attr('scrolling','no');
    iframe.css('overflow','hidden');
    currentObject.replaceWith(iframe);
  },

  // This jquery selection string selects anchor elements
  // that point to the posts controller in the Web Application.
  selectors: 'a[href^="https://priv.ly/posts/"],'+
                   'a[href^="http://priv.ly/posts/"],'+
                   'a[href^="http://localhost:3000/posts/"]',

  //Replace Privly links with their iframe
  replaceLinks: function(){

    //don't recursively replace links
    if(document.URL.indexOf('priv.ly') != -1 )
      return;

    jQ(privly.selectors).each(function() {
      var exclude = jQ(this).attr("privly");
      if(exclude != "exclude")
      {
        privly.replaceLink(jQ(this));
      }
    });
  },

  /* we want to execute the function replaceLinks() that is defined in privly.js(which is loaded on the webpage, hence it is part of
  the web page) from privly-setup.js(which is part of the extension). We want to run replaceLinks whenever the user tries to run
  the extension either via key press or by mouse click.
  There is no straight way of calling a function defined on the web page from an extension. A hack for this is to add a HTML element
  (in this case a button) to the page and to call the required function(here replaceLinks) on the button's click/mousedown.
  It is possible to simulate click/mousedown on any HTML element from the extension as content.document is available to the extension.
  refer - http://stackoverflow.com/a/2896066
   */

  addPWbutton: function(){
    var pwbutton = '<input type="button" id="pwbtn" style="visibility:hidden;" onclick="replaceLinks()" />';
    jQ('body').append(pwbutton);
  },

  resizeIframe: function(evt){
    //do nothing. Actual implementation is in privly-setup.js
  }
};

jQ(document).ready(function(){

  if(document.URL.indexOf('localhost:3000') == -1 && document.URL.indexOf('priv.ly') == -1){
    privly.addPWbutton();
  }

  privly.createLinks();
  privly.correctIndirection();
  privly.replaceLinks();//replace all available links on load

  //replace all links whenever the page is clicked in the body
  jQ("body").live('click', function() {
    privly.createLinks();
    privly.correctIndirection();
    privly.replaceLinks();
  });

  //replace the clicked link only, the link must be prepped with
  //calls to privly.createLinks() and privly.correctIndirection()
  //jQ(privly.selectors).live('click', function(event) {
  //  event.preventDefault();
  //  privly.replaceLink(jQ(this));
  //});

  if(document.URL.indexOf('localhost:3000') == -1 && document.URL.indexOf('priv.ly') == -1)
  {
    window.addEventListener("IframeResizeEvent", function(e) { privly.resizeIframe(e); }, false, true);
  }
});
<commit_msg>removed reference to Greasemonkey from extension<commit_after>/*******************************************************************************
Open Source Initiative OSI - The MIT License (MIT):Licensing
[OSI Approved License]
The MIT License (MIT)

Copyright (c) Sean McGregor

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

*******************************************************************************/

var privly = {

  //Matches:
  //              http://
  //              https://
  //                        priv.ly/textAndNumbers/any/number/of/times
  //
  //also matches localhost:3000
  privlyReferencesRegex: /\b(https?:\/\/){0,1}(priv\.ly|localhost:3000)(\/\w*){2,}\b/gi,

  // Takes a domain with an optional http(s) in front and returns a fully formed domain name
  makeHref: function(domain)
  {
    var hasHTTPRegex = /^((https?)\:\/\/)/i
    if(!hasHTTPRegex.test(domain))
        domain = "http://" + domain;
    return domain;
  },

  //Make plain text links into anchor elements
  createLinks: function()
  {
      /*************************************************************************
      Inspired by Linkify script:
        http://downloads.mozdev.org/greasemonkey/linkify.user.js

      Originally written by Anthony Lieuallen of http://arantius.com/
      Licensed for unlimited modification and redistribution as long as
      this notice is kept intact.
      **************************************************************************/

      var excludeParents = ["a", "applet", "button", "code", "form",
                             "input", "option", "script", "select", "meta",
                             "style", "textarea", "title"];
      var excludedParentsString = excludeParents.join(" or parent::");
      var xpathExpression = ".//text()[not(parent:: " + excludedParentsString +")]";

      textNodes = document.evaluate(xpathExpression, document.body, null,
                                    XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);

      for(var i=0; i < textNodes.snapshotLength; i++){
          item = textNodes.snapshotItem(i);

          var itemText = item.nodeValue;

          if(privly.privlyReferencesRegex.test(itemText)){
              var span = document.createElement("span");
              var lastLastIndex = 0;
              privly.privlyReferencesRegex.lastIndex = 0;
              for(var results = null; results = privly.privlyReferencesRegex.exec(itemText); ){
                  var href = results[0];
                  span.appendChild(document.createTextNode(itemText.substring(lastLastIndex, results.index)));

                  var text = (href.indexOf(" ")==0)?href.substring(1):href;

                  var href = privly.makeHref(text);

                  var a = document.createElement("a");
                  a.setAttribute("href", href);
                  a.appendChild(document.createTextNode(text.substring(0,4).toLowerCase()+text.substring(4)));
                  if(href.indexOf(" ")==0)
                      span.appendChild(document.createTextNode(" "));
                  span.appendChild(a);
                  lastLastIndex = privly.privlyReferencesRegex.lastIndex;
              }
              span.appendChild(document.createTextNode(itemText.substring(lastLastIndex)));
              item.parentNode.replaceChild(span, item);
          }
      }
  },

  //Checks link attributes and text for privly links without the proper href attribute.
  //Twitter and other hosts change links so they can collect click events.
  correctIndirection: function()
  {
    var allLinks = jQ("a");
    allLinks.each(function() {
        thisLink = jQ(this);
        linkBody = thisLink.html();
        if (privly.privlyReferencesRegex.test(linkBody)) {
          var href = thisLink.attr("href");
          // If the href is not present or is on a different domain
          if(href.indexOf("priv.ly/posts/") == -1 || href.indexOf("priv.ly/posts/") > 9)
          {
            privly.privlyReferencesRegex.lastIndex = 0;
            var results = privly.privlyReferencesRegex.exec(linkBody);
            var newHref = privly.makeHref(results[0]);
            thisLink.attr("href", newHref);
          }
        }
    });
  },

  nextAvailableFrameID: 0,

  // Replace a jQuery anchor element with its referenced content.
  replaceLink: function(currentObject)
  {

    var linkUrl = currentObject.attr("href");
    var postId = linkUrl.substr(linkUrl.indexOf("/posts")+7);

    iframe = jQ('<iframe />', {"frameborder":"0",
      "vspace":"0",
      "hspace":"0",
      "name":"privlyiframe",
      "width":"100%",
      "marginwidth":"0",
      "marginheight":"0",
      "height":"1px",
      "src":linkUrl + ".iframe?frame_id=" + privly.nextAvailableFrameID,
      "id":"ifrm"+privly.nextAvailableFrameID});
    privly.nextAvailableFrameID++;
    iframe.attr('scrolling','no');
    iframe.css('overflow','hidden');
    currentObject.replaceWith(iframe);
  },

  // This jquery selection string selects anchor elements
  // that point to the posts controller in the Web Application.
  selectors: 'a[href^="https://priv.ly/posts/"],'+
                   'a[href^="http://priv.ly/posts/"],'+
                   'a[href^="http://localhost:3000/posts/"]',

  //Replace Privly links with their iframe
  replaceLinks: function(){

    //don't recursively replace links
    if(document.URL.indexOf('priv.ly') != -1 )
      return;

    jQ(privly.selectors).each(function() {
      var exclude = jQ(this).attr("privly");
      if(exclude != "exclude")
      {
        privly.replaceLink(jQ(this));
      }
    });
  },

  /* we want to execute the function replaceLinks() that is defined in privly.js(which is loaded on the webpage, hence it is part of
  the web page) from privly-setup.js(which is part of the extension). We want to run replaceLinks whenever the user tries to run
  the extension either via key press or by mouse click.
  There is no straight way of calling a function defined on the web page from an extension. A hack for this is to add a HTML element
  (in this case a button) to the page and to call the required function(here replaceLinks) on the button's click/mousedown.
  It is possible to simulate click/mousedown on any HTML element from the extension as content.document is available to the extension.
  refer - http://stackoverflow.com/a/2896066
   */

  addPWbutton: function(){
    var pwbutton = '<input type="button" id="pwbtn" style="visibility:hidden;" onclick="replaceLinks()" />';
    jQ('body').append(pwbutton);
  },

  resizeIframe: function(evt){
    //do nothing. Actual implementation is in privly-setup.js
  }
};

jQ(document).ready(function(){

  if(document.URL.indexOf('localhost:3000') == -1 && document.URL.indexOf('priv.ly') == -1){
    privly.addPWbutton();
  }

  privly.createLinks();
  privly.correctIndirection();
  privly.replaceLinks();//replace all available links on load

  //replace all links whenever the page is clicked in the body
  jQ("body").live('click', function() {
    privly.createLinks();
    privly.correctIndirection();
    privly.replaceLinks();
  });

  //replace the clicked link only, the link must be prepped with
  //calls to privly.createLinks() and privly.correctIndirection()
  //jQ(privly.selectors).live('click', function(event) {
  //  event.preventDefault();
  //  privly.replaceLink(jQ(this));
  //});

  if(document.URL.indexOf('localhost:3000') == -1 && document.URL.indexOf('priv.ly') == -1)
  {
    window.addEventListener("IframeResizeEvent", function(e) { privly.resizeIframe(e); }, false, true);
  }
});
<|endoftext|>


<commit_before>'use strict';

Connector.playerSelector = '.now-playing-box';

Connector.artistSelector = '#np-artist';

Connector.trackSelector = '#np-title';
<commit_msg>Delta Radio UK: force DOM change on ready<commit_after>'use strict';

Connector.playerSelector = '.now-playing-box';

Connector.artistSelector = '#np-artist';

Connector.trackSelector = '#np-title';

Connector.onReady = Connector.onStateChanged;
<|endoftext|>


<commit_before>/*
 * ------------------------------------------
 * JST模板二次封装文件
 * @version  1.0
 * @author   genify(caijf@corp.netease.com)
 * ------------------------------------------
 */
var f = function(){
    // variable declaration
    var _  = NEJ.P,
        _e = _('nej.e'),
        _u = _('nej.u');
    // interface
    /**
     * 取模板随机数种子

     * 脚本举例
     * [code]
     *   var _e = NEJ.P('nej.e');
     *   // 返回一个当前日期
     *   var _seed = _e._$getHtmlTemplateSeed();
     * [/code]
     * @api    {nej.e._$getHtmlTemplateSeed}
     * @return {String} 随机数种子
     */
    _e._$getHtmlTemplateSeed = TrimPath.seed;
    /**
     * 根据模板的序列号合并模板数据

     * 脚本举例
     * [code]
     *   var _e = NEJ.P('nej.e');
     *   var _html_seed =  _e._$addHtmlTemplate('
${name}
');
     *   // 生成结构
jack

     *   var _html = _e._$getHtmlTemplate(_html_seed,{name:'jack'});
     * [/code]
     * @api    {nej.e._$getHtmlTemplate}
     * @see    {#._$addHtmlTemplate}
     * @param  {String} 模板序列号
     * @param  {Object} 模板数据
     * @param  {Object} 扩展接口
     * @return {String} 合并数据后的内容
     */
    _e._$getHtmlTemplate = (function(){
        var _doInline = function(_id){
            return !_e._$getTextTemplate?'':
                    _e._$getTextTemplate(_id);
        };
        return function(_sn,_data,_extend){
            _data = _data||{};
            _data.inline = _doInline;
            _extend = _extend||{};
            _extend.rand = _u._$randNumberString;
            _extend.format = _u._$format;
            _extend.escape = _u._$escape;
            _extend.inline = _doInline;
            return TrimPath.merge(_sn,_data,_extend);
        };
    })();
    /**
     * 添加JST模板，JST模板可以是节点的值

     * 脚本举例
     * [code]
     *   var _e = NEJ.P('nej.e');
     *   var _html_seed =  _e._$addHtmlTemplate('
${name}
');
     * [/code]
     * @api    {nej.e._$addHtmlTemplate}
     * @see    {#._$getHtmlTemplate}
     * @param  {String}  JST模板内容或者节点ID
     * @param  {Boolean} 是否保留节点
     * @return {String}  JST模板在缓存中的序列号
     */
    _e._$addHtmlTemplate = function(_content,_keep){
        if (!_content) return '';
        var _sn,_element = _e._$get(_content);
        if (!!_element){
            _sn = _element.id;
            _content = _element.value||_element.innerText;
            if (!_keep) _e._$remove(_element);
        }
        return TrimPath.parse(_content,_sn);
    };
    /**
     * 整合模板后输出至指定容器节点

     * 页面脚本举例
     * [code type="html"]
     *
aaa

     * [/code]
     * 脚本举例
     * [code]
     *   var _e = NEJ.P('nej.e');
     *   var _html_seed =  _e._$addHtmlTemplate('
${name}
');
     *   // 把结构塞到box中，生成

jack

     *   _e._$renderHtmlTemplate('box',_html_seed,{name:'jack'});
     * [/code]
     * @api    {nej.e._$renderHtmlTemplate}
     * @param  {String|Node} 容器节点
     * @param  {String}      模板序列号
     * @param  {Object}      模板数据
     * @param  {Object}      扩展接口
     * @return {nej.e}
     */
    _e._$renderHtmlTemplate = function(_parent,_sn,_data,_extend){
        _parent = _e._$get(_parent);
        if (!!_parent)
            _parent.innerHTML =
                 _e._$getHtmlTemplate(_sn,_data,_extend);
        return this;
    };
    /**
     * 导出JST模版缓存对象，仅用于调试
     * @return {Void}
     */
    _('dbg').dumpJST = function(){
        return TrimPath.dump();
    };
};
NEJ.define('{lib}util/template/jst.js',
          ['{lib}base/util.js'
          ,'{lib}base/element.js'
          ,'{lib}util/template/trimpath.nej.js'],f);<commit_msg>support nej.e._$registJSTExt for regist jst extend api<commit_after>/*
 * ------------------------------------------
 * JST模板二次封装文件
 * @version  1.0
 * @author   genify(caijf@corp.netease.com)
 * ------------------------------------------
 */
var f = function(){
    // variable declaration
    var _  = NEJ.P,
        _e = _('nej.e'),
        _u = _('nej.u'),
        _ext = {};
    // interface
    /**
     * 取模板随机数种子

     * 脚本举例
     * [code]
     *   var _e = NEJ.P('nej.e');
     *   // 返回一个当前日期
     *   var _seed = _e._$getHtmlTemplateSeed();
     * [/code]
     * @api    {nej.e._$getHtmlTemplateSeed}
     * @return {String} 随机数种子
     */
    _e._$getHtmlTemplateSeed = TrimPath.seed;
    /**
     * 根据模板的序列号合并模板数据

     * 脚本举例
     * [code]
     *   var _e = NEJ.P('nej.e');
     *   var _html_seed =  _e._$addHtmlTemplate('
${name}
');
     *   // 生成结构
jack

     *   var _html = _e._$getHtmlTemplate(_html_seed,{name:'jack'});
     * [/code]
     * @api    {nej.e._$getHtmlTemplate}
     * @see    {#._$addHtmlTemplate}
     * @param  {String} 模板序列号
     * @param  {Object} 模板数据
     * @param  {Object} 扩展接口
     * @return {String} 合并数据后的内容
     */
    _e._$getHtmlTemplate = (function(){
        var _doInline = function(_id){
            return !_e._$getTextTemplate?'':
                    _e._$getTextTemplate(_id);
        };
        return function(_sn,_data,_extend){
            _data = _data||{};
            _data.inline = _doInline;
            _extend = NEJ.X(NEJ.X({},_ext),_extend);
            _extend.rand = _u._$randNumberString;
            _extend.format = _u._$format;
            _extend.escape = _u._$escape;
            _extend.inline = _doInline;
            return TrimPath.merge(_sn,_data,_extend);
        };
    })();
    /**
     * 添加JST模板，JST模板可以是节点的值

     * 脚本举例
     * [code]
     *   var _e = NEJ.P('nej.e');
     *   var _html_seed =  _e._$addHtmlTemplate('
${name}
');
     * [/code]
     * @api    {nej.e._$addHtmlTemplate}
     * @see    {#._$getHtmlTemplate}
     * @param  {String}  JST模板内容或者节点ID
     * @param  {Boolean} 是否保留节点
     * @return {String}  JST模板在缓存中的序列号
     */
    _e._$addHtmlTemplate = function(_content,_keep){
        if (!_content) return '';
        var _sn,_element = _e._$get(_content);
        if (!!_element){
            _sn = _element.id;
            _content = _element.value||_element.innerText;
            if (!_keep) _e._$remove(_element);
        }
        return TrimPath.parse(_content,_sn);
    };
    /**
     * 整合模板后输出至指定容器节点

     * 页面脚本举例
     * [code type="html"]
     *
aaa

     * [/code]
     * 脚本举例
     * [code]
     *   var _e = NEJ.P('nej.e');
     *   var _html_seed =  _e._$addHtmlTemplate('
${name}
');
     *   // 把结构塞到box中，生成

jack

     *   _e._$renderHtmlTemplate('box',_html_seed,{name:'jack'});
     * [/code]
     * @api    {nej.e._$renderHtmlTemplate}
     * @param  {String|Node} 容器节点
     * @param  {String}      模板序列号
     * @param  {Object}      模板数据
     * @param  {Object}      扩展接口
     * @return {nej.e}
     */
    _e._$renderHtmlTemplate = function(_parent,_sn,_data,_extend){
        _parent = _e._$get(_parent);
        if (!!_parent)
            _parent.innerHTML =
                 _e._$getHtmlTemplate(_sn,_data,_extend);
        return this;
    };
    /**
     * 注册JST扩展方法
     * [code type="html"]
     *   <textarea name="jst" id="abc">
     *

     *
${name|a|b}

     *

     *   </textarea>
     * [/code]
     * [code]
     *   // 注册扩展方法 a和b
     *   nej.e._$registJSTExt({
     *       a:function(){},
     *       b:function(){}
     *   });
     *   // 模板整合数据
     *   nej.e._$renderHtmlTemplate(
     *       'box','abc',{name:'jack'}
     *   );
     * [/code]
     * @api    {nej.e._$registJSTExt}
     * @param  {Object} 扩展方法
     * @return {Void}
     */
    _e._$registJSTExt = function(_map){
        NEJ.X(_ext,_map);
    };
    /**
     * 导出JST模版缓存对象，仅用于调试
     * @return {Void}
     */
    _('dbg').dumpJST = function(){
        return TrimPath.dump();
    };
};
NEJ.define('{lib}util/template/jst.js',
          ['{lib}base/util.js'
          ,'{lib}base/element.js'
          ,'{lib}util/template/trimpath.nej.js'],f);<|endoftext|>


<commit_before>export function parsePositiveNumber(numberString) {
  if (!numberString || numberString.length < 1) return null;
  try {
    return Math.max(parseFloat(numberString), 0); // Negative numbers become 0
  } catch (error) {
    throw error;
  }
}
<commit_msg>Invalid number strings in, e.g., customer invoice page, become 0<commit_after>export function parsePositiveNumber(numberString) {
  if (!numberString || numberString.length < 1) return null;
  const number = parseFloat(numberString);
  if (isNaN(number)) return 0; // Invalid strings become 0
  return Math.max(number, 0); // Negative numbers become 0
}
<|endoftext|>


<commit_before>/* global THREE */
var debug = require('./debug');
var extend = require('object-assign');

var warn = debug('utils:coordinates:warn');

// Order of coordinates parsed by coordinates.parse.
var coordinateKeys = ['x', 'y', 'z', 'w'];

// Coordinate string regex. Handles negative, positive, and decimals.
var regex = /^\s*((-?\d*\.{0,1}\d+(e-?\d+)?)\s+){2,3}(-?\d*\.{0,1}\d+(e-?\d+)?)\s*$/;
module.exports.regex = regex;

/**
 * Parses coordinates from an "x y z" string.
 * Example: "3 10 -5" to {x: 3, y: 10, z: -5}.
 *
 * @param {string} val - An "x y z" string.
 * @param {string} defaults - fallback value.
 * @returns {object} An object with keys [x, y, z].
 */
function parse (value, defaultVec) {
  var coordinate;
  var vec;

  if (value && value instanceof Object) {
    var x = value.x === undefined ? defaultVec && defaultVec.x : value.x;
    var y = value.y === undefined ? defaultVec && defaultVec.y : value.y;
    var z = value.z === undefined ? defaultVec && defaultVec.z : value.z;
    var w = value.w === undefined ? defaultVec && defaultVec.w : value.w;
    if (x !== undefined) value.x = parseIfString(x);
    if (y !== undefined) value.y = parseIfString(y);
    if (z !== undefined) value.z = parseIfString(z);
    if (w !== undefined) value.w = parseIfString(w);
    return value;
  }

  if (value === null || value === undefined) {
    return typeof defaultVec === 'object' ? extend({}, defaultVec) : defaultVec;
  }

  coordinate = value.trim().split(/\s+/g);

  vec = {};
  for (var i = 0; i < 4; i++) {
    var key = coordinateKeys[i];
    if (coordinate.length > i) {
      vec[key] = parseFloat(coordinate[i], 10);
    } else {
      var defaultVal = defaultVec && defaultVec[key];
      if (defaultVal !== undefined) {
        vec[key] = parseIfString(defaultVal);
      }
    }
  }
  return vec;
}
module.exports.parse = parse;

/**
 * Stringify coordinates from an object with keys [x y z].
 * Example: {x: 3, y: 10, z: -5} to "3 10 -5".
 *
 * @param {object|string} data - An object with keys [x y z].
 * @returns {string} An "x y z" string.
 */
function stringify (data) {
  if (typeof data !== 'object') { return data; }
  return [data.x, data.y, data.z, data.w].join(' ').trim();
}
module.exports.stringify = stringify;

/**
 * @returns {bool}
 */
function isCoordinates (value) {
  return regex.test(value);
}
module.exports.isCoordinates = isCoordinates;

module.exports.isCoordinate = function (value) {
  warn('`AFRAME.utils.isCoordinate` has been renamed to `AFRAME.utils.isCoordinates`');
  return isCoordinates(value);
};

function parseIfString (val) {
  if (val.constructor === String) {
    return parseFloat(val, 10);
  }
  return val;
}

/**
 * Convert {x, y, z} object to three.js Vector3.
 */
module.exports.toVector3 = function (vec3) {
  return new THREE.Vector3(vec3.x, vec3.y, vec3.z);
};
<commit_msg>Tiny cleanup<commit_after>/* global THREE */
var debug = require('./debug');
var extend = require('object-assign');

var warn = debug('utils:coordinates:warn');

// Order of coordinates parsed by coordinates.parse.
var coordinateKeys = ['x', 'y', 'z', 'w'];

// Coordinate string regex. Handles negative, positive, and decimals.
var regex = /^\s*((-?\d*\.{0,1}\d+(e-?\d+)?)\s+){2,3}(-?\d*\.{0,1}\d+(e-?\d+)?)\s*$/;
module.exports.regex = regex;

/**
 * Parses coordinates from an "x y z" string.
 * Example: "3 10 -5" to {x: 3, y: 10, z: -5}.
 *
 * @param {string} val - An "x y z" string.
 * @param {string} defaults - fallback value.
 * @returns {object} An object with keys [x, y, z].
 */
function parse (value, defaultVec) {
  var coordinate;
  var vec;

  if (value && value instanceof Object) {
    var x = value.x === undefined ? defaultVec && defaultVec.x : value.x;
    var y = value.y === undefined ? defaultVec && defaultVec.y : value.y;
    var z = value.z === undefined ? defaultVec && defaultVec.z : value.z;
    var w = value.w === undefined ? defaultVec && defaultVec.w : value.w;
    if (x !== undefined) value.x = parseIfString(x);
    if (y !== undefined) value.y = parseIfString(y);
    if (z !== undefined) value.z = parseIfString(z);
    if (w !== undefined) value.w = parseIfString(w);
    return value;
  }

  if (value === null || value === undefined) {
    return typeof defaultVec === 'object' ? extend({}, defaultVec) : defaultVec;
  }

  coordinate = value.trim().split(/\s+/g);

  vec = {};
  for (var i = 0; i < coordinateKeys.length; i++) {
    var key = coordinateKeys[i];
    if (coordinate.length > i) {
      vec[key] = parseFloat(coordinate[i], 10);
    } else {
      var defaultVal = defaultVec && defaultVec[key];
      if (defaultVal !== undefined) {
        vec[key] = parseIfString(defaultVal);
      }
    }
  }
  return vec;
}
module.exports.parse = parse;

/**
 * Stringify coordinates from an object with keys [x y z].
 * Example: {x: 3, y: 10, z: -5} to "3 10 -5".
 *
 * @param {object|string} data - An object with keys [x y z].
 * @returns {string} An "x y z" string.
 */
function stringify (data) {
  if (typeof data !== 'object') { return data; }
  return [data.x, data.y, data.z, data.w].join(' ').trim();
}
module.exports.stringify = stringify;

/**
 * @returns {bool}
 */
function isCoordinates (value) {
  return regex.test(value);
}
module.exports.isCoordinates = isCoordinates;

module.exports.isCoordinate = function (value) {
  warn('`AFRAME.utils.isCoordinate` has been renamed to `AFRAME.utils.isCoordinates`');
  return isCoordinates(value);
};

function parseIfString (val) {
  if (val.constructor === String) {
    return parseFloat(val, 10);
  }
  return val;
}

/**
 * Convert {x, y, z} object to three.js Vector3.
 */
module.exports.toVector3 = function (vec3) {
  return new THREE.Vector3(vec3.x, vec3.y, vec3.z);
};
<|endoftext|>


<commit_before>import React from 'react';
import { Hotkeys, Hotkey, HotkeysTarget } from '@blueprintjs/core';
import { startCase } from 'lodash';

// This has been mostly superseded by blueprint's KeyCombo component, but may
// still be useful for cases where we need plain text
export function comboToLabel(def, useSymbols = true) {
  const combo = typeof def === "string" ? def : def.combo;

  if (useSymbols) {
    let parts = combo.replace("++", "+plus").split("+");
    parts = parts.map(p => symbols[p] || startCase(p));
    return parts.join("");
  } else {
    return combo
      .split("+")
      .map(startCase)
      .join(" + ")
      .replace("Mod", isMac ? "Cmd" : "Ctrl")
      .replace("Alt", isMac ? "Option" : "Alt");
  }
}

// HOF to get hotkey combos by id
export const hotkeysById = (hotkeys, mode = 'raw') => id => {
  const def = getHotkeyProps(hotkeys[id]);
  return def && (mode === 'raw' ? def.combo : comboToLabel(def.combo, mode === 'symbols'));
}

// Translate shorthand array if needed
export const getHotkeyProps = (def, id) => {
  let out;
  if (typeof def === 'string') {
    out = { combo: def };
  } else if (def instanceof Array) {
    out = { combo: def[0], label: def[1], ...(def[2] || {})};
  } else {
    out = def;
  }
  out.label = out.label || startCase(id);
  return out;
}

// Return a class-based component wrapping a functional one. Creates a dummy
// one if no function is passed.
const wrapperClass = (funcComponent) => {
  const func = funcComponent || (() =>

);
  return class FunctionalWrapper extends React.Component {
    render() {
      return func(this.props);
    }
  };
};

/*
 * HOC to add hotkey support to components. Use this instead of blueprint's one.
 *
 * Arguments:
 * - hotkeySpec: either a named hotkey section previously registered, or an
 *   object mapping command ids to hotkey definitions, where each hotkey can
 *   be either:
 *   - a string consisting in the key combo (e.g. 'ctrl+shift+x')
 *   - an array holding the combo, label, and an object with any other props
 *   - an object holding all props
 * - handlers: an object mapping command ids to handler functions
 * - options: an object that may specify the follownig options:
 *   - functional: boolean indicating if the wrapped component will be a
 *     functional stateless component instead of a class-based one
 *
 * Returns a function that can be invoked with a component class, or a
 * stateless component function (if specified in the options) and returns
 * the decorated class. It may also be invoked without arguments to generate a
 * dummy ad-hoc component with no output.
 *
 */
export const withHotkeys = (hotkeys, handlers, options = {}) => Component => {
  let ComponentClass = (options.functional || !Component) ?
    wrapperClass(Component) : Component;

  class Sub extends ComponentClass {
    renderHotkeys() {
      return (
        <Hotkeys>
          {Object.keys(hotkeys).map(id => {
            const { ...props } = getHotkeyProps(hotkeys[id], id);
            return (
              <Hotkey
                {...props}
                key={id}
                global={props.global !== false}
                onKeyDown={function(e) {
                  return handlers[id].call(this, e, props)
                }}
              />
            );
          })}
        </Hotkeys>
      )
    }
  }

  return HotkeysTarget(Sub);
}

const isMac = navigator.userAgent.includes("Mac OS X");

// TODO maybe avoid using symbols by default when not on Mac?
// Anyway, alternative 'Key + Key' description is provided as well
const symbols = {
  meta: "⌘",
  ctrl: "⌃",
  alt: "⌥",
  shift: "⇧",
  esc: "␛", //'⎋',
  enter: "⏎",
  backspace: "⌫",
  plus: "+",
  tab: "⇥",
  space: "␣",
  capslock: "⇪",
  pageup: "⇞",
  pagedown: "⇟",
  home: "↖",
  end: "↘",
  left: "←",
  right: "→",
  up: "↑",
  down: "↓"
};

symbols.mod = symbols[isMac ? "meta" : "ctrl"];
<commit_msg>Passing props down to hotkey handlers now<commit_after>import React from "react";
import { Hotkeys, Hotkey, HotkeysTarget } from "@blueprintjs/core";
import { startCase } from "lodash";

// This has been mostly superseded by blueprint's KeyCombo component, but may
// still be useful for cases where we need plain text
export function comboToLabel(def, useSymbols = true) {
  const combo = typeof def === "string" ? def : def.combo;

  if (useSymbols) {
    let parts = combo.replace("++", "+plus").split("+");
    parts = parts.map(p => symbols[p] || startCase(p));
    return parts.join("");
  } else {
    return combo
      .split("+")
      .map(startCase)
      .join(" + ")
      .replace("Mod", isMac ? "Cmd" : "Ctrl")
      .replace("Alt", isMac ? "Option" : "Alt");
  }
}

// HOF to get hotkey combos by id
export const hotkeysById = (hotkeys, mode = "raw") => id => {
  const def = getHotkeyProps(hotkeys[id]);
  return (
    def &&
    (mode === "raw" ? def.combo : comboToLabel(def.combo, mode === "symbols"))
  );
};

// Translate shorthand array if needed
export const getHotkeyProps = (def, id) => {
  let out;
  if (typeof def === "string") {
    out = { combo: def };
  } else if (def instanceof Array) {
    out = { combo: def[0], label: def[1], ...(def[2] || {}) };
  } else {
    out = def;
  }
  out.label = out.label || startCase(id);
  return out;
};

// Return a class-based component wrapping a functional one. Creates a dummy
// one if no function is passed.
const wrapperClass = funcComponent => {
  const func = funcComponent || (() =>
);
  return class FunctionalWrapper extends React.Component {
    render() {
      return func(this.props);
    }
  };
};

/*
 * HOC to add hotkey support to components. Use this instead of blueprint's one.
 *
 * Arguments:
 * - hotkeySpec: either a named hotkey section previously registered, or an
 *   object mapping command ids to hotkey definitions, where each hotkey can
 *   be either:
 *   - a string consisting in the key combo (e.g. 'ctrl+shift+x')
 *   - an array holding the combo, label, and an object with any other props
 *   - an object holding all props
 * - handlers: an object mapping command ids to handler functions
 * - options: an object that may specify the follownig options:
 *   - functional: boolean indicating if the wrapped component will be a
 *     functional stateless component instead of a class-based one
 *
 * Returns a function that can be invoked with a component class, or a
 * stateless component function (if specified in the options) and returns
 * the decorated class. It may also be invoked without arguments to generate a
 * dummy ad-hoc component with no output.
 *
 */
export const withHotkeys = (hotkeys, handlers, options = {}) => Component => {
  let ComponentClass =
    options.functional || !Component ? wrapperClass(Component) : Component;

  class Sub extends ComponentClass {
    renderHotkeys() {
      const componentProps = this.props;
      return (
        <Hotkeys>
          {Object.keys(hotkeys).map(id => {
            const { ...props } = getHotkeyProps(hotkeys[id], id);
            return (
              <Hotkey
                {...props}
                key={id}
                global={props.global !== false}
                onKeyDown={function(e) {
                  return handlers[id].call(this, e, componentProps);
                }}
              />
            );
          })}
        </Hotkeys>
      );
    }
  }

  return HotkeysTarget(Sub);
};

const isMac = navigator.userAgent.includes("Mac OS X");

// TODO maybe avoid using symbols by default when not on Mac?
// Anyway, alternative 'Key + Key' description is provided as well
const symbols = {
  meta: "⌘",
  ctrl: "⌃",
  alt: "⌥",
  shift: "⇧",
  esc: "␛", //'⎋',
  enter: "⏎",
  backspace: "⌫",
  plus: "+",
  tab: "⇥",
  space: "␣",
  capslock: "⇪",
  pageup: "⇞",
  pagedown: "⇟",
  home: "↖",
  end: "↘",
  left: "←",
  right: "→",
  up: "↑",
  down: "↓"
};

symbols.mod = symbols[isMac ? "meta" : "ctrl"];
<|endoftext|>


<commit_before>import React from 'react';
import _ from 'lodash';
import Immutable from 'immutable';

var Input = (ComposedComponent) => class extends React.Component {

  /**
   * Define property types
   */
  static propTypes = {
    name: React.PropTypes.string.isRequired
  }

  static contextTypes = {
    form: React.PropTypes.object
  }

  static defaultProps = ComposedComponent.defaultProps

  /**
   * Determines if the component should re-render
   */
  shouldComponentUpdate = (nextProps, nextState) => {
    var { value, ...otherProps } = this.props;
    var previous = value;
    var { value, ...otherNextProps } = nextProps;

    if (!Immutable.is(previous, value) ||
        !_.isEqual(otherProps, otherNextProps) ||
        !_.isEqual(this.state, nextState)) {
      return true;
    }

    return false;
  }

  generateFormName = () => {
    if (this.props.name.charAt(0) === "[") {
      return this.context.form.model + this.props.name;
    } else {
      return this.context.form.model + "[" + this.props.name + "]";
    }
  }

  /**
   * Returns modified properties for the input element.
   *
   * @method inputProps
   */
  inputProps = () => {
    var { ...inputProps } = this.props;

    inputProps.name = this.generateFormName();

    // set id so label will work correctly
    inputProps.id = inputProps.name;

    if (inputProps.onChange) {
      inputProps.onChange = this.handleOnChange;
    }

    return inputProps;
  }

  /**
   * Calls the onChange method with relevant data.
   */
  handleOnChange = (ev) => {
    this.props.onChange(ev, this.props);
  }

  /**
   * Returns HTML for the label.
   *
   * @method labelHTML
   */
  labelHTML = () => {
    if (this.props.label === false) {
      return;
    }

    var labelText = this.props.label || this.props.name.charAt(0).toUpperCase() + this.props.name.slice(1);

    if (this.props.validations) {
      labelText += "*";
    }

    return (
      { labelText }
    );
  }

  state = {
    labelHTML: this.labelHTML,
    inputProps: this.inputProps
  }

  mainClasses = () => {
    return " base-input";
  }

  inputClasses = () => {
    return " base-input__input";
  }

  exposedMethods = () => {
    return {
      mainClasses: this.mainClasses,
      inputClasses: this.inputClasses,
      ...this.state
    };
  }

  render() {
    return (
      <ComposedComponent input={this.exposedMethods()} {...this.props} />
    );
  }

};

export default Input;
<commit_msg>inputs no longer require forms<commit_after>import React from 'react';
import _ from 'lodash';
import Immutable from 'immutable';

var Input = (ComposedComponent) => class extends React.Component {

  /**
   * Define property types
   */
  static propTypes = {
    name: React.PropTypes.string.isRequired
  }

  static contextTypes = {
    form: React.PropTypes.object
  }

  static defaultProps = ComposedComponent.defaultProps

  /**
   * Determines if the component should re-render
   */
  shouldComponentUpdate = (nextProps, nextState) => {
    var { value, ...otherProps } = this.props;
    var previous = value;
    var { value, ...otherNextProps } = nextProps;

    if (!Immutable.is(previous, value) ||
        !_.isEqual(otherProps, otherNextProps) ||
        !_.isEqual(this.state, nextState)) {
      return true;
    }

    return false;
  }

  generateFormName = () => {
    if (this.context.form) {
      if (this.props.name.charAt(0) === "[") {
        return this.context.form.model + this.props.name;
      } else {
        return this.context.form.model + "[" + this.props.name + "]";
      }
    } else {
      return this.props.name;
    }
  }

  /**
   * Returns modified properties for the input element.
   *
   * @method inputProps
   */
  inputProps = () => {
    var { ...inputProps } = this.props;

    inputProps.name = this.generateFormName();

    // set id so label will work correctly
    inputProps.id = inputProps.name;

    if (inputProps.onChange) {
      inputProps.onChange = this.handleOnChange;
    }

    return inputProps;
  }

  /**
   * Calls the onChange method with relevant data.
   */
  handleOnChange = (ev) => {
    this.props.onChange(ev, this.props);
  }

  /**
   * Returns HTML for the label.
   *
   * @method labelHTML
   */
  labelHTML = () => {
    if (this.props.label === false) {
      return;
    }

    var labelText = this.props.label || this.props.name.charAt(0).toUpperCase() + this.props.name.slice(1);

    if (this.props.validations) {
      labelText += "*";
    }

    return (
      { labelText }
    );
  }

  state = {
    labelHTML: this.labelHTML,
    inputProps: this.inputProps
  }

  mainClasses = () => {
    return " base-input";
  }

  inputClasses = () => {
    return " base-input__input";
  }

  exposedMethods = () => {
    return {
      mainClasses: this.mainClasses,
      inputClasses: this.inputClasses,
      ...this.state
    };
  }

  render() {
    return (
      <ComposedComponent input={this.exposedMethods()} {...this.props} />
    );
  }

};

export default Input;
<|endoftext|>


<commit_before>import Vue from 'vue';
import merge from 'element-ui/src/utils/merge';
import PopupManager from 'element-ui/src/utils/popup/popup-manager';

let idSeed = 1;
const transitions = [];

const hookTransition = (transition) => {
  if (transitions.indexOf(transition) !== -1) return;

  const getVueInstance = (element) => {
    let instance = element.__vue__;
    if (!instance) {
      const textNode = element.previousSibling;
      if (textNode.__vue__) {
        instance = textNode.__vue__;
      }
    }
    return instance;
  };

  Vue.transition(transition, {
    afterEnter(el) {
      const instance = getVueInstance(el);

      if (instance) {
        instance.doAfterOpen && instance.doAfterOpen();
      }
    },
    afterLeave(el) {
      const instance = getVueInstance(el);

      if (instance) {
        instance.doAfterClose && instance.doAfterClose();
      }
    }
  });
};

let scrollBarWidth;
const getScrollBarWidth = () => {
  if (Vue.prototype.$isServer) return;
  if (scrollBarWidth !== undefined) return scrollBarWidth;

  const outer = document.createElement('div');
  outer.style.visibility = 'hidden';
  outer.style.width = '100px';
  outer.style.position = 'absolute';
  outer.style.top = '-9999px';
  document.body.appendChild(outer);

  const widthNoScroll = outer.offsetWidth;
  outer.style.overflow = 'scroll';

  const inner = document.createElement('div');
  inner.style.width = '100%';
  outer.appendChild(inner);

  const widthWithScroll = inner.offsetWidth;
  outer.parentNode.removeChild(outer);

  return widthNoScroll - widthWithScroll;
};

const getDOM = function(dom) {
  if (dom.nodeType === 3) {
    dom = dom.nextElementSibling || dom.nextSibling;
    getDOM(dom);
  }
  return dom;
};

export default {
  props: {
    value: {
      type: Boolean,
      default: false
    },
    transition: {
      type: String,
      default: ''
    },
    openDelay: {},
    closeDelay: {},
    zIndex: {},
    modal: {
      type: Boolean,
      default: false
    },
    modalFade: {
      type: Boolean,
      default: true
    },
    modalClass: {
    },
    lockScroll: {
      type: Boolean,
      default: true
    },
    closeOnPressEscape: {
      type: Boolean,
      default: false
    },
    closeOnClickModal: {
      type: Boolean,
      default: false
    }
  },

  created() {
    if (this.transition) {
      hookTransition(this.transition);
    }
  },

  beforeMount() {
    this._popupId = 'popup-' + idSeed++;
    PopupManager.register(this._popupId, this);
  },

  beforeDestroy() {
    PopupManager.deregister(this._popupId);
    PopupManager.closeModal(this._popupId);
    if (this.modal && this.bodyOverflow !== null && this.bodyOverflow !== 'hidden') {
      document.body.style.overflow = this.bodyOverflow;
      document.body.style.paddingRight = this.bodyPaddingRight;
    }
    this.bodyOverflow = null;
    this.bodyPaddingRight = null;
  },

  data() {
    return {
      opened: false,
      bodyOverflow: null,
      bodyPaddingRight: null,
      rendered: false
    };
  },

  watch: {
    value(val) {
      if (val) {
        if (this._opening) return;
        if (!this.rendered) {
          this.rendered = true;
          Vue.nextTick(() => {
            this.open();
          });
        } else {
          this.open();
        }
      } else {
        this.close();
      }
    }
  },

  methods: {
    open(options) {
      if (!this.rendered) {
        this.rendered = true;
        this.$emit('input', true);
      }

      const props = merge({}, this, options);

      if (this._closeTimer) {
        clearTimeout(this._closeTimer);
        this._closeTimer = null;
      }
      clearTimeout(this._openTimer);

      const openDelay = Number(props.openDelay);
      if (openDelay > 0) {
        this._openTimer = setTimeout(() => {
          this._openTimer = null;
          this.doOpen(props);
        }, openDelay);
      } else {
        this.doOpen(props);
      }
    },

    doOpen(props) {
      if (this.$isServer) return;
      if (this.willOpen && !this.willOpen()) return;
      if (this.opened) return;

      this._opening = true;

      // 使用 vue-popup 的组件，如果需要和父组件通信显示的状态，应该使用 value，它是一个 prop，
      // 这样在父组件中用 v-model 即可；否则可以使用 visible，它是一个 data
      this.visible = true;
      this.$emit('input', true);

      const dom = getDOM(this.$el);

      const modal = props.modal;

      const zIndex = props.zIndex;
      if (zIndex) {
        PopupManager.zIndex = zIndex;
      }

      if (modal) {
        if (this._closing) {
          PopupManager.closeModal(this._popupId);
          this._closing = false;
        }
        PopupManager.openModal(this._popupId, PopupManager.nextZIndex(), dom, props.modalClass, props.modalFade);
        if (props.lockScroll) {
          if (!this.bodyOverflow) {
            this.bodyPaddingRight = document.body.style.paddingRight;
            this.bodyOverflow = document.body.style.overflow;
          }
          scrollBarWidth = getScrollBarWidth();
          let bodyHasOverflow = document.documentElement.clientHeight < document.body.scrollHeight;
          if (scrollBarWidth > 0 && bodyHasOverflow) {
            document.body.style.paddingRight = scrollBarWidth + 'px';
          }
          document.body.style.overflow = 'hidden';
        }
      }

      if (getComputedStyle(dom).position === 'static') {
        dom.style.position = 'absolute';
      }

      dom.style.zIndex = PopupManager.nextZIndex();
      this.opened = true;

      this.onOpen && this.onOpen();

      if (!this.transition) {
        this.doAfterOpen();
      }
    },

    doAfterOpen() {
      this._opening = false;
    },

    close() {
      if (this.willClose && !this.willClose()) return;

      if (this._openTimer !== null) {
        clearTimeout(this._openTimer);
        this._openTimer = null;
      }
      clearTimeout(this._closeTimer);

      const closeDelay = Number(this.closeDelay);

      if (closeDelay > 0) {
        this._closeTimer = setTimeout(() => {
          this._closeTimer = null;
          this.doClose();
        }, closeDelay);
      } else {
        this.doClose();
      }
    },

    doClose() {
      this.visible = false;
      this.$emit('input', false);
      this._closing = true;

      this.onClose && this.onClose();

      if (this.lockScroll) {
        setTimeout(() => {
          if (this.modal && this.bodyOverflow !== 'hidden') {
            document.body.style.overflow = this.bodyOverflow;
            document.body.style.paddingRight = this.bodyPaddingRight;
          }
          this.bodyOverflow = null;
          this.bodyPaddingRight = null;
        }, 200);
      }

      this.opened = false;

      if (!this.transition) {
        this.doAfterClose();
      }
    },

    doAfterClose() {
      PopupManager.closeModal(this._popupId);
      this._closing = false;
    }
  }
};

export { PopupManager };
<commit_msg>Popper: Fixing the rest part of wrong comments. (#2619)<commit_after>import Vue from 'vue';
import merge from 'element-ui/src/utils/merge';
import PopupManager from 'element-ui/src/utils/popup/popup-manager';
import getScrollBarWidth from '../scrollbar-width';

let idSeed = 1;
const transitions = [];

const hookTransition = (transition) => {
  if (transitions.indexOf(transition) !== -1) return;

  const getVueInstance = (element) => {
    let instance = element.__vue__;
    if (!instance) {
      const textNode = element.previousSibling;
      if (textNode.__vue__) {
        instance = textNode.__vue__;
      }
    }
    return instance;
  };

  Vue.transition(transition, {
    afterEnter(el) {
      const instance = getVueInstance(el);

      if (instance) {
        instance.doAfterOpen && instance.doAfterOpen();
      }
    },
    afterLeave(el) {
      const instance = getVueInstance(el);

      if (instance) {
        instance.doAfterClose && instance.doAfterClose();
      }
    }
  });
};

let scrollBarWidth;

const getDOM = function(dom) {
  if (dom.nodeType === 3) {
    dom = dom.nextElementSibling || dom.nextSibling;
    getDOM(dom);
  }
  return dom;
};

export default {
  props: {
    value: {
      type: Boolean,
      default: false
    },
    transition: {
      type: String,
      default: ''
    },
    openDelay: {},
    closeDelay: {},
    zIndex: {},
    modal: {
      type: Boolean,
      default: false
    },
    modalFade: {
      type: Boolean,
      default: true
    },
    modalClass: {},
    lockScroll: {
      type: Boolean,
      default: true
    },
    closeOnPressEscape: {
      type: Boolean,
      default: false
    },
    closeOnClickModal: {
      type: Boolean,
      default: false
    }
  },

  created() {
    if (this.transition) {
      hookTransition(this.transition);
    }
  },

  beforeMount() {
    this._popupId = 'popup-' + idSeed++;
    PopupManager.register(this._popupId, this);
  },

  beforeDestroy() {
    PopupManager.deregister(this._popupId);
    PopupManager.closeModal(this._popupId);
    if (this.modal && this.bodyOverflow !== null && this.bodyOverflow !== 'hidden') {
      document.body.style.overflow = this.bodyOverflow;
      document.body.style.paddingRight = this.bodyPaddingRight;
    }
    this.bodyOverflow = null;
    this.bodyPaddingRight = null;
  },

  data() {
    return {
      opened: false,
      bodyOverflow: null,
      bodyPaddingRight: null,
      rendered: false
    };
  },

  watch: {
    value(val) {
      if (val) {
        if (this._opening) return;
        if (!this.rendered) {
          this.rendered = true;
          Vue.nextTick(() => {
            this.open();
          });
        } else {
          this.open();
        }
      } else {
        this.close();
      }
    }
  },

  methods: {
    open(options) {
      if (!this.rendered) {
        this.rendered = true;
        this.$emit('input', true);
      }

      const props = merge({}, this, options);

      if (this._closeTimer) {
        clearTimeout(this._closeTimer);
        this._closeTimer = null;
      }
      clearTimeout(this._openTimer);

      const openDelay = Number(props.openDelay);
      if (openDelay > 0) {
        this._openTimer = setTimeout(() => {
          this._openTimer = null;
          this.doOpen(props);
        }, openDelay);
      } else {
        this.doOpen(props);
      }
    },

    doOpen(props) {
      if (this.$isServer) return;
      if (this.willOpen && !this.willOpen()) return;
      if (this.opened) return;

      this._opening = true;

      // 使用 vue-popup 的组件，如果需要和父组件通信显示的状态，应该使用 value，它是一个 prop，
      // 这样在父组件中用 v-model 即可；否则可以使用 visible，它是一个 data
      this.visible = true;
      this.$emit('input', true);

      const dom = getDOM(this.$el);

      const modal = props.modal;

      const zIndex = props.zIndex;
      if (zIndex) {
        PopupManager.zIndex = zIndex;
      }

      if (modal) {
        if (this._closing) {
          PopupManager.closeModal(this._popupId);
          this._closing = false;
        }
        PopupManager.openModal(this._popupId, PopupManager.nextZIndex(), dom, props.modalClass, props.modalFade);
        if (props.lockScroll) {
          if (!this.bodyOverflow) {
            this.bodyPaddingRight = document.body.style.paddingRight;
            this.bodyOverflow = document.body.style.overflow;
          }
          scrollBarWidth = getScrollBarWidth();
          let bodyHasOverflow = document.documentElement.clientHeight < document.body.scrollHeight;
          if (scrollBarWidth > 0 && bodyHasOverflow) {
            document.body.style.paddingRight = scrollBarWidth + 'px';
          }
          document.body.style.overflow = 'hidden';
        }
      }

      if (getComputedStyle(dom).position === 'static') {
        dom.style.position = 'absolute';
      }

      dom.style.zIndex = PopupManager.nextZIndex();
      this.opened = true;

      this.onOpen && this.onOpen();

      if (!this.transition) {
        this.doAfterOpen();
      }
    },

    doAfterOpen() {
      this._opening = false;
    },

    close() {
      if (this.willClose && !this.willClose()) return;

      if (this._openTimer !== null) {
        clearTimeout(this._openTimer);
        this._openTimer = null;
      }
      clearTimeout(this._closeTimer);

      const closeDelay = Number(this.closeDelay);

      if (closeDelay > 0) {
        this._closeTimer = setTimeout(() => {
          this._closeTimer = null;
          this.doClose();
        }, closeDelay);
      } else {
        this.doClose();
      }
    },

    doClose() {
      this.visible = false;
      this.$emit('input', false);
      this._closing = true;

      this.onClose && this.onClose();

      if (this.lockScroll) {
        setTimeout(() => {
          if (this.modal && this.bodyOverflow !== 'hidden') {
            document.body.style.overflow = this.bodyOverflow;
            document.body.style.paddingRight = this.bodyPaddingRight;
          }
          this.bodyOverflow = null;
          this.bodyPaddingRight = null;
        }, 200);
      }

      this.opened = false;

      if (!this.transition) {
        this.doAfterClose();
      }
    },

    doAfterClose() {
      PopupManager.closeModal(this._popupId);
      this._closing = false;
    }
  }
};

export {
  PopupManager
};
<|endoftext|>


<commit_before>// Copyright 2010 Steven Dee. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

goog.provide('jsprettify.prettifyStr');

goog.require('goog.array');
goog.require('jsprettify.entities');

/**
 * Prettifies strings by replacing ASCII shorthand with proper typographical
 * symbols.
 * @param {string} text Text to prettify.
 * @return {string} Prettified text.
 */
jsprettify.prettifyStr = function(text) {
  var e = jsprettify.entities;
  /**
   * This array holds entries consisting of patterns and replacements in the
   * order that they are to be applied. We need to preserve order, since e.g.
   * if -- were replaced before ---, disaster would ensue.
   * @type {Array.<{pattern: string, replace: string}>}
   */
  var subs = [
    {pattern: '\\.\\.\\.',         replace: e.hellip},
    {pattern: "(^|[\\s\"])'",      replace: '$1' + e.lsquo},
    {pattern: '(^|[\\s-])"',       replace: '$1' + e.ldquo},
    {pattern: '---',               replace: e.emdash},
    {pattern: '--',                replace: e.endash},
    {pattern: "'($|[\\s\"])?",     replace: e.rsquo + '$1'},
    {pattern: '"($|[\\s.,;:?!])',  replace: e.rdquo + '$1'}
  ];
  goog.array.forEach(subs, function(sub) {
    var pattern = new RegExp(sub.pattern, 'g');
    text = text.replace(pattern, sub.replace);
  });
  return text;
};
<commit_msg>Now we prettify the logo. :-)<commit_after>// Copyright 2010 Steven Dee. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

goog.provide('jsprettify.prettifyStr');

goog.require('goog.array');
goog.require('jsprettify.entities');

/**
 * Prettifies strings by replacing ASCII shorthand with proper typographical
 * symbols.
 * @param {string} text Text to prettify.
 * @return {string} Prettified text.
 */
jsprettify.prettifyStr = function(text) {
  var e = jsprettify.entities;
  /**
   * This array holds entries consisting of patterns and replacements in the
   * order that they are to be applied. We need to preserve order, since e.g.
   * if -- were replaced before ---, disaster would ensue.
   * @type {Array.<{pattern: string, replace: string}>}
   */
  var subs = [
    {pattern: '\\.\\.\\.',         replace: e.hellip},
    {pattern: "(^|[\\s\"])'",      replace: '$1' + e.lsquo},
    {pattern: "'($|[\\s\"])?",     replace: e.rsquo + '$1'},
    {pattern: '"($|[\\s.,;:?!])',  replace: e.rdquo + '$1'},
    {pattern: '(^|[\\s-])"',       replace: '$1' + e.ldquo},
    {pattern: '---',               replace: e.emdash},
    {pattern: '--',                replace: e.endash}
  ];
  goog.array.forEach(subs, function(sub) {
    var pattern = new RegExp(sub.pattern, 'g');
    text = text.replace(pattern, sub.replace);
  });
  return text;
};
<|endoftext|>


<commit_before>/**
 * Daimyo - utilities for dealing with XML
 * Copyright (c)2011, by Branko Vukelic <branko@herdhound.com>
 * Licensed under MIT license (see LICENSE)
 */

var xmlutils = exports;

/**
 * Generate regex for parsing a single tag
 *
 * @param {String} tagName The exact tag name as it appears in the XML
 * @returns {RegExp} Regular expresson object that will parse the given tag
 * @private
 */
function getTagRe(tagName) {
  return new RegExp('<' + tagName + '[^>]*>([^<]*)<');
}

/**
 * Run a regex multiple times until matches are exhausted
 *
 * @param {String} s Source string
 * @param {RegExp} rxp RegExp object to run on the source
 * @returns {Array} Array of results
 * @private
 */
function matchAll(s, rxp) {
  var firstMatch = rxp.exec(s);
  var matches = [];

  if (!firstMatch) {
    return [];
  }

  matches.push(firstMatch[1]);

  function recurse() {
    var match = rxp.exec(s);
    if (match) {
      matches.push(match[1]);
      recurse();
    } else {
      return;
    }
  }

  return matches;
}

/**
 * Convert a string to integer
 *
 * @param {String} s String to be parsed
 * @returns {Integer} Converted integer
 */
xmlutils.toInt = function(s) {
  return parseInt(s, 10);
};

/**
 * Convert a string to Date object
 *
 * @param {String} s String to be parsed
 * @returns {Date} Converted date
 */
xmlutils.toDate = function(s) {
  return new Date(s);
};

/**
 * Convert a string to Bool
 *
 * This function treats `'true'` as `true`, and everything else as false.
 *
 * @param {String} s String to be parsed
 * @returns {Bool} Converted boolean
 */
xmlutils.toBool = function(s) {
  return s === 'true' ? true : false;
};

/**
 * Pass-through function that does nothing
 *
 * @param {String} s Strning to be passed through
 * @returns {String} Same string that came in
 */
xmlutils.toString = function(s) {
  return s;
};

/**
 * Extract data from XML string using recipe mappings
 *
 * Recipe object contains a mapping between tag names and coercion functions
 * like `toInt` and `toDate`. Each key in the recipe object will be treated
 * as a valid tag name, and searched for within the XML. Data found within the
 * XML string will be coerced and assigned to a key in the result object. The
 * key name in the result object will match the key name from the recipe
 * object.
 *
 * An example recipe object:
 *
 *     {
 *       'payment_method_token': xmlutils.toString,
 *       'created_at': xmlutils.toDate,
 *       ....
 *     }
 *
 * @param {String} xml The source XML string
 * @param {Object} recipe The recipe object
 * @returns {Object} Name-value pairs of extracted data
 */
xmlutils.extractData = function(xml, recipe) {
  var result = {};
  Object.keys(recipe).forEach(function(key) {
    // Get the Regex for the recipe
    var rxp = getTagRe(key);
    var matches = matchAll(xml, rxp);

    if (matches.length === 1) {
      result[key] = recipe[key](matches[0]);
    } else if (matches.length > 1) {
      result[key] = [];
      matches.forEach(function(match) {
        result[key].push(recipe[key](match));
      });
    }
  });

  return result;
};

/**
 * Extract messages from XML string
 *
 * The messages can be of the following classes:
 * - _error_: errors and declines
 * - _info_: success and other information
 *
 * The messages will also have a context in which it was transmitted, and the
 * message that describes the details.
 *
 * The return object may look like this:
 *
 *     {
 *       error: [{'input.card_number': 'failed_checksum'}]
 *     }
 *
 * @param {String} xml The XML string to be parsed
 * @returns {Array} Array of error messages.
 */
xmlutils.extractMessages = function(xml) {
  var messageRe = /<messsage([^\/]+)\/>/;
  var classRe = /class="([^"]+)"/;
  var contextRe = /context="([^"]+)"/;
  var keyRe = /key="([^"]+")"/;

  var messages = [];

  function recurse() {
    var match = messageRe.exec(xml);
    var attrs;
    var message = {};

    if (!match) {
      return;
    }

    attrs = match[1];
    message.cls = classRe.exec(attrs)[1];
    message.context = contextRe.exec(attrs)[1];
    message.key = keyRe.exec(attrs)[1];
    messages.push(message);
    return recurse();
  }

  return messages;
};

/**
 * Decamelizes a string
 *
 * Converts 'CamelCase' to 'camel_case'.
 *
 * @param {String} s String to convert
 * @returns {String} Decamelized string
 */
xmlutils.decamelize = function(s) {
  s = s.replace(/^[A-Z]/, function(match) {
    return match.toLowerCase();
  });
  s = s.replace(/[A-Z]/g, function(match) {
    return '_' + match.toLowerCase();
  });
  return s;
};

<commit_msg>Added function to shallow-convert JS objects to XML.<commit_after>/**
 * Daimyo - utilities for dealing with XML
 * Copyright (c)2011, by Branko Vukelic <branko@herdhound.com>
 * Licensed under MIT license (see LICENSE)
 */

var xmlutils = exports;

/**
 * Generate regex for parsing a single tag
 *
 * @param {String} tagName The exact tag name as it appears in the XML
 * @returns {RegExp} Regular expresson object that will parse the given tag
 * @private
 */
function getTagRe(tagName) {
  return new RegExp('<' + tagName + '[^>]*>([^<]*)<');
}

/**
 * Run a regex multiple times until matches are exhausted
 *
 * @param {String} s Source string
 * @param {RegExp} rxp RegExp object to run on the source
 * @returns {Array} Array of results
 * @private
 */
function matchAll(s, rxp) {
  var firstMatch = rxp.exec(s);
  var matches = [];

  if (!firstMatch) {
    return [];
  }

  matches.push(firstMatch[1]);

  function recurse() {
    var match = rxp.exec(s);
    if (match) {
      matches.push(match[1]);
      recurse();
    } else {
      return;
    }
  }

  return matches;
}

/**
 * Convert a string to integer
 *
 * @param {String} s String to be parsed
 * @returns {Integer} Converted integer
 */
xmlutils.toInt = function(s) {
  return parseInt(s, 10);
};

/**
 * Convert a string to Date object
 *
 * @param {String} s String to be parsed
 * @returns {Date} Converted date
 */
xmlutils.toDate = function(s) {
  return new Date(s);
};

/**
 * Convert a string to Bool
 *
 * This function treats `'true'` as `true`, and everything else as false.
 *
 * @param {String} s String to be parsed
 * @returns {Bool} Converted boolean
 */
xmlutils.toBool = function(s) {
  return s === 'true' ? true : false;
};

/**
 * Pass-through function that does nothing
 *
 * @param {String} s Strning to be passed through
 * @returns {String} Same string that came in
 */
xmlutils.toString = function(s) {
  return s;
};

/**
 * Extract data from XML string using recipe mappings
 *
 * Recipe object contains a mapping between tag names and coercion functions
 * like `toInt` and `toDate`. Each key in the recipe object will be treated
 * as a valid tag name, and searched for within the XML. Data found within the
 * XML string will be coerced and assigned to a key in the result object. The
 * key name in the result object will match the key name from the recipe
 * object.
 *
 * An example recipe object:
 *
 *     {
 *       'payment_method_token': xmlutils.toString,
 *       'created_at': xmlutils.toDate,
 *       ....
 *     }
 *
 * @param {String} xml The source XML string
 * @param {Object} recipe The recipe object
 * @returns {Object} Name-value pairs of extracted data
 */
xmlutils.extractData = function(xml, recipe) {
  var result = {};
  Object.keys(recipe).forEach(function(key) {
    // Get the Regex for the recipe
    var rxp = getTagRe(key);
    var matches = matchAll(xml, rxp);

    if (matches.length === 1) {
      result[key] = recipe[key](matches[0]);
    } else if (matches.length > 1) {
      result[key] = [];
      matches.forEach(function(match) {
        result[key].push(recipe[key](match));
      });
    }
  });

  return result;
};

/**
 * Extract messages from XML string
 *
 * The messages can be of the following classes:
 * - _error_: errors and declines
 * - _info_: success and other information
 *
 * The messages will also have a context in which it was transmitted, and the
 * message that describes the details.
 *
 * The return object may look like this:
 *
 *     {
 *       error: [{'input.card_number': 'failed_checksum'}]
 *     }
 *
 * @param {String} xml The XML string to be parsed
 * @returns {Array} Array of error messages.
 */
xmlutils.extractMessages = function(xml) {
  var messageRe = /<messsage([^\/]+)\/>/;
  var classRe = /class="([^"]+)"/;
  var contextRe = /context="([^"]+)"/;
  var keyRe = /key="([^"]+")"/;

  var messages = [];

  function recurse() {
    var match = messageRe.exec(xml);
    var attrs;
    var message = {};

    if (!match) {
      return;
    }

    attrs = match[1];
    message.cls = classRe.exec(attrs)[1];
    message.context = contextRe.exec(attrs)[1];
    message.key = keyRe.exec(attrs)[1];
    messages.push(message);
    return recurse();
  }

  return messages;
};

/**
 * Decamelizes a string
 *
 * Converts 'CamelCase' to 'camel_case'.
 *
 * @param {String} s String to convert
 * @returns {String} Decamelized string
 */
xmlutils.decamelize = function(s) {
  s = s.replace(/^[A-Z]/, function(match) {
    return match.toLowerCase();
  });
  s = s.replace(/[A-Z]/g, function(match) {
    return '_' + match.toLowerCase();
  });
  return s;
};

/**
 * Shallow conversion of JavaScript object to XML
 *
 * It converts each key to a single XML node and converts the contents of the
 * key to a text node by calling `toString` on it.
 *
 * Optionally, the whole XML string can be wrapped in a top-level tag.
 *
 * This function _does not_ care about the order of keys, so if you need the
 * nodes to be in a certain order, you should supply an array of keys.
 *
 * @param {Object} o Object to be converted
 * @param {String} [topLevel] Top level tag
 * @param {Array} [keys] Array of keys to use so that nodes are ordered
 * @returns {String} XML version of the object
 */
xmlutils.toXML = function(o, topLevel, keys) {
  var xml = '';

  // Was topLevel arg skipped?
  if (typeof topLevel != 'string') {
    keys = topLevel;
    topLevel = null;
  } else {
    xml += '<' + xmlutils.decamelize(topLevel) + '>\n';
  }

  keys = keys || Object.keys(o);

  keys.forEach(function(key) {
    var tagName = xmlutils.decamelize(key);
    xml += '<' + tagName + '>' + o[key].toString() + '</' + tagName + '>\n';
  });

  if (topLevel) {
    xml += '</' + xmlutils.decamelize(topLevel) + '>\n';
  }

  return xml;
};
<|endoftext|>


<commit_before>var http = require('http')
,   https = require('https')

var api  = require('./commands')
,   errors = require('./errors')

function Client(options) {
    this.opts = {
        host:    'localhost'
     ,  port:    22555
     ,  method:  'POST'
     ,  user:    ''
     ,  pass:    ''
     ,  headers:  {
            'Host': 'localhost'
         ,  'Authorization':  ''
       }
     , passphrasecallback: null
     , https: false
     , ca: null
    }

    if (options) {
        this.set(options)
    }
}

Client.prototype = {

    invalid:function(command) {
        var args = Array.prototype.slice.call(arguments, 1)
        ,   fn   = args.pop()

        if (typeof fn !== 'function') {
            fn = console.log
        }

        return fn(new Error('No such command "' + command  + '"'))
    },

    send:function(command) {
        var args = Array.prototype.slice.call(arguments, 1)
         ,  self = this
         ,  fn

        if (typeof args[args.length-1] === 'function') {
            fn = args.pop().bind(this)
        }else {
            fn = console.log
        }

        var rpcData = JSON.stringify({
            id:      new Date().getTime()
         ,  method:  command.toLowerCase()
         ,  params:  args
        })

        var options = this.opts
        options.headers['Content-Length'] = rpcData.length

        var request;
        if (options.https === true){
          request = https.request;
        } else{
          request = http.request;
        }

        var req = request(options, function(res) {
            var data = ''
            res.setEncoding('utf8')
            res.on('data', function(chunk) {
                data += chunk
            })
            res.on('end', function() {
                try {
                    data = JSON.parse(data)
                }catch(exception) {
                    var errMsg = res.statusCode !== 200
                        ? 'Invalid params ' + res.statusCode
                        : 'Failed to parse JSON'
                    errMsg += ' : '+JSON.stringify(data)
                    return fn(new Error(errMsg))
                }
                if (data.error) {
                    if (data.error.code === errors.RPC_WALLET_UNLOCK_NEEDED &&
                        options.passphrasecallback) {
                      return self.unlock(command, args, fn)
                    } else {
                      var err = new Error(JSON.stringify(data))
                      err.code = data.error.code
                      return fn(err)
                    }
                }
                fn(null, data.result !== null ? data.result : data)
            })
        })

        req.on('error', fn)
        req.end(rpcData)
        return this
    },

    exec:function(command) {
        var func = api.isCommand(command) ? 'send' : 'invalid'
        return this[func].apply(this, arguments)
    },

    auth:function(user, pass) {
        if (user && pass) {
            var authString = ('Basic ') + new Buffer(user+':'+pass).toString('base64')
            this.opts.headers['Authorization'] = authString
        }
      return this
    },

    unlock:function(command, args, fn) {
      var self = this

      var retry = function(err) {
        if (err) {
          fn(err)
        } else {
          var sendargs = args.slice();
          sendargs.unshift(command);
          sendargs.push(fn)
          self.send.apply(self, sendargs)
        }
      }

      this.opts.passphrasecallback(command, args, function(err, passphrase, timeout) {
        if (err) {
          fn(err)
        } else {
          self.send('walletpassphrase', passphrase, timeout, retry)
        }
      })
    },

    set:function(k, v) {
        var type = typeof(k);

        if (typeof(k) === 'object') {
            for (var key in k) {
                this.set(key, k[key]);
            };
            return;
        };

        var opts = this.opts;
        var k = k.toLowerCase();

        if (opts.hasOwnProperty(k)) {
            opts[k] = v
           if (/^(user|pass)$/.test(k)) {
                this.auth(opts.user, opts.pass)
             }else if (k === 'host') {
                opts.headers['Host'] = v
            }else if (k === 'passphrasecallback' ||
                      k === 'https' ||
                      k === 'ca') {
                opts[k] = v
            }
        }

        return this;
    },

    get:function(k) {
        //Special case for booleans
        if(this.opts[k] === false){
          return false;
        }else {
          if(this.opts[k] !== false){
            var opt = this.opts[k.toLowerCase()]
          }
          return  opt; //new Error('No such option "'+k+'" exists');
        }
    },

    errors: errors

}

api.commands.forEach(function(command) {
    var cp  = Client.prototype;
    var tlc = [command.toLowerCase()];

    cp[command] = cp[tlc] = function() {
        cp.send.apply(this, tlc.concat(([]).slice.call(arguments)));
    };
})

module.exports = function(options) {
    return new Client(options)
}
<commit_msg>Port Changes<commit_after>var http = require('http')
,   https = require('https')

var api  = require('./commands')
,   errors = require('./errors')

function Client(options) {
    this.opts = {
        host:    'localhost'
     ,  port:    12126
     ,  method:  'POST'
     ,  user:    '123'
     ,  pass:    '123'
     ,  headers:  {
            'Host': 'localhost'
         ,  'Authorization':  ''
       }
     , passphrasecallback: null
     , https: false
     , ca: null
    }

    if (options) {
        this.set(options)
    }
}

Client.prototype = {

    invalid:function(command) {
        var args = Array.prototype.slice.call(arguments, 1)
        ,   fn   = args.pop()

        if (typeof fn !== 'function') {
            fn = console.log
        }

        return fn(new Error('No such command "' + command  + '"'))
    },

    send:function(command) {
        var args = Array.prototype.slice.call(arguments, 1)
         ,  self = this
         ,  fn

        if (typeof args[args.length-1] === 'function') {
            fn = args.pop().bind(this)
        }else {
            fn = console.log
        }

        var rpcData = JSON.stringify({
            id:      new Date().getTime()
         ,  method:  command.toLowerCase()
         ,  params:  args
        })

        var options = this.opts
        options.headers['Content-Length'] = rpcData.length

        var request;
        if (options.https === true){
          request = https.request;
        } else{
          request = http.request;
        }

        var req = request(options, function(res) {
            var data = ''
            res.setEncoding('utf8')
            res.on('data', function(chunk) {
                data += chunk
            })
            res.on('end', function() {
                try {
                    data = JSON.parse(data)
                }catch(exception) {
                    var errMsg = res.statusCode !== 200
                        ? 'Invalid params ' + res.statusCode
                        : 'Failed to parse JSON'
                    errMsg += ' : '+JSON.stringify(data)
                    return fn(new Error(errMsg))
                }
                if (data.error) {
                    if (data.error.code === errors.RPC_WALLET_UNLOCK_NEEDED &&
                        options.passphrasecallback) {
                      return self.unlock(command, args, fn)
                    } else {
                      var err = new Error(JSON.stringify(data))
                      err.code = data.error.code
                      return fn(err)
                    }
                }
                fn(null, data.result !== null ? data.result : data)
            })
        })

        req.on('error', fn)
        req.end(rpcData)
        return this
    },

    exec:function(command) {
        var func = api.isCommand(command) ? 'send' : 'invalid'
        return this[func].apply(this, arguments)
    },

    auth:function(user, pass) {
        if (user && pass) {
            var authString = ('Basic ') + new Buffer(user+':'+pass).toString('base64')
            this.opts.headers['Authorization'] = authString
        }
      return this
    },

    unlock:function(command, args, fn) {
      var self = this

      var retry = function(err) {
        if (err) {
          fn(err)
        } else {
          var sendargs = args.slice();
          sendargs.unshift(command);
          sendargs.push(fn)
          self.send.apply(self, sendargs)
        }
      }

      this.opts.passphrasecallback(command, args, function(err, passphrase, timeout) {
        if (err) {
          fn(err)
        } else {
          self.send('walletpassphrase', passphrase, timeout, retry)
        }
      })
    },

    set:function(k, v) {
        var type = typeof(k);

        if (typeof(k) === 'object') {
            for (var key in k) {
                this.set(key, k[key]);
            };
            return;
        };

        var opts = this.opts;
        var k = k.toLowerCase();

        if (opts.hasOwnProperty(k)) {
            opts[k] = v
           if (/^(user|pass)$/.test(k)) {
                this.auth(opts.user, opts.pass)
             }else if (k === 'host') {
                opts.headers['Host'] = v
            }else if (k === 'passphrasecallback' ||
                      k === 'https' ||
                      k === 'ca') {
                opts[k] = v
            }
        }

        return this;
    },

    get:function(k) {
        //Special case for booleans
        if(this.opts[k] === false){
          return false;
        }else {
          if(this.opts[k] !== false){
            var opt = this.opts[k.toLowerCase()]
          }
          return  opt; //new Error('No such option "'+k+'" exists');
        }
    },

    errors: errors

}

api.commands.forEach(function(command) {
    var cp  = Client.prototype;
    var tlc = [command.toLowerCase()];

    cp[command] = cp[tlc] = function() {
        cp.send.apply(this, tlc.concat(([]).slice.call(arguments)));
    };
})

module.exports = function(options) {
    return new Client(options)
}
<|endoftext|>


<commit_before>var QUERIES = (function(){
	var query_types = ["NumClusters", "NumClusteredElems", "MeanClusterSize",
	                   "PercentInTop4", "PercentInTop", "ClustersTo90", "Cohesion","Separation",
	                   "NoiseLevel", "MirrorCohesion", "MinimumMeanSeparation",
	                   "Silhouette", "Calinski-Harabasz", "Dunn", "Davies-Bouldin",
	                   "CythonMirrorCohesion", "CythonMinimumMeanSeparation",
	                   "CythonSilhouette", "RatioCut", "NCut",
	                   "CythonNormNCut", "NormNCut", "MinMaxCut",
	                   "PCAanalysis", "Details"];

	var criteria_types = ["MeanClusterSize", "CythonMirrorCohesion", "Separation",
	                      "CythonMinimumMeanSeparation",
	                      "Calinski-Harabasz", "Dunn",, "Davies-Bouldin",
	                      "CythonSilhouette", "RatioCut", "NCut",
	                      "CythonNormNCut", "MinMaxCut", "PCAanalysis" ];

	return {
		query_types:query_types,
		criteria_types:criteria_types
	}
}());
<commit_msg>added GaussianSeparation to queries<commit_after>var QUERIES = (function(){
	var query_types = ["NumClusters", "NumClusteredElems", "MeanClusterSize",
	                   "PercentInTop4", "PercentInTop", "ClustersTo90", "Cohesion",
	                   "Separation","GaussianSeparation",
	                   "NoiseLevel", "MirrorCohesion", "MinimumMeanSeparation",
	                   "Silhouette", "Calinski-Harabasz", "Dunn", "Davies-Bouldin",
	                   "CythonMirrorCohesion", "CythonMinimumMeanSeparation",
	                   "CythonSilhouette", "RatioCut", "NCut",
	                   "CythonNormNCut", "NormNCut", "MinMaxCut",
	                   "PCAanalysis", "Details"];

	var criteria_types = ["MeanClusterSize", "CythonMirrorCohesion",
	                      "Separation", "GaussianSeparation",
	                      "CythonMinimumMeanSeparation",
	                      "Calinski-Harabasz", "Dunn",, "Davies-Bouldin",
	                      "CythonSilhouette", "RatioCut", "NCut",
	                      "CythonNormNCut", "MinMaxCut", "PCAanalysis" ];

	return {
		query_types:query_types,
		criteria_types:criteria_types
	}
}());
<|endoftext|>