<commit_before>/*
 * @license
 * Copyright 2016 Google Inc. 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.
 */

/**
 * Context Support
 *
 * Contexts, also known as frames, scopes or environments, are used to store
 * named resources. They provide an object-oriented replacement for global
 * variables. Contexts are immutable. New bindings are added by creating
 * "sub-contexts" with new bindings, from an existing parent context.
 * Sub-contexts inherit bindings from their parent.
 *
 * Contexts provide a form of inversion-of-control or dependendency-injection.
 * Normally, contexts are not explicitly used because FOAM's imports/exports
 * mechanism provides a high-level declarative method of dependency management
 * which hides their use.
 *
 * foam.__context__ references the root context, which is the ancestor of all other
 * contexts.
 */

(function() {
  var __context__ = {
    // Temporary: gets replaced in Window.js.
    assert: function(b) { console.assert.apply(console, arguments); return b; },

    /**
     * Lookup a class in the context.  Throws an exception if the value
     * couldn't be found, unless opt_suppress is true.
     *
     * @param id The id of the class to lookup.
     * @param opt_suppress Suppress throwing an error.
     **/
    lookup: function(id, opt_suppress) {
      var ret = typeof id === 'string' && this.__cache__[id];

      if ( ! opt_suppress ) {
        this.assert(
            ret,
            'Could not find any registered class for ' + id);
      }

      return ret;
    },

    /**
     * Register a class into the given context.  After registration
     * the class can be found again by calling foam.lookup('com.foo.SomeClass');
     *
     * @param cls    The class to register.
     * @param opt_id Optional id under which to register class.
     */
    register: function(cls, opt_id) {
      this.assert(
        typeof cls === 'object',
        'Cannot register non-objects into a context.');

      function doRegister(cache, name) {
        console.assert(
          cache.hasOwnProperty(name) === false,
          cls.id + ' is already registerd in this context.');

        cache[name] = cls;
      }

      if ( opt_id ) {
        doRegister(this.__cache__, opt_id);
      } else {
        this.assert(
            typeof cls.id === 'string',
            'Must have an .id property to be registered in a context.');

        doRegister(this.__cache__, cls.id);

        if ( cls.package === 'foam.core' ) {
          doRegister(this.__cache__, cls.name);
        }
      }
    },

    /**
     * Creates a sub context of the context that this is called upon.
     * @param opt_args A map of bindings to set up in the sub context.
     *     Currently unused.
     */
    createSubContext: function createSubContext(opt_args, opt_name) {
      if ( ! opt_args ) return this;

      this.assert(
          opt_name === undefined || typeof opt_name === 'string',
          'opt_name must be left undefined or be a string.');

      var sub = Object.create(this);

      if ( opt_name ) {
        Object.defineProperty(sub, 'NAME', {
          value: opt_name,
          enumerable: false
        });
      }

      for ( var key in opt_args ) {
        if ( opt_args.hasOwnProperty(key) ) {
          var v = opt_args[key];

          if ( ! foam.core.Slot.isInstance(v) ) {
            sub[key + '$'] = foam.core.ConstantSlot.create({ value: v });

            (function(v) {
              Object.defineProperty(sub, key, {
                value: v,
                enumerable: false
              });
            })(v);
          } else {
            sub[key + '$'] = v;

            (function(v) {
              Object.defineProperty(sub, key, {
                get: function() { return v.get(); },
                enumerable: false
              });
            })(v);
          }

        }
      }

      Object.defineProperty(sub, '__cache__', {
        value: Object.create(this.__cache__),
        enumerable: false
      });

      sub.$UID__ = foam.next$UID();
//      Object.freeze(sub);

      return sub;
    }
  };

  Object.defineProperty(__context__, '__cache__', {
    value: {},
    enumerable: false
  });

  // Create short-cuts for foam.__context__.[createSubContext, register, lookup]
  // in foam.
  foam.lookup = function(id, opt_suppress) {
    return foam.__context__.lookup(id, opt_suppress);
  };
  foam.register = function(cls) { foam.__context__.register(cls); };
  foam.createSubContext = function(opt_args, opt_name) {
    return foam.__context__.createSubContext(opt_args, opt_name);
  };

  foam.__context__ = __context__;
})();
<commit_msg>Add memoization to slot name creation.<commit_after>/*
 * @license
 * Copyright 2016 Google Inc. 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.
 */

/**
 * Context Support
 *
 * Contexts, also known as frames, scopes or environments, are used to store
 * named resources. They provide an object-oriented replacement for global
 * variables. Contexts are immutable. New bindings are added by creating
 * "sub-contexts" with new bindings, from an existing parent context.
 * Sub-contexts inherit bindings from their parent.
 *
 * Contexts provide a form of inversion-of-control or dependendency-injection.
 * Normally, contexts are not explicitly used because FOAM's imports/exports
 * mechanism provides a high-level declarative method of dependency management
 * which hides their use.
 *
 * foam.__context__ references the root context, which is the ancestor of all other
 * contexts.
 */

(function() {
  var __context__ = {
    // Temporary: gets replaced in Window.js.
    assert: function(b) { console.assert.apply(console, arguments); return b; },

    /**
     * Lookup a class in the context.  Throws an exception if the value
     * couldn't be found, unless opt_suppress is true.
     *
     * @param id The id of the class to lookup.
     * @param opt_suppress Suppress throwing an error.
     **/
    lookup: function(id, opt_suppress) {
      var ret = typeof id === 'string' && this.__cache__[id];

      if ( ! opt_suppress ) {
        this.assert(
            ret,
            'Could not find any registered class for ' + id);
      }

      return ret;
    },

    /**
     * Register a class into the given context.  After registration
     * the class can be found again by calling foam.lookup('com.foo.SomeClass');
     *
     * @param cls    The class to register.
     * @param opt_id Optional id under which to register class.
     */
    register: function(cls, opt_id) {
      this.assert(
        typeof cls === 'object',
        'Cannot register non-objects into a context.');

      function doRegister(cache, name) {
        console.assert(
          cache.hasOwnProperty(name) === false,
          cls.id + ' is already registerd in this context.');

        cache[name] = cls;
      }

      if ( opt_id ) {
        doRegister(this.__cache__, opt_id);
      } else {
        this.assert(
            typeof cls.id === 'string',
            'Must have an .id property to be registered in a context.');

        doRegister(this.__cache__, cls.id);

        if ( cls.package === 'foam.core' ) {
          doRegister(this.__cache__, cls.name);
        }
      }
    },

    toSlotName_: foam.Function.memoize1(function toSlotName_(key) {
      return key + '$';
    }),

    /**
     * Creates a sub context of the context that this is called upon.
     * @param opt_args A map of bindings to set up in the sub context.
     *     Currently unused.
     */
    createSubContext: function createSubContext(opt_args, opt_name) {
      if ( ! opt_args ) return this;

      this.assert(
          opt_name === undefined || typeof opt_name === 'string',
          'opt_name must be left undefined or be a string.');

      var sub = Object.create(this);

      if ( opt_name ) {
        Object.defineProperty(sub, 'NAME', {
          value: opt_name,
          enumerable: false
        });
      }

      for ( var key in opt_args ) {
        if ( opt_args.hasOwnProperty(key) ) {
          var v = opt_args[key];

          if ( ! foam.core.Slot.isInstance(v) ) {
            sub[this.toSlotName_(key)] = foam.core.ConstantSlot.create({ value: v });

            (function(v) {
              Object.defineProperty(sub, key, {
                value: v,
                enumerable: false
              });
            })(v);
          } else {
            sub[this.toSlotName_(key)] = v;

            (function(v) {
              Object.defineProperty(sub, key, {
                get: function() { return v.get(); },
                enumerable: false
              });
            })(v);
          }
        }
      }

      Object.defineProperty(sub, '__cache__', {
        value: Object.create(this.__cache__),
        enumerable: false
      });

      sub.$UID__ = foam.next$UID();
//      Object.freeze(sub);

      return sub;
    }
  };

  Object.defineProperty(__context__, '__cache__', {
    value: {},
    enumerable: false
  });

  // Create short-cuts for foam.__context__.[createSubContext, register, lookup]
  // in foam.
  foam.lookup = function(id, opt_suppress) {
    return foam.__context__.lookup(id, opt_suppress);
  };
  foam.register = function(cls) { foam.__context__.register(cls); };
  foam.createSubContext = function(opt_args, opt_name) {
    return foam.__context__.createSubContext(opt_args, opt_name);
  };

  foam.__context__ = __context__;
})();
<|endoftext|>


<commit_before>const CLINICAL_ANALYSIS_PORTAL_SETTINGS = {
    title: "Case Portal",
    icon: "fas fa-window-restore",
    menu: {
        // merge criterium: internal sections and filters are used to hydrates the external filters list for each section (which is a list of string). Sections and filter order is respected.
        sections: [
            {
                filters: ["id", "family", "proband", "sample", "status", "priority", "type", "date"],
            },
        ],
        // merge criterium: full outer join-like. it adds objects presents in internal array only and in external array only. In case of same id, the external value overwrite the internal.
        examples: [
            /* {
                id: "Intellectual disability2",
                active: false,
                query: {
                    disorder: "Intellectual disability"
                }
            }*/
        ],
    },
    table: {
        // merge criterium: spread operator
        toolbar: {
            showColumns: true,
            showCreate: true,
            showExport: false,
            showDownload: true,
            // columns list for the dropdown will be added in grid components based on settings.table.columns
        },
        // merge criterium: uses this array as filter for internal 1D/2D array. It handles row/col span
        // It is supported either columns[] or hiddenColumns[].
        // TODO NOTE this refers to clinical-analysis-grid (same list in clinical-analysis-browser.settings)
        // columns: ["caseId", "probandId", "familyId", "disorderId", "interpretation", "actions"]
    },
    details: ["clinical-analysis-view"],
};
<commit_msg>iva: hide create case button in case portal settings #TASK-993<commit_after>const CLINICAL_ANALYSIS_PORTAL_SETTINGS = {
    title: "Case Portal",
    icon: "fas fa-window-restore",
    menu: {
        // merge criterium: internal sections and filters are used to hydrates the external filters list for each section (which is a list of string). Sections and filter order is respected.
        sections: [
            {
                filters: ["id", "family", "proband", "sample", "status", "priority", "type", "date"],
            },
        ],
        // merge criterium: full outer join-like. it adds objects presents in internal array only and in external array only. In case of same id, the external value overwrite the internal.
        examples: [
            /* {
                id: "Intellectual disability2",
                active: false,
                query: {
                    disorder: "Intellectual disability"
                }
            }*/
        ],
    },
    table: {
        // merge criterium: spread operator
        toolbar: {
            showColumns: true,
            showCreate: false,
            showExport: false,
            showDownload: true,
            // columns list for the dropdown will be added in grid components based on settings.table.columns
        },
        // merge criterium: uses this array as filter for internal 1D/2D array. It handles row/col span
        // It is supported either columns[] or hiddenColumns[].
        // TODO NOTE this refers to clinical-analysis-grid (same list in clinical-analysis-browser.settings)
        // columns: ["caseId", "probandId", "familyId", "disorderId", "interpretation", "actions"]
    },
    details: ["clinical-analysis-view"],
};
<|endoftext|>


<commit_before>var HTMLLinkElement = function

  // http://w3c.github.io/webcomponents/spec/imports/#h-interface-import

(tag) {

  var
    proxy = {}

  , link = document.querySelector // use CSS :any ?
      ('link[href*='+tag+'][rel=import]')

  , register = function (event, handler) { return (HTMLImports && !!! HTMLImports.useNative)
        ? HTMLImports.whenReady
            ( function (_) { return handler ({ target: link }); } ) // eww

        : link.addEventListener
            (event, handler); }

    Object
      .defineProperties (proxy, {

        'addEventListener': {
          writable: false,

          value: function (event, handler) {
            !!! link
              ? handler  ({ target: proxy })
              : register (event, handler)
          }
        }

// TODO: definition for onerror
//    , 'onerror':
//        { set (handler) {} }
      })

  return proxy
}

var TokenList = function (node) {

  this
    .sift (node)
    .map(this.tokenize, this)
};

TokenList.prototype.tokenize = function (node) {
    var this$1 = this;

  var
    insert = function (node) { return function (symbol) { return (this$1 [symbol] = this$1 [symbol] || []).push (node); }; }

  void (node.text = node.textContent)
    .match (/([^{]*?)(\w|#)(?=\})/g)
    .map (insert (node))
};

TokenList.prototype.sift = function (node) {

  var
    nodes = []
  , expression = /{(\w+|#)}/

  , visit = function (node) { return node.nodeType === Node.TEXT_NODE
        ? TEXT_NODE (node)
        : ELEMENT_NODE (node.attributes)
      && NodeFilter.FILTER_REJECT; } // We don't need 'em

  , TEXT_NODE = function (node) { return expression.test (node.textContent)
      && nodes.push (node); }

  , ELEMENT_NODE = function (attrs) { return Array
        .from (attrs)
        .map(function (attr) { return expression.test (attr.value) && nodes.push (attr); }); }

  , walker =
      document.createNodeIterator
        (node, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, visit)
        // by default breaks on template YAY! 🎉

  while (walker.nextNode ()) { 0 } // Walk all nodes and do nothing.

  return nodes
};

TokenList.prototype.bind = function (context) {
    var this$1 = this;

  var
    keys = Object.keys (this)

  , reset = function (symbol) { return this$1 [symbol].map
        (function (node) { return (node.textContent = node.text) && symbol; }); }

  , replace =
      function (symbol, token) {
            if ( token === void 0 ) token = '{'+symbol+'}';

            return function (item) { return (item.textContent = item.textContent.replace (token, context [symbol])); };
    }

  keys.map (reset)

  for (var symbol$1 in this$1)
    { this$1 [symbol$1]
      .map (replace (symbol$1)) }
};

// INTERESTING! Converting `Template` to a class increases size by ~16 octets

var HTMLTemplateElement = Template = function (name) {

  // create shallow clone using `.getOwnPropertyDescriptors`
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors#Examples
  // https://docs.microsoft.com/en-us/scripting/javascript/reference/object-getownpropertydescriptor-function-javascript
  return Object.assign
    (document.querySelector ('template[name='+name+']'), { bind: bind } )

  function bind (context) {
    var this$1 = this;

    contexts = (ref = []).concat.apply ( ref, [context] )

    var
      clone
    , template = this.cloneNode (false)

    template.innerHTML =
    contexts
      .map (function (context) { return context; })
      .map (function (context, index) {

      context =
        (typeof context  === 'object') ? context : { self: context }

      context ['#'] = index

      clone  = this$1.cloneNode (true)

      void (new TokenList (clone.content))
        .bind (context)

      return clone.innerHTML // immutable snapshot
    })
    .join ('')

    void (this.dependents || [])
      .map (function (dependent) { return dependent.remove (); })

    this.dependents =
      Array.from
        (template.content.childNodes)

    this.after ( template.content )

    return this
    var ref;
  }
}

var EventTarget = function (HTMLElement) { return ((function (HTMLElement) {
    function anonymous () {
      HTMLElement.apply(this, arguments);
    }

    if ( HTMLElement ) anonymous.__proto__ = HTMLElement;
    anonymous.prototype = Object.create( HTMLElement && HTMLElement.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.on = function ( event, handler ) {

    this.addEventListener
      (event, this.renderable (handler))
  };

  anonymous.prototype.renderable = function ( handler ) {
    var this$1 = this;

    return function (event, render) {
        if ( render === void 0 ) render = true;

        return (event.prevent = function (_) { return (render = false) && event.preventDefault (); })

      && handler.call (this$1, event) !== false // for `return false`

      && render && this$1.render ();
    } // check render availability
  };

    return anonymous;
  }(HTMLElement))); }

var ParentNode = function (Element) { return ((function (Element) {
    function anonymous () {
      Element.apply(this, arguments);
    }

    if ( Element ) anonymous.__proto__ = Element;
    anonymous.prototype = Object.create( Element && Element.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.selectAll = function (selector)
    { return this.querySelectorAll (selector) };

  anonymous.prototype.select = function (selector)
    // watch out for clobbering `HTMLInputElement.select ()`
    // https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select
    { return this.selectAll (selector) [0] };

    return anonymous;
  }(Element))); }

//function comb
//  // ElementTraversal interface
//  // https://www.w3.org/TR/ElementTraversal/#interface-elementTraversal
//
//(parent) {
//  if (parent.hasChildNodes())
//    for (let node = parent.firstChild; node; node = node.nextSibling)
//      comb (node)
//}

var GlobalEventHandlers = function (Element) { return ((function (Element) {
    function anonymous () {
      Element.apply(this, arguments);
    }

    if ( Element ) anonymous.__proto__ = Element;
    anonymous.prototype = Object.create( Element && Element.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.onconnect = function (event, document) {

    (document = event.target.import)
      && this.mirror (document.querySelector ('template'))

    Element.prototype.onconnect
      && Element.prototype.onconnect.call (this)

    this.tokens = new TokenList (this)
    this.render ()

    console.warn (this.innerHTML)
  };

  // Reflection - https://en.wikipedia.org/wiki/Reflection_(computer_programming)
  // Type Introspection - https://en.wikipedia.org/wiki/Type_introspection
  //
  // In computing, type introspection is the ability of a program
  // to examine the type or properties of an object at runtime.
  // Some programming languages possess this capability.
  //
  // Introspection should not be confused with reflection,
  // which goes a step further and is the ability for a program to manipulate the values,
  // meta-data, properties and/or functions of an object at runtime.

  anonymous.prototype.reflect = function (handler, name) {
    ( name = ( handler.match (/^on(.+)$/) || [] ) [1] )

    && Object.keys // ensure W3C on event
     ( HTMLElement.prototype )
       .includes ( handler )

    && this.on (name, this [handler])
  };

  anonymous.prototype.register = function (node) {
    var this$1 = this;

    var
      register = function (event, handler) { return (handler = /{\s*(\w+)\s*}/.exec (node [event]))

        && ( handler = this$1 [ (handler || []) [1] ] )
        && ( node [event] = this$1.renderable (handler) ); }

    Array
      .from (node.attributes)
      .map (function (attr) { return attr.name; })
      .filter (function (name) { return /^on/.test (name); })
      .map (register)
  };

    return anonymous;
  }(Element))); }

var Component = function (HTMLElement) { return ( (function (superclass) {
    function anonymous (context) {
  var this$1 = this;
 superclass.call (this)

    var
      descriptions =
        Object.getOwnPropertyDescriptors
          (HTMLElement.prototype)

    , bind = function (key) { return 'function' === typeof descriptions [key].value
        && (this$1 [key] = this$1 [key].bind (this$1)); }

    Object
      .keys (descriptions)
      .map (bind)

    Object
      .getOwnPropertyNames (HTMLElement.prototype)
      .map (this.reflect, this)

    this.context = this.context || {}
    this.initialize && this.initialize ()
  }

    if ( superclass ) anonymous.__proto__ = superclass;
    anonymous.prototype = Object.create( superclass && superclass.prototype );
    anonymous.prototype.constructor = anonymous;

  anonymous.prototype.connectedCallback = function () {

    HTMLLinkElement
      (this.tagName.toLowerCase ())
        .addEventListener ('load', this.onconnect.bind (this))
  };

  anonymous.prototype.render = function () {
    var this$1 = this;

    this.tokens.bind (this)

    Array
      .from
        (this.selectAll ('template[name]'))

      .map
        (function (template) { return template.getAttribute ('name'); })

      .map
        (function (name) { return (new Template (name)).bind (this$1 [name]); })

    Array
      .from (this.selectAll ('*'))

      .concat ([this])

      .map (this.register, this)

    superclass.prototype.onidle && superclass.prototype.onidle.call (this)
  };

  anonymous.prototype.mirror = function (template, insert) {
    var this$1 = this;

    template = template.cloneNode (true)

    insert = function (replacement, name, slot) { return (name = replacement.getAttribute ('slot')) &&

      (slot = template.content.querySelector ('slot[name='+name+']'))
         // prefer to use replaceWith however support is sparse
         // https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/replaceWith
         // using `Node.parentNode` - https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode
         // & `Node.replaceChid` - https://developer.mozilla.org/en-US/docs/Web/API/Node/replaceChild
         // as is defined in (ancient) W3C DOM Level 1,2,3
         .parentNode
         .replaceChild (replacement, slot); }

    for (var i = 0, list = this$1.selectAll ('[slot]'); i < list.length; i += 1)
      {
      var replacement = list[i];

      insert (replacement)
    }

    Array
      .from (template.attributes)

      // skip swapping attribute if setting exists
      .filter (function (attr) { return !!! this$1.getAttribute (attr.name); })

      .map  (function (attr) { return this$1.setAttribute (attr.name, attr.value); })

    this.innerHTML = template.innerHTML
  };

    return anonymous;
  }(( EventTarget ( ParentNode ( GlobalEventHandlers ( HTMLElement ))))))); }

var ElementPrototype = window.Element.prototype // see bottom of this file

var Element = function (tag) { return function (Element) { return (ref = window.customElements).define.apply
        ( ref, tag.concat( [Component (Element)] ))
        var ref;; }; }

// Assign `window.Element.prototype` in case of feature checking on `Element`
Element.prototype = ElementPrototype
  // http://2ality.com/2013/09/window.html
  // http://tobyho.com/2013/03/13/window-prop-vs-global-var
  // https://github.com/webcomponents/webcomponentsjs/blob/master/webcomponents-es5-loader.js#L19

<commit_msg>:muscle: bump distribution for dist/snuggsi.js<commit_after>var HTMLLinkElement = function

  // http://w3c.github.io/webcomponents/spec/imports/#h-interface-import

(tag) {

  var
    proxy = {}

  , link = document.querySelector // use CSS :any ?
      ('link[href*='+tag+'][rel=import]')

  , register = function (event, handler) { return (HTMLImports && !!! HTMLImports.useNative)
        ? HTMLImports.whenReady
            ( function (_) { return handler ({ target: link }); } ) // eww

        : link.addEventListener
            (event, handler); }

    Object
      .defineProperties (proxy, {

        'addEventListener': {
          writable: false,

          value: function (event, handler) {
            !!! link
              ? handler  ({ target: proxy })
              : register (event, handler)
          }
        }

// TODO: definition for onerror
//    , 'onerror':
//        { set (handler) {} }
      })

  return proxy
}

var TokenList = function (node) {

  this
    .sift (node)
    .map(this.tokenize, this)
};

TokenList.prototype.tokenize = function (node) {
    var this$1 = this;

  var
    insert = function (node) { return function (symbol) { return (this$1 [symbol] = this$1 [symbol] || []).push (node); }; }

  void (node.text = node.textContent)
    .match (/([^{]*?)(\w|#)(?=\})/g)
    .map (insert (node))
};

TokenList.prototype.sift = function (node) {

  var
    nodes = []
  , expression = /{(\w+|#)}/

  , visit = function (node) { return node.nodeType === Node.TEXT_NODE
        ? TEXT_NODE (node)
        : ELEMENT_NODE (node.attributes)
      && NodeFilter.FILTER_REJECT; } // We don't need 'em

  , TEXT_NODE = function (node) { return expression.test (node.textContent)
      && nodes.push (node); }

  , ELEMENT_NODE = function (attrs) { return Array
        .from (attrs)
        .map(function (attr) { return expression.test (attr.value) && nodes.push (attr); }); }

  , walker =
      document.createNodeIterator
        (node, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, visit)
        // by default breaks on template YAY! 🎉

  while (walker.nextNode ()) { 0 } // Walk all nodes and do nothing.

  return nodes
};

TokenList.prototype.bind = function (context) {
    var this$1 = this;

  var
    keys = Object.keys (this)

  , reset = function (symbol) { return this$1 [symbol].map
        (function (node) { return (node.textContent = node.text) && symbol; }); }

  , replace =
      function (symbol, token) {
            if ( token === void 0 ) token = '{'+symbol+'}';

            return function (item) { return (item.textContent = item.textContent.replace (token, context [symbol])); };
    }

  keys.map (reset)

  for (var symbol$1 in this$1)
    { this$1 [symbol$1]
      .map (replace (symbol$1)) }
};

// INTERESTING! Converting `Template` to a class increases size by ~16 octets

var HTMLTemplateElement = Template = function (name) {

  // create shallow clone using `.getOwnPropertyDescriptors`
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors#Examples
  // https://docs.microsoft.com/en-us/scripting/javascript/reference/object-getownpropertydescriptor-function-javascript
  return Object.assign
    (document.querySelector ('template[name='+name+']'), { bind: bind } )

  function bind (context) {
    var this$1 = this;

    contexts = (ref = []).concat.apply ( ref, [context] )

    var
      clone
    , template = this.cloneNode (false)

    template.innerHTML =
    contexts
      .map (function (context) { return context; })
      .map (function (context, index) {

      context =
        (typeof context  === 'object') ? context : { self: context }

      context ['#'] = index

      clone  = this$1.cloneNode (true)

      void (new TokenList (clone.content))
        .bind (context)

      return clone.innerHTML // immutable snapshot
    })
    .join ('')

    void (this.dependents || [])
      .map (function (dependent) { return dependent.remove (); })

    this.dependents =
      Array.from
        (template.content.childNodes)

    this.after ( template.content )

    return this
    var ref;
  }
}

var EventTarget = function (HTMLElement) { return ((function (HTMLElement) {
    function anonymous () {
      HTMLElement.apply(this, arguments);
    }

    if ( HTMLElement ) anonymous.__proto__ = HTMLElement;
    anonymous.prototype = Object.create( HTMLElement && HTMLElement.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.on = function ( event, handler ) {

    this.addEventListener
      (event, this.renderable (handler))
  };

  anonymous.prototype.renderable = function ( handler ) {
    var this$1 = this;

    return function (event, render) {
        if ( render === void 0 ) render = true;

        return (event.prevent = function (_) { return (render = false) && event.preventDefault (); })

      && handler.call (this$1, event) !== false // for `return false`

      && render && this$1.render ();
    } // check render availability
  };

    return anonymous;
  }(HTMLElement))); }

var ParentNode = function (Element) { return ((function (Element) {
    function anonymous () {
      Element.apply(this, arguments);
    }

    if ( Element ) anonymous.__proto__ = Element;
    anonymous.prototype = Object.create( Element && Element.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.selectAll = function (selector)
    { return this.querySelectorAll (selector) };

  anonymous.prototype.select = function (selector)
    // watch out for clobbering `HTMLInputElement.select ()`
    // https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select
    { return this.selectAll (selector) [0] };

    return anonymous;
  }(Element))); }

//function comb
//  // ElementTraversal interface
//  // https://www.w3.org/TR/ElementTraversal/#interface-elementTraversal
//
//(parent) {
//  if (parent.hasChildNodes())
//    for (let node = parent.firstChild; node; node = node.nextSibling)
//      comb (node)
//}

var GlobalEventHandlers = function (Element) { return ((function (Element) {
    function anonymous () {
      Element.apply(this, arguments);
    }

    if ( Element ) anonymous.__proto__ = Element;
    anonymous.prototype = Object.create( Element && Element.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.onconnect = function (event, document) {

    (document = event.target.import)
      && this.mirror (document.querySelector ('template'))

    Element.prototype.onconnect
      && Element.prototype.onconnect.call (this)

    this.tokens = new TokenList (this)
    this.render ()
  };

  // Reflection - https://en.wikipedia.org/wiki/Reflection_(computer_programming)
  // Type Introspection - https://en.wikipedia.org/wiki/Type_introspection
  //
  // In computing, type introspection is the ability of a program
  // to examine the type or properties of an object at runtime.
  // Some programming languages possess this capability.
  //
  // Introspection should not be confused with reflection,
  // which goes a step further and is the ability for a program to manipulate the values,
  // meta-data, properties and/or functions of an object at runtime.

  anonymous.prototype.reflect = function (handler, name) {
    ( name = ( handler.match (/^on(.+)$/) || [] ) [1] )

    && Object.keys // ensure W3C on event
     ( HTMLElement.prototype )
       .includes ( handler )

    && this.on (name, this [handler])
  };

  anonymous.prototype.register = function (node) {
    var this$1 = this;

    var
      register = function (event, handler) { return (handler = /{\s*(\w+)\s*}/.exec (node [event]))

        && ( handler = this$1 [ (handler || []) [1] ] )
        && ( node [event] = this$1.renderable (handler) ); }

    Array
      .from (node.attributes)
      .map (function (attr) { return attr.name; })
      .filter (function (name) { return /^on/.test (name); })
      .map (register)
  };

    return anonymous;
  }(Element))); }

var Component = function (HTMLElement) { return ( (function (superclass) {
    function anonymous (context) {
  var this$1 = this;
 superclass.call (this)

    var
      descriptions =
        Object.getOwnPropertyDescriptors
          (HTMLElement.prototype)

    , bind = function (key) { return 'function' === typeof descriptions [key].value
        && (this$1 [key] = this$1 [key].bind (this$1)); }

    Object
      .keys (descriptions)
      .map (bind)

    Object
      .getOwnPropertyNames (HTMLElement.prototype)
      .map (this.reflect, this)

    this.context = this.context || {}
    this.initialize && this.initialize ()
  }

    if ( superclass ) anonymous.__proto__ = superclass;
    anonymous.prototype = Object.create( superclass && superclass.prototype );
    anonymous.prototype.constructor = anonymous;

  anonymous.prototype.connectedCallback = function () {

    HTMLLinkElement
      (this.tagName.toLowerCase ())
        .addEventListener ('load', this.onconnect.bind (this))
  };

  anonymous.prototype.render = function () {
    var this$1 = this;

    this.tokens.bind (this)

    Array
      .from
        (this.selectAll ('template[name]'))

      .map
        (function (template) { return template.getAttribute ('name'); })

      .map
        (function (name) { return (new Template (name)).bind (this$1 [name]); })

    Array
      .from (this.selectAll ('*'))

      .concat ([this])

      .map (this.register, this)

    superclass.prototype.onidle && superclass.prototype.onidle.call (this)
  };

  anonymous.prototype.mirror = function (template, insert) {
    var this$1 = this;

    template = template.cloneNode (true)

    insert = function (replacement, name, slot) { return (name = replacement.getAttribute ('slot')) &&

      (slot = template.content.querySelector ('slot[name='+name+']'))
         // prefer to use replaceWith however support is sparse
         // https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/replaceWith
         // using `Node.parentNode` - https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode
         // & `Node.replaceChid` - https://developer.mozilla.org/en-US/docs/Web/API/Node/replaceChild
         // as is defined in (ancient) W3C DOM Level 1,2,3
         .parentNode
         .replaceChild (replacement, slot); }

    for (var i = 0, list = this$1.selectAll ('[slot]'); i < list.length; i += 1)
      {
      var replacement = list[i];

      insert (replacement)
    }

    Array
      .from (template.attributes)

      // skip swapping attribute if setting exists
      .filter (function (attr) { return !!! this$1.getAttribute (attr.name); })

      .map  (function (attr) { return this$1.setAttribute (attr.name, attr.value); })

    this.innerHTML = template.innerHTML
  };

    return anonymous;
  }(( EventTarget ( ParentNode ( GlobalEventHandlers ( HTMLElement ))))))); }

var ElementPrototype = window.Element.prototype // see bottom of this file

var Element = function (tag) { return function (Element) { return (ref = window.customElements).define.apply
        ( ref, tag.concat( [Component (Element)] ))
        var ref;; }; }

// Assign `window.Element.prototype` in case of feature checking on `Element`
Element.prototype = ElementPrototype
  // http://2ality.com/2013/09/window.html
  // http://tobyho.com/2013/03/13/window-prop-vs-global-var
  // https://github.com/webcomponents/webcomponentsjs/blob/master/webcomponents-es5-loader.js#L19

<|endoftext|>


<commit_before>textToGame = function(text, seed) {
	var game = JSON.parse(text)

	if (game.version != 11) {
		alert("Invalid version number: " + json_game.version);
	}

	//Adds determinism (when used with https://github.com/davidbau/seedrandom) to color scramble.
	console.log(seed);
	Math.seedrandom(seed);

	//Hardcoding colors:
	var colors = [];
	colors.push('0xe37222'); //TS Orange
	colors.push('0x63ceca'); //TS Mid Teal
	//colors.push('0x002226'); //TS Midnight Teal
	colors.push('0xffbe00'); //TS Yellow
	colors.push('0xff0000');
	colors.push('0x00cc00');
	colors.push('0xaa4444');
	colors.push('0x9900ff');
	colors.push('0xff66ff');

	var x, i;
	for (i = colors.length; i; i--) {
		var j = Math.floor(Math.random() * i);
		x = colors[i - 1];
		colors[i - 1] = colors[j];
		colors[j] = x;
	}

	game.players = []
	game.players.push({name: 'NULL', color: "0x888888"});
	for(i = 0; i < game.num_players; i++) {
		game.players.push({name: game.player_names[i], color: colors[i] });
		console.log(game.players[game.players.length - 1].color);
	}
	delete game.player_names;

	console.log(game.players);

	var maxProd = 0;
	for(var a = 0; a < game.height; a++) {
		for(var b = 0; b < game.width; b++) {
			if(game.productions[a][b] > maxProd) maxProd = game.productions[a][b];
		}
	}

	game.productionNormals = []
	for(var a = 0; a < game.height; a++) {
		var row = []
		for(var b = 0; b < game.width; b++) {
			row.push(game.productions[a][b] / maxProd);
		}
		game.productionNormals.push(row)
	}

	for(var a = 0; a < game.num_frames; a++) {
		for(var b = 0; b < game.height; b++) {
			for(var c = 0; c < game.width; c++) {
				var array = game.frames[a][b][c];
				game.frames[a][b][c] = { owner: array[0], strength: array[1] };
			}
		}
	}

	//Get game statistics:
	for(var a = 1; a <= game.num_players; a++) {
		game.players[a].territories = [];
		game.players[a].productions = [];
		game.players[a].strengths = [];
		for(var b = 0; b < game.num_frames; b++) {
			var ter = 0, prod = 0, str = 0;
			for(var c = 0; c < game.height; c++) for(var d = 0; d < game.width; d++) {
				if(game.frames[b][c][d].owner == a) {
					ter++;
					prod += game.productions[c][d];
					str += game.frames[b][c][d].strength;
				}
			}
			game.players[a].territories.push(ter);
			game.players[a].productions.push(prod);
			game.players[a].strengths.push(str);
		}
	}

	//Normalize game statistics for display
	var maxPlayerTer = 0, maxPlayerProd = 0, maxPlayerStr = 0;
	for(var a = 1; a <= game.num_players; a++) {
		for(var b = 0; b < game.num_frames; b++) {
			if(game.players[a].territories[b] > maxPlayerTer) maxPlayerTer = game.players[a].territories[b];
			if(game.players[a].productions[b] > maxPlayerProd) maxPlayerProd = game.players[a].productions[b];
			if(game.players[a].strengths[b] > maxPlayerStr) maxPlayerStr = game.players[a].strengths[b];
		}
	}
	for(var a = 1; a <= game.num_players; a++) {
		game.players[a].normTers = [];
		game.players[a].normProds = [];
		game.players[a].normStrs = [];
		for(var b = 0; b < game.num_frames; b++) {
			game.players[a].normTers.push(game.players[a].territories[b] / maxPlayerTer);
			game.players[a].normProds.push(game.players[a].productions[b] / maxPlayerProd);
			game.players[a].normStrs.push(game.players[a].strengths[b] / maxPlayerStr);
		}
	}

	return game
}
<commit_msg>Use a colorblind safe palatte for the visualizer.<commit_after>textToGame = function(text, seed) {
	var game = JSON.parse(text)

	if (game.version != 11) {
		alert("Invalid version number: " + json_game.version);
	}

	//Adds determinism (when used with https://github.com/davidbau/seedrandom) to color scramble.
	console.log(seed);
	Math.seedrandom(seed);

	//Hardcoding colors:
    var colors = ['0x6DB6FF',
                  '0x490092',
                  '0x24ff24',
                  '0x009292',
                  '0xFFB677',
                  '0xffff6d',
                  '0xB66DFF',
                  '0x924900',
                 ];

	var x, i;
	for (i = colors.length; i; i--) {
		var j = Math.floor(Math.random() * i);
		x = colors[i - 1];
		colors[i - 1] = colors[j];
		colors[j] = x;
	}

	game.players = []
	game.players.push({name: 'NULL', color: "0x888888"});
	for(i = 0; i < game.num_players; i++) {
		game.players.push({name: game.player_names[i], color: colors[i] });
		console.log(game.players[game.players.length - 1].color);
	}
	delete game.player_names;

	console.log(game.players);

	var maxProd = 0;
	for(var a = 0; a < game.height; a++) {
		for(var b = 0; b < game.width; b++) {
			if(game.productions[a][b] > maxProd) maxProd = game.productions[a][b];
		}
	}

	game.productionNormals = []
	for(var a = 0; a < game.height; a++) {
		var row = []
		for(var b = 0; b < game.width; b++) {
			row.push(game.productions[a][b] / maxProd);
		}
		game.productionNormals.push(row)
	}

	for(var a = 0; a < game.num_frames; a++) {
		for(var b = 0; b < game.height; b++) {
			for(var c = 0; c < game.width; c++) {
				var array = game.frames[a][b][c];
				game.frames[a][b][c] = { owner: array[0], strength: array[1] };
			}
		}
	}

	//Get game statistics:
	for(var a = 1; a <= game.num_players; a++) {
		game.players[a].territories = [];
		game.players[a].productions = [];
		game.players[a].strengths = [];
		for(var b = 0; b < game.num_frames; b++) {
			var ter = 0, prod = 0, str = 0;
			for(var c = 0; c < game.height; c++) for(var d = 0; d < game.width; d++) {
				if(game.frames[b][c][d].owner == a) {
					ter++;
					prod += game.productions[c][d];
					str += game.frames[b][c][d].strength;
				}
			}
			game.players[a].territories.push(ter);
			game.players[a].productions.push(prod);
			game.players[a].strengths.push(str);
		}
	}

	//Normalize game statistics for display
	var maxPlayerTer = 0, maxPlayerProd = 0, maxPlayerStr = 0;
	for(var a = 1; a <= game.num_players; a++) {
		for(var b = 0; b < game.num_frames; b++) {
			if(game.players[a].territories[b] > maxPlayerTer) maxPlayerTer = game.players[a].territories[b];
			if(game.players[a].productions[b] > maxPlayerProd) maxPlayerProd = game.players[a].productions[b];
			if(game.players[a].strengths[b] > maxPlayerStr) maxPlayerStr = game.players[a].strengths[b];
		}
	}
	for(var a = 1; a <= game.num_players; a++) {
		game.players[a].normTers = [];
		game.players[a].normProds = [];
		game.players[a].normStrs = [];
		for(var b = 0; b < game.num_frames; b++) {
			game.players[a].normTers.push(game.players[a].territories[b] / maxPlayerTer);
			game.players[a].normProds.push(game.players[a].productions[b] / maxPlayerProd);
			game.players[a].normStrs.push(game.players[a].strengths[b] / maxPlayerStr);
		}
	}

	return game
}
<|endoftext|>


<commit_before>import EventEmitter from 'events';
import keyMirror from 'keymirror';
import dialog from 'dialog';
import shell from 'shell';

import manifest from '../../../package.json';
import AutoUpdater from '../components/auto-updater';
import platform from '../utils/platform';
import prefs from '../utils/prefs';

const STATES = keyMirror({
  IDLE: null,
  UPDATE_CHECKING: null,
  UPDATE_AVAILABLE: null,
  UPDATE_DOWNLOADED: null
});

const IGNORED_ERRORS = [
  'The request timed out.',
  'The network connection was lost.',
  'Se ha agotado el tiempo de espera.',
  'An SSL error has occurred and a secure connection to the server cannot be made.',
  'Update download failed',
  'getaddrinfo EAI_AGAIN',
  'getaddrinfo ENOTFOUND',
  'connect ETIMEDOUT'
];

class AutoUpdateManager extends EventEmitter {

  constructor(manifest, options, mainWindowManager) {
    super();

    this.manifest = manifest;
    this.options = options;
    this.mainWindowManager = mainWindowManager;

    this.enabled = !this.options.mas && prefs.get('updates-auto-check');
    this.state = STATES.IDLE;
    this.states = STATES;

    this.latestVersion = null;
    this.latestDownloadUrl = null;
  }

  init() {
    log('starting auto updater');
    this.initFeedUrl();
    this.initErrorListener();
    this.initStateListeners();
    this.initVersionListener();
    this.initDownloadListener();
  }

  initFeedUrl() {
    let feedUrl = this.manifest.updater.urls[process.platform]
      .replace(/%CURRENT_VERSION%/g, this.manifest.version)
      .replace(/%CHANNEL%/g, prefs.get('updates-channel'));

    if (this.options.portable) {
      feedUrl += '/portable';
    }

    log('updater feed url:', feedUrl);
    AutoUpdater.setFeedURL(feedUrl);
  }

  initErrorListener() {
    AutoUpdater.on('error', (err) => {
      log('auto updater error');
      if (err.message && IGNORED_ERRORS.find(msg => err.message.includes(msg))) {
        log(err);
      } else {
        logError(err);
      }
    });
  }

  initStateListeners() {
    const eventToStateMap = {
      'error': STATES.IDLE,
      'checking-for-update': STATES.UPDATE_CHECKING,
      'update-available': STATES.UPDATE_AVAILABLE,
      'update-not-available': STATES.IDLE,
      'update-downloaded': STATES.UPDATE_DOWNLOADED
    };

    for (let [eventName, state] of Object.entries(eventToStateMap)) {
      AutoUpdater.on(eventName, () => this.state = state);
    }
  }

  initVersionListener() {
    AutoUpdater.on('update-available', (newVersion, downloadUrl) => {
      this.latestVersion = newVersion;
      this.latestDownloadUrl = downloadUrl;
    });
  }

  initDownloadListener() {
    if (platform.isWin && !this.options.portable) {
      AutoUpdater.on('update-downloaded', () => {
        dialog.showMessageBox({
          type: 'question',
          message: 'A new version of ' + manifest.productName + ' has been downloaded.',
          detail: 'Would you like to restart the app and install the update? You can do this later from the App menu.',
          buttons: ['Later', 'Update']
        }, (response) => {
          if (response === 1) {
            log('user clicked Update');
            this.quitAndInstall();
          }
        });
      });
    }
  }

  handleMenuCheckForUpdate() {
    this.checkForUpdate(false);
  }

  handleMenuUpdateAvailable() {
    this.onCheckUpdateAvailable(this.latestVersion, this.latestDownloadUrl);
  }

  handleMenuUpdateDownloaded() {
    this.quitAndInstall();
  }

  setAutoCheck(check) {
    if (this.enabled === check) {
      log('update checker already', check ? 'enabled' : 'disabled');
      return; // same state
    }

    this.enabled = !this.options.mas && check;
    if (this.enabled) { // disabled -> enabled
      log('enabling auto update checker');
      this.scheduleUpdateChecks();
    } else if (this.scheduledCheckerId) {  // enabled -> disabled
      log('disabling auto update checker');
      clearInterval(this.scheduledCheckerId);
      this.scheduledCheckerId = null;
    }
  }

  onCheckUpdateAvailable(newVersion, downloadUrl) {
    log('onCheckUpdateAvailable', 'newVersion:', newVersion, 'downloadUrl:', downloadUrl);
    if (platform.isLinux) {
      dialog.showMessageBox({
        type: 'info',
        message: 'A new version is available: ' + newVersion,
        detail: 'Use your package manager to update, or click Download to get the new package.',
        buttons: ['OK', 'Download']
      }, function(response) {
        if (response === 1) {
          log('user clicked Download, opening url', downloadUrl);
          shell.openExternal(downloadUrl);
        }
      });
    } else if (platform.isWin && this.options.portable) {
      dialog.showMessageBox({
        type: 'info',
        message: 'A new version is available: ' + newVersion,
        detail: 'Click Download to get a portable zip with the new version.',
        buttons: ['OK', 'Download']
      }, function(response) {
        if (response === 1) {
          log('user clicked Download, opening url', downloadUrl);
          shell.openExternal(downloadUrl);
        }
      });
    } else {
      dialog.showMessageBox({
        type: 'info',
        message: 'A new version is available.',
        detail: 'It will start downloading in the background.',
        buttons: ['OK']
      }, function() {});
    }
  }

  onCheckUpdateNotAvailable() {
    log('onCheckUpdateNotAvailable');
    dialog.showMessageBox({
      type: 'info',
      message: 'No update available.',
      detail: 'You are using the latest version: ' + this.manifest.version,
      buttons: ['OK']
    }, function() {});
  }

  onCheckError(err) {
    log('onCheckError:', err);
    let detailMessage;

    if (err.message && IGNORED_ERRORS.find(msg => err.message.includes(msg))) {
      detailMessage = manifest.productName + ' could not connect to the updates server.'
        + ' Please make sure you have a working internet connection.'
        + '\n\nERR: ' + err.message;
    } else {
      detailMessage = err.message;
    }

    dialog.showMessageBox({
      type: 'error',
      message: 'Error while checking for update.',
      detail: detailMessage,
      buttons: ['OK']
    }, function() {});
  }

  scheduleUpdateChecks() {
    const checkInterval = 1000 * 60 * 60 * 4; // 4 hours
    log('scheduling update checks every', checkInterval, 'ms');
    this.scheduledCheckerId = setInterval(::this.checkForUpdate, checkInterval);
    this.checkForUpdate();
  }

  checkForUpdate(silent = true) {
    log('checking for update...');
    AutoUpdater.checkForUpdates();

    if (!silent) {
      const onCheck = {};

      const removeListeners = () => {
        AutoUpdater.removeListener('update-available', onCheck.updateAvailable);
        AutoUpdater.removeListener('update-not-available', onCheck.updateNotAvailable);
        AutoUpdater.removeListener('error', onCheck.error);
      };

      onCheck.updateAvailable = () => {
        this.onCheckUpdateAvailable.apply(this, arguments);
        removeListeners();
      };

      onCheck.updateNotAvailable = () => {
        this.onCheckUpdateNotAvailable.apply(this, arguments);
        removeListeners();
      };

      onCheck.error = () => {
        this.onCheckError.apply(this, arguments);
        removeListeners();
      };

      AutoUpdater.once('update-available', onCheck.updateAvailable);
      AutoUpdater.once('update-not-available', onCheck.updateNotAvailable);
      AutoUpdater.once('error', onCheck.error);
    }
  }

  quitAndInstall() {
    if (this.mainWindowManager) {
      this.mainWindowManager.updateInProgress = true;
      AutoUpdater.quitAndInstall();
    } else {
      logError(new Error('cannot quit to install update'));
    }
  }

}

export default AutoUpdateManager;
<commit_msg>Add another ignored error message (aum)<commit_after>import EventEmitter from 'events';
import keyMirror from 'keymirror';
import dialog from 'dialog';
import shell from 'shell';

import manifest from '../../../package.json';
import AutoUpdater from '../components/auto-updater';
import platform from '../utils/platform';
import prefs from '../utils/prefs';

const STATES = keyMirror({
  IDLE: null,
  UPDATE_CHECKING: null,
  UPDATE_AVAILABLE: null,
  UPDATE_DOWNLOADED: null
});

const IGNORED_ERRORS = [
  'The request timed out.',
  'The network connection was lost.',
  'Se ha agotado el tiempo de espera.',
  'An SSL error has occurred and a secure connection to the server cannot be made.',
  'System.Net.WebException: The request was aborted: The connection was closed unexpectedly.',
  'Update download failed',
  'getaddrinfo EAI_AGAIN',
  'getaddrinfo ENOTFOUND',
  'connect ETIMEDOUT'
];

class AutoUpdateManager extends EventEmitter {

  constructor(manifest, options, mainWindowManager) {
    super();

    this.manifest = manifest;
    this.options = options;
    this.mainWindowManager = mainWindowManager;

    this.enabled = !this.options.mas && prefs.get('updates-auto-check');
    this.state = STATES.IDLE;
    this.states = STATES;

    this.latestVersion = null;
    this.latestDownloadUrl = null;
  }

  init() {
    log('starting auto updater');
    this.initFeedUrl();
    this.initErrorListener();
    this.initStateListeners();
    this.initVersionListener();
    this.initDownloadListener();
  }

  initFeedUrl() {
    let feedUrl = this.manifest.updater.urls[process.platform]
      .replace(/%CURRENT_VERSION%/g, this.manifest.version)
      .replace(/%CHANNEL%/g, prefs.get('updates-channel'));

    if (this.options.portable) {
      feedUrl += '/portable';
    }

    log('updater feed url:', feedUrl);
    AutoUpdater.setFeedURL(feedUrl);
  }

  initErrorListener() {
    AutoUpdater.on('error', (err) => {
      log('auto updater error');
      if (err.message && IGNORED_ERRORS.find(msg => err.message.includes(msg))) {
        log(err);
      } else {
        logError(err);
      }
    });
  }

  initStateListeners() {
    const eventToStateMap = {
      'error': STATES.IDLE,
      'checking-for-update': STATES.UPDATE_CHECKING,
      'update-available': STATES.UPDATE_AVAILABLE,
      'update-not-available': STATES.IDLE,
      'update-downloaded': STATES.UPDATE_DOWNLOADED
    };

    for (let [eventName, state] of Object.entries(eventToStateMap)) {
      AutoUpdater.on(eventName, () => this.state = state);
    }
  }

  initVersionListener() {
    AutoUpdater.on('update-available', (newVersion, downloadUrl) => {
      this.latestVersion = newVersion;
      this.latestDownloadUrl = downloadUrl;
    });
  }

  initDownloadListener() {
    if (platform.isWin && !this.options.portable) {
      AutoUpdater.on('update-downloaded', () => {
        dialog.showMessageBox({
          type: 'question',
          message: 'A new version of ' + manifest.productName + ' has been downloaded.',
          detail: 'Would you like to restart the app and install the update? You can do this later from the App menu.',
          buttons: ['Later', 'Update']
        }, (response) => {
          if (response === 1) {
            log('user clicked Update');
            this.quitAndInstall();
          }
        });
      });
    }
  }

  handleMenuCheckForUpdate() {
    this.checkForUpdate(false);
  }

  handleMenuUpdateAvailable() {
    this.onCheckUpdateAvailable(this.latestVersion, this.latestDownloadUrl);
  }

  handleMenuUpdateDownloaded() {
    this.quitAndInstall();
  }

  setAutoCheck(check) {
    if (this.enabled === check) {
      log('update checker already', check ? 'enabled' : 'disabled');
      return; // same state
    }

    this.enabled = !this.options.mas && check;
    if (this.enabled) { // disabled -> enabled
      log('enabling auto update checker');
      this.scheduleUpdateChecks();
    } else if (this.scheduledCheckerId) {  // enabled -> disabled
      log('disabling auto update checker');
      clearInterval(this.scheduledCheckerId);
      this.scheduledCheckerId = null;
    }
  }

  onCheckUpdateAvailable(newVersion, downloadUrl) {
    log('onCheckUpdateAvailable', 'newVersion:', newVersion, 'downloadUrl:', downloadUrl);
    if (platform.isLinux) {
      dialog.showMessageBox({
        type: 'info',
        message: 'A new version is available: ' + newVersion,
        detail: 'Use your package manager to update, or click Download to get the new package.',
        buttons: ['OK', 'Download']
      }, function(response) {
        if (response === 1) {
          log('user clicked Download, opening url', downloadUrl);
          shell.openExternal(downloadUrl);
        }
      });
    } else if (platform.isWin && this.options.portable) {
      dialog.showMessageBox({
        type: 'info',
        message: 'A new version is available: ' + newVersion,
        detail: 'Click Download to get a portable zip with the new version.',
        buttons: ['OK', 'Download']
      }, function(response) {
        if (response === 1) {
          log('user clicked Download, opening url', downloadUrl);
          shell.openExternal(downloadUrl);
        }
      });
    } else {
      dialog.showMessageBox({
        type: 'info',
        message: 'A new version is available.',
        detail: 'It will start downloading in the background.',
        buttons: ['OK']
      }, function() {});
    }
  }

  onCheckUpdateNotAvailable() {
    log('onCheckUpdateNotAvailable');
    dialog.showMessageBox({
      type: 'info',
      message: 'No update available.',
      detail: 'You are using the latest version: ' + this.manifest.version,
      buttons: ['OK']
    }, function() {});
  }

  onCheckError(err) {
    log('onCheckError:', err);
    let detailMessage;

    if (err.message && IGNORED_ERRORS.find(msg => err.message.includes(msg))) {
      detailMessage = manifest.productName + ' could not connect to the updates server.'
        + ' Please make sure you have a working internet connection.'
        + '\n\nERR: ' + err.message;
    } else {
      detailMessage = err.message;
    }

    dialog.showMessageBox({
      type: 'error',
      message: 'Error while checking for update.',
      detail: detailMessage,
      buttons: ['OK']
    }, function() {});
  }

  scheduleUpdateChecks() {
    const checkInterval = 1000 * 60 * 60 * 4; // 4 hours
    log('scheduling update checks every', checkInterval, 'ms');
    this.scheduledCheckerId = setInterval(::this.checkForUpdate, checkInterval);
    this.checkForUpdate();
  }

  checkForUpdate(silent = true) {
    log('checking for update...');
    AutoUpdater.checkForUpdates();

    if (!silent) {
      const onCheck = {};

      const removeListeners = () => {
        AutoUpdater.removeListener('update-available', onCheck.updateAvailable);
        AutoUpdater.removeListener('update-not-available', onCheck.updateNotAvailable);
        AutoUpdater.removeListener('error', onCheck.error);
      };

      onCheck.updateAvailable = () => {
        this.onCheckUpdateAvailable.apply(this, arguments);
        removeListeners();
      };

      onCheck.updateNotAvailable = () => {
        this.onCheckUpdateNotAvailable.apply(this, arguments);
        removeListeners();
      };

      onCheck.error = () => {
        this.onCheckError.apply(this, arguments);
        removeListeners();
      };

      AutoUpdater.once('update-available', onCheck.updateAvailable);
      AutoUpdater.once('update-not-available', onCheck.updateNotAvailable);
      AutoUpdater.once('error', onCheck.error);
    }
  }

  quitAndInstall() {
    if (this.mainWindowManager) {
      this.mainWindowManager.updateInProgress = true;
      AutoUpdater.quitAndInstall();
    } else {
      logError(new Error('cannot quit to install update'));
    }
  }

}

export default AutoUpdateManager;
<|endoftext|>


<commit_before><commit_msg>:muscle: bump TRANSPILED distribution dist/snuggsi.js<commit_after>// http://nshipster.com/method-swizzling/
// HTMLElement Swizzle - To swizzle a method is to change a class’s dispatch table in order to resolve messages from an existing selector to a different implementation, while aliasing the original method implementation to a new selector.

// 3.2.3 HTML element constructors
// https://html.spec.whatwg.org/multipage/dom.html#html-element-constructors
// Satisfy Element interface document.createElement
//   - https://dom.spec.whatwg.org/#concept-element-interface

var HTMLElement =

/*
// Domenic discusses
// https://esdiscuss.org/topic/extending-an-es6-class-using-es5-syntax#content-1
I believe this will work in most cases:

function B() {
  const obj = new A();
  Object.setPrototypeOf(obj, new.target.prototype); // or B.prototype, but if you derive from B you'll have to do this dance again

  // use obj instead of this

  return obj;
}
Also, in general you should do

instead of

B.prototype = Object.create(A.prototype);
for slightly better semantics, including class-side inheritance and not clobbering .constructor.
*/

( function (_) {
  function E () {}

  E.prototype =

    window.HTMLElement.prototype

  // Prevent `.constructor` clobbering
  // E.__proto__ = window.HTMLElement

    // https://github.com/whatwg/html/issues/1704
    // E.prototype.__proto__
    //   = (E.__proto__ = HTMLElement).prototype

    // Domenic's method
    // Object
    //   .setPrototypeOf
    //     (Object.setPrototypeOf (B, A).prototype, A.prototype)

    return E
})()

var TokenList = function (node) {
  var this$1 = this;

  var
    visit = function (node) { return node.attributes && [].slice
         .call (node.attributes)
         .map(collect)
      || collect (node); }

  , collect = function (node) { return /{(\w+|#)}/.test (node.textContent)
        && (node.text = node.textContent)
            .match (/[^{]+(?=})/g)
            .map (function (symbol) { return (this$1 [symbol] || (this$1 [symbol] = [])).push (node); }); }

  , walker =
      document.createNodeIterator
        (node, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, visit, null)

  while (walker.nextNode ()) { null } // Walk all nodes and do nothing.
};

TokenList.prototype.bind = function (context) {

  var
    tokenize = function (symbol) { return function (node) { return (node.textContent
        = node.textContent
        .split ('{'+symbol+'}')
        .join(context [symbol])); }; }

  for (var symbol in this)
    { symbol != 'bind'
      && this [symbol].map
        (function (node) { return (node.textContent = node.text); }) }

  for (var symbol$1 in this)
    { symbol$1 != 'bind'
      && this [symbol$1].map
        (tokenize (symbol$1)) } // more than one occurrence
};

// https://codereview.chromium.org/1987413002
// https://github.com/whatwg/fetch/pull/442
// https://chromium.googlesource.com/chromium/src.git/+/a5a314d3249ecf1c291b417fbe067e8c2a65fad2
//
// Link rel preload as attribute doesn't support the as=document value
// https://bugs.chromium.org/p/chromium/issues/detail?id=593267
//
// Requests with useStreamOnResponse flag don't reuse preloaded resources
// https://bugs.chromium.org/p/chromium/issues/detail?id=652228
//
// Spurious warning preloading script
// https://bugs.chromium.org/p/chromium/issues/detail?id=655698
//
// WPT
// https://github.com/w3c/web-platform-tests/pull/4505
//
// w3c preload Tighter definition of "load was successful"
// https://github.com/w3c/preload/issues/83
void ( function (_) {

  //create an observer instance
  // Can always default to DOMContentLoaded
  // https://bugs.webkit.org/show_bug.cgi?id=38995#c26
  (new MutationObserver ( function (mutations) {

    for (var i$1 = 0, list$1 = mutations; i$1 < list$1.length; i$1 += 1)
      {
      var mutation = list$1[i$1];

      for (var i = 0, list = mutation.addedNodes; i < list.length; i += 1) {
         var node = list[i];

          /^p/.test (node.rel)
           && /\-/.test (node.id)
           && load (node)

         !! /\-/.test (node.localName)
           && (link = document.querySelector ('#'+node.localName))
           && link.content
           && stamp.call (node, link.content)
           && customElements.upgrade (node)
      }
    }
  }))

  .observe (document.documentElement, { childList: true, subtree: true })

  void

  [].slice
    .call (document.querySelectorAll ('[rel^=pre][id~="-"]'))
    .map  (load)

  // XHR Specs
  // https://xhr.spec.whatwg.org
  // Progress events
  // https://xhr.spec.whatwg.org/#interface-progressevent
  // Loader - https://trac.webkit.org/browser/trunk/WebCore/loader/loader.cpp
  function load (link) {

    var xhr = new XMLHttpRequest

    // Destination - https://fetch.spec.whatwg.org/#requestdestination

    xhr.link   = link
    xhr.onload = onload
    // progress events won't fire unless defining before open
    xhr.open ('GET', link.href)
    xhr.responseType = 'document'
    // Max requests
    xhr.send ()
  }

  // https://github.com/w3c/preload/pull/40
  // https://bugs.webkit.org/show_bug.cgi?id=38995
  // https://www.w3.org/TR/html5/document-metadata.html#the-link-element
  function onload () {
    var
      link = this.link

    , response =
        this.response

    , anchor =
        link.nextChild

    , template =
        link.content =
           response.querySelector ('template')

    // https://www.nczonline.net/blog/2010/09/28/why-is-getelementsbytagname-faster-that-queryselectorall
    for (var i = 0, list = document.querySelectorAll (link.id); i < list.length; i += 1)
      {
      var node = list[i];

      template && stamp.call (node, template)
    }

    for (var i$1 = 0, list$1 = response.querySelectorAll ('style,link,script'); i$1 < list$1.length; i$1 += 1)
      {
      var node$1 = list$1[i$1];

      process (link, node$1, anchor)
    }
  }

  function process (link, node, anchor) {
      var
        // https://chromium.googlesource.com/chromium/src.git/+/0661feafc9a84f03b04dd3719b8aaa255dfaec63/third_party/WebKit/Source/core/loader/LinkLoader.cpp
        // HTML WhatWG scripting
        // https://html.spec.whatwg.org/multipage/scripting.html
        // https://html.spec.whatwg.org/multipage/scripting.html#prepare-a-script
        // Classic script graph - https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-classic-script
        // Module script tree - https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-script-tree
        // Concept Script script - https://html.spec.whatwg.org/multipage/scripting.html#concept-script-script
        as = node.getAttribute ('as')

      , clone =
          document.createElement
            ('script' == as ? as : node.localName)

      void

      // 'type' is used for data blocks (i.e. `type=text/recipe` or `type=application/x-game-data`
      // https://html.spec.whatwg.org/multipage/scripting.html#data-block
      ['id', 'rel', 'href', 'src', 'textContent', 'as', 'defer', 'crossOrigin' ]
        // setAttribute won't work for textContent and likewise explicit set for crossorigin
        .map (function (attr) { return node [attr] && attr in clone && (clone [attr] = node [attr]); })

      // use rel = 'preload stylesheet' for async
      // or use media=snuggsi => media || 'all' trick
      // loadCSS - https://github.com/filamentgroup/loadCSS
      // http://keithclark.co.uk/articles/loading-css-without-blocking-render
      'style' == as
      // https://www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/#markup-based-async-loader
        && (clone.rel = 'stylesheet')

      'script' == as // smelly
        && (clone.src = clone.href)

      link
        .parentNode
        .insertBefore (clone, anchor)
  }

  // Slot replacement & light DOM stamping
  // https://github.com/w3c/webcomponents/issues/288
  // https://dom.spec.whatwg.org/#slot-assigned-nodes
  function stamp (template) {
    var this$1 = this;

    template =
      document.importNode (template, true)

    var slot

    [] // distribute attributes
      .slice
      .call (template.attributes)
      .map  (function (attr) { return !   this$1.attributes [attr.name]
        &&  this$1.setAttribute (attr.name, attr.value); })

    for (var i = 0, list = this.querySelectorAll ('[slot]'); i < list.length; i += 1)
      {
      var replacement = list[i];

      (slot = (template.content || template).querySelector
       ( 'slot[name=' + replacement.getAttribute ('slot') + ']' ))

      && // this could be slow
        slot.parentNode.replaceChild (replacement, slot)
    }

    return this.innerHTML = template.innerHTML
  }

}) ()

var Template = function (template) {

  var
    range = document.createRange ()

  template
    = typeof template === 'string'
    ? document.querySelector ( 'template[name=' + template + ']' )
    : template

  range.selectNodeContents ( template.content )

  var
    fragment = range.cloneContents ()

  , tokenize = function (context, index) {
      var
        clone = fragment.cloneNode (true)

      typeof context != 'object'
        && ( context  = { self: context })

      context ['#'] = index

      void (new TokenList (clone))
        .bind (context)

      return clone
    }

  , bind = function (context) {
      range.deleteContents ()

      context && []
        .concat (context)
        .map (tokenize)
        .reverse () // Range.insertNode does prepend
        .map (function (fragment) { return range.insertNode (fragment); })
    }

  range.setStartAfter (template)
  template.bind = bind
  return template
}

window.customElements =
  window.customElements
  || {/* microfill */}

void ( function (_) { /* CustomElementRegistry */

  customElements.define = function ( name, constructor ) {

    !! /\-/.test (name)
    && (customElements [name] = constructor)
    && [].slice
      // https://www.nczonline.net/blog/2010/09/28/why-is-getelementsbytagname-faster-that-queryselectorall
      .call ( document.querySelectorAll (name) )
      .map  ( customElements.upgrade )
  }

  customElements.upgrade = function (root) {

    var candidates = []

    // Here's where we can swizzle
    // https://github.com/whatwg/html/issues/1704#issuecomment-241881091

    Object.setPrototypeOf
      (root, customElements [root.localName].prototype)

    root.connectedCallback ()
  }

  void (new MutationObserver ( function (mutations) {

    for (var i$1 = 0, list$1 = mutations; i$1 < list$1.length; i$1 += 1)
      {
      var mutation = list$1[i$1];

      for (var i = 0, list = mutation.addedNodes; i < list.length; i += 1)

         {
          var root = list[i];

          !! /\-/.test (root.localName)
         && customElements [root.localName]
         && customElements.upgrade (root)
        }
    }
  }))

  .observe (document.documentElement, { childList: true, subtree: true })

})() /* CustomElementRegistry */

var ParentNode = function (Element) { return (/*@__PURE__*/(function (Element) {
    function anonymous () {
      Element.apply(this, arguments);
    }

    if ( Element ) anonymous.__proto__ = Element;
    anonymous.prototype = Object.create( Element && Element.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.select = function ( )
    {
    var ref;
 return (ref = this).selectAll.apply ( ref, arguments ) [0] };

  anonymous.prototype.selectAll = function ( strings ) {
    var tokens = [], len = arguments.length - 1;
    while ( len-- > 0 ) tokens[ len ] = arguments[ len + 1 ];

    strings = [ ].concat ( strings )

    return [].slice.call
      (this.querySelectorAll
        (tokens.reduce // denormalize selector
          (function (part, token) { return part + token + strings.shift (); }
          , strings.shift ())))
  };

    return anonymous;
  }(Element))); }

//  comb (parent) {
//    // ElementTraversal interface
//    // https://www.w3.org/TR/ElementTraversal/#interface-elementTraversal
//
//    if (parent.hasChildNodes())
//      for (let node = parent.firstChild; node; node = node.nextSibling)
//        comb (node)
//  }

var EventTarget = function (HTMLElement) { return (/*@__PURE__*/(function (HTMLElement) {
    function anonymous () {
      HTMLElement.apply(this, arguments);
    }

    if ( HTMLElement ) anonymous.__proto__ = HTMLElement;
    anonymous.prototype = Object.create( HTMLElement && HTMLElement.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.on = function ( event, handler ) {

    this.addEventListener
      (event, this.renderable (handler))
  };

  anonymous.prototype.renderable = function ( handler ) {
    var this$1 = this;

    // BIG BUG IN IE!!!
    //
    // https://connect.microsoft.com/IE/feedback/details/790389/event-defaultprevented-returns-false-after-preventdefault-was-called
    //
    // https://github.com/webcomponents/webcomponents-platform/blob/master/webcomponents-platform.js#L16

    return function (event) { return handler.call (this$1, event) !== false
        // check render availability
        && event.defaultPrevented
        || this$1.render (); }
  };

//off (event, listener = 'on' + this [event])
//  // MDN EventTarget.removeEventListener
//  // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
//  //
//  // WHATWG Living Standard EventTarget.removeEventListener
//  // https://dom.spec.whatwg.org/#dom-eventtarget-removeeventlistener
//  //
//  // DOM Level 2 EventTarget.removeEventListener
//  // https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget-removeEventListener

//  { this.removeEventListener (event, listener) }

//dispatch (event)
//  // MDN EventTarget.dispatchEvent
//  // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent
//  //
//  // WHATWG Living Standard EventTarget.dispatchEvent
//  // https://dom.spec.whatwg.org/#dom-eventtarget-dispatchevent
//  //
//  // DOM Level 2 EventTarget.dispatchEvent
//  //  https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget-dispatchEvent

//  { }

  // Reflection - https://en.wikipedia.org/wiki/Reflection_(computer_programming)
  // Type Introspection - https://en.wikipedia.org/wiki/Type_introspection
  //
  // In computing, type introspection is the ability of a program
  // to examine the type or properties of an object at runtime.
  // Some programming languages possess this capability.
  //
  // Introspection should not be confused with reflection,
  // which goes a step further and is the ability for a program to manipulate the values,
  // meta-data, properties and/or functions of an object at runtime.

  anonymous.prototype.reflect = function (handler) {

    /^on/.test (handler) // is a W3C `on`event
      && handler in HTMLElement.prototype // `on*`

      && // automagically delegate event
        this.on ( handler.substr (2), this [handler] )
  };

  anonymous.prototype.register = function (node, handler, event) {
    for (var i = 0, list = [].slice.call (node.attributes); i < list.length; i += 1)
            {
      var attribute = list[i];

      /^on/.test (event = attribute.name)
            // https://www.quirksmode.org/js/events_tradmod.html
            // because under traditional registration the handler value is wrapped in scope `{ onfoo }`
            && ( handler = (/{\s*(\w+)/.exec (node [event]) || []) [1])
            && ( node [event] = this.renderable (this [handler]) )
    }
  };

    return anonymous;
  }(HTMLElement))); }

var GlobalEventHandlers = function (Element) { return (/*@__PURE__*/(function (Element) {
    function anonymous () {
      Element.apply(this, arguments);
    }

    if ( Element ) anonymous.__proto__ = Element;
    anonymous.prototype = Object.create( Element && Element.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.onconnect = function (event) {

    this.templates =
      this
        .selectAll ('template[name]')
        .map (Template)

    this.tokens =
      new TokenList (this)

    Element.prototype.onconnect
      && Element.prototype.onconnect.call (this, event)
  };

    return anonymous;
  }(Element))); }
var Custom = function (Element) { return ( /*@__PURE__*/(function (superclass) {
    function anonymous () {
      superclass.apply(this, arguments);
    }

    if ( superclass ) anonymous.__proto__ = superclass;
    anonymous.prototype = Object.create( superclass && superclass.prototype );
    anonymous.prototype.constructor = anonymous;

    anonymous.prototype.connectedCallback = function () {
    this.context = {}

    superclass.prototype.initialize
      && superclass.prototype.initialize.call (this)

    Object
      .getOwnPropertyNames (Element.prototype)
      .map (this.reflect, this)

    this.addEventListener
      ('connect', this.onconnect)

    this.addEventListener.call
      (this, 'idle', superclass.prototype.onidle)

    this.dispatchEvent
      (new Event ('connect'))

    this.render ()
  };

  anonymous.prototype.render = function () {

    for (var i = 0, list = this.templates; i < list.length; i += 1)
      {
      var template = list[i];

      template.bind
        (this [template.getAttribute ('name')])
    }

    this
      .tokens
      .bind (this)

    this.register (this)

    this
      // possibly restrict to elements with on event
      .selectAll ('*')
      .map (this.register, this)

    this.dispatchEvent
      (new Event ('idle'))
  };

    return anonymous;
  }(( ParentNode
  ( EventTarget
  ( GlobalEventHandlers
  ( Element ))))))); }

// http://2ality.com/2013/09/window.html
// http://tobyho.com/2013/03/13/window-prop-vs-global-var

var Element = function (tag) { return (

//      const constructor =// swizzle
//        typeof tag === 'string'
//    //    ? HTMLCustomElement
//    //    : HTMLElement

        //https://gist.github.com/allenwb/53927e46b31564168a1d
        // https://github.com/w3c/webcomponents/issues/587#issuecomment-271031208
        // https://github.com/w3c/webcomponents/issues/587#issuecomment-254017839

      function (Element) { return customElements.define
          ( tag + '', Custom (Element) ); }

// Assign `window.Element.prototype` in case of feature checking on `Element`
//  E.prototype = Element.prototype
//  return E
); }

<|endoftext|>


<commit_before>/*
 * @license
 * Copyright 2016 Google Inc. 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.
 */

foam.LIB({
  name: 'compare',

  methods: [
    function isDefined(o) {
      return o !== undefined && o !== null;
    },

    function equals(a, b) {
      if ( a === b ) return true;
      if ( ! a || ! b ) return false;
      if ( a.equals ) return a.equals(b);
      return a == b;
    },

    function compareDates(d1, d2) {
      if ( d1 === d2 ) return 0;
      if ( ! d1 ) return -1;
      if ( ! d2 ) return 1;
      var d = d1.getTime() - d2.getTime();
      return d == 0 ? 0 : d > 0 ? 1 : -1;
    },

    function compare(a, b) {
      if ( a === b ) return 0;

      if ( this.isDefined(a) && ! this.isDefined(b) ) return 1;

      if ( ! this.isDefined(a) && this.isDefined(b) ) return -1;

      if ( typeof a === 'number' && typeof b === 'number' )
        return a < b ? -1 : a > b ? 1 : 0;

      if ( typeof a === 'string' && typeof b === 'string' )
        return a < b ? -1 : a > b ? 1 : 0;

      if ( a instanceof Date && b instanceof Date )
        return this.compareDates(a, b);

      if ( a.compareTo ) return a.compareTo(b);

      if ( b.compareTo ) return - b.compareTo(a);

      if ( foam.compare.equals(a, b) ) return 0;

      return a.$UID.compareTo(b.$UID);
    }
  ]
});
<commit_msg>Changes to compare.compare.<commit_after>/*
 * @license
 * Copyright 2016 Google Inc. 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.
 */

foam.LIB({
  name: 'compare',

  methods: [
    function isDefined(o) {
      return o !== undefined && o !== null;
    },

    function equals(a, b) {
      if ( a === b ) return true;
      if ( ! a || ! b ) return false;
      if ( a.equals ) return a.equals(b);
      return a == b;
    },

    function compare(a, b) {
      if ( a === b ) return 0;

      if ( this.isDefined(a) && ! this.isDefined(b) ) return 1;

      if ( ! this.isDefined(a) && this.isDefined(b) ) return -1;

      if ( typeof a === 'number' && typeof b === 'number' )
        return a < b ? -1 : a > b ? 1 : 0;

      if ( typeof a === 'string' && typeof b === 'string' )
        return a < b ? -1 : a > b ? 1 : 0;

      if ( a instanceof Date && b instanceof Date ) {
        var d = a.getTime() - b.getTime();
        return d == 0 ? 0 : d > 0 ? 1 : -1;
      }

      if ( a.compareTo ) return a.compareTo(b);

      if ( b.compareTo ) return - b.compareTo(a);

      if ( foam.compare.equals(a, b) ) return 0;

      return a.$UID.compareTo(b.$UID);
    }
  ]
});
<|endoftext|>