<commit_before>(function (Object, GOPS) {'use strict';

  // (C) Andrea Giammarchi - Mit Style

  if (GOPS in Object) return;

  var
    setDescriptor,
    G = typeof global === typeof G ? window : global,
    id = 0,
    random = '' + Math.random(),
    prefix = '__\x01symbol:',
    prefixLength = prefix.length,
    internalSymbol = '__\x01symbol@@' + random,
    DP = 'defineProperty',
    DPies = 'defineProperties',
    GOPN = 'getOwnPropertyNames',
    GOPD = 'getOwnPropertyDescriptor',
    PIE = 'propertyIsEnumerable',
    gOPN = Object[GOPN],
    gOPD = Object[GOPD],
    create = Object.create,
    keys = Object.keys,
    defineProperty = Object[DP],
    defineProperties = Object[DPies],
    descriptor = gOPD(Object, GOPN),
    ObjectProto = Object.prototype,
    hOP = ObjectProto.hasOwnProperty,
    pIE = ObjectProto[PIE],
    toString = ObjectProto.toString,
    indexOf = Array.prototype.indexOf || function (v) {
      for (var i = this.length; i-- && this[i] !== v;) {}
      return i;
    },
    addInternalIfNeeded = function (o, uid, enumerable) {
      if (!hOP.call(o, internalSymbol)) {
        defineProperty(o, internalSymbol, {
          enumerable: false,
          configurable: false,
          writable: false,
          value: {}
        });
      }
      o[internalSymbol]['@@' + uid] = enumerable;
    },
    createWithSymbols = function (proto, descriptors) {
      var self = create(proto);
      gOPN(descriptors).forEach(function (key) {
        if (propertyIsEnumerable.call(descriptors, key)) {
          $defineProperty(self, key, descriptors[key]);
        }
      });
      return self;
    },
    copyAsNonEnumerable = function (descriptor) {
      var newDescriptor = create(descriptor);
      newDescriptor.enumerable = false;
      return newDescriptor;
    },
    get = function get(){},
    onlyNonSymbols = function (name) {
      return  name != internalSymbol &&
              !hOP.call(source, name);
    },
    onlySymbols = function (name) {
      return  name != internalSymbol &&
              hOP.call(source, name);
    },
    propertyIsEnumerable = function propertyIsEnumerable(key) {
      var uid = '' + key;
      return onlySymbols(uid) ? (
        hOP.call(this, uid) &&
        this[internalSymbol]['@@' + uid]
      ) : pIE.call(this, key);
    },
    setAndGetSymbol = function (uid) {
      var descriptor = {
        enumerable: false,
        configurable: true,
        get: get,
        set: function (value) {
          setDescriptor(this, uid, {
            enumerable: false,
            configurable: true,
            writable: true,
            value: value
          });
          addInternalIfNeeded(this, uid, true);
        }
      };
      defineProperty(ObjectProto, uid, descriptor);
      return (source[uid] = defineProperty(
        Object(uid),
        'constructor',
        sourceConstructor
      ));
    },
    Symbol = function Symbol(description) {
      if (this && this !== G) {
        throw new TypeError('Symbol is not a constructor');
      }
      return setAndGetSymbol(
        prefix.concat(description || '', random, ++id)
      );
    },
    source = create(null),
    sourceConstructor = {value: Symbol},
    sourceMap = function (uid) {
      return source[uid];
    },
    $defineProperty = function defineProp(o, key, descriptor) {
      var uid = '' + key;
      if (onlySymbols(uid)) {
        setDescriptor(o, uid, descriptor.enumerable ?
            copyAsNonEnumerable(descriptor) : descriptor);
        addInternalIfNeeded(o, uid, !!descriptor.enumerable);
      } else {
        defineProperty(o, key, descriptor);
      }
      return o;
    },
    $getOwnPropertySymbols = function getOwnPropertySymbols(o) {
      return gOPN(o).filter(onlySymbols).map(sourceMap);
    }
  ;

  descriptor.value = $defineProperty;
  defineProperty(Object, DP, descriptor);

  descriptor.value = $getOwnPropertySymbols;
  defineProperty(Object, GOPS, descriptor);

  descriptor.value = function getOwnPropertyNames(o) {
    return gOPN(o).filter(onlyNonSymbols);
  };
  defineProperty(Object, GOPN, descriptor);

  descriptor.value = function defineProperties(o, descriptors) {
    var symbols = $getOwnPropertySymbols(descriptors);
    if (symbols.length) {
      keys(descriptors).concat(symbols).forEach(function (uid) {
        if (propertyIsEnumerable.call(descriptors, uid)) {
          $defineProperty(o, uid, descriptors[uid]);
        }
      });
    } else {
      defineProperties(o, descriptors);
    }
    return o;
  };
  defineProperty(Object, DPies, descriptor);

  descriptor.value = propertyIsEnumerable;
  defineProperty(ObjectProto, PIE, descriptor);

  descriptor.value = Symbol;
  defineProperty(G, 'Symbol', descriptor);

  // defining `Symbol.for(key)`
  descriptor.value = function (key) {
    var uid = prefix.concat(prefix, key, random);
    return uid in ObjectProto ? source[uid] : setAndGetSymbol(uid);
  };
  defineProperty(Symbol, 'for', descriptor);

  // defining `Symbol.keyFor(symbol)`
  descriptor.value = function (symbol) {
    return hOP.call(source, symbol) ?
      symbol.slice(prefixLength * 2, -random.length) :
      void 0
    ;
  };
  defineProperty(Symbol, 'keyFor', descriptor);

  descriptor.value = function getOwnPropertyDescriptor(o, key) {
    var descriptor = gOPD(o, key);
    if (descriptor && onlySymbols(key)) {
      descriptor.enumerable = propertyIsEnumerable.call(o, key);
    }
    return descriptor;
  };
  defineProperty(Object, GOPD, descriptor);

  descriptor.value = function (proto, descriptors) {
    return arguments.length === 1 ?
      create(proto) :
      createWithSymbols(proto, descriptors);
  };
  defineProperty(Object, 'create', descriptor);

  descriptor.value = function () {
    var str = toString.call(this);
    return (str === '[object String]' && onlySymbols(this)) ? '[object Symbol]' : str;
  };
  defineProperty(ObjectProto, 'toString', descriptor);

  try { // fails in few pre ES 5.1 engines
    setDescriptor = create(
      defineProperty(
        {},
        prefix,
        {
          get: function () {
            return defineProperty(this, prefix, {value: false})[prefix];
          }
        }
      )
    )[prefix] || defineProperty;
  } catch(o_O) {
    setDescriptor = function (o, key, descriptor) {
      var protoDescriptor = gOPD(ObjectProto, key);
      delete ObjectProto[key];
      defineProperty(o, key, descriptor);
      defineProperty(ObjectProto, key, protoDescriptor);
    };
  }

}(Object, 'getOwnPropertySymbols'));

(function (O, S) {
  var
    dP = O.defineProperty,
    ObjectProto = O.prototype,
    toString = ObjectProto.toString,
    toStringTag = 'toStringTag',
    descriptor
  ;
  [
    'iterator',           // A method returning the default iterator for an object. Used by for...of.
    'match',              // A method that matches against a string, also used to determine if an object may be used as a regular expression. Used by String.prototype.match().
    'replace',            // A method that replaces matched substrings of a string. Used by String.prototype.replace().
    'search',             // A method that returns the index within a string that matches the regular expression. Used by String.prototype.search().
    'split',              // A method that splits a string at the indices that match a regular expression. Used by String.prototype.split().
    'hasInstance',        // A method determining if a constructor object recognizes an object as its instance. Used by instanceof.
    'isConcatSpreadable', // A Boolean value indicating if an object should be flattened to its array elements. Used by Array.prototype.concat().
    'unscopables',        // An Array of string values that are property values. These are excluded from the with environment bindings of the associated objects.
    'species',            // A constructor function that is used to create derived objects.
    'toPrimitive',        // A method converting an object to a primitive value.
    toStringTag           // A string value used for the default description of an object. Used by Object.prototype.toString().
  ].forEach(function (name) {
    if (!(name in Symbol)) {
      dP(Symbol, name, {value: Symbol(name)});
      switch (name) {
        case toStringTag:
          descriptor = O.getOwnPropertyDescriptor(ObjectProto, 'toString');
          descriptor.value = function () {
            var
              str = toString.call(this),
              tst = this[Symbol.toStringTag]
            ;
            return typeof tst === 'undefined' ? str : ('[object ' + tst + ']');
          };
          dP(ObjectProto, 'toString', descriptor);
          break;
      }
    }
  });
}(Object, Symbol));

(function (Si, AP, SP) {

  function returnThis() { return this; }

  // make Arrays usable as iterators
  // so that other iterables can copy same logic
  if (!AP[Si]) AP[Si] = function () {
    var
      i = 0,
      self = this,
      iterator = {
        next: function next() {
          var done = self.length <= i;
          return done ?
            {done: done} :
            {done: done, value: self[i++]};
        }
      }
    ;
    iterator[Si] = returnThis;
    return iterator;
  };

  // make Strings usable as iterators
  // to simplify Array.from and
  if (!SP[Si]) SP[Si] = function () {
    var
      fromCodePoint = String.fromCodePoint,
      self = this,
      i = 0,
      length = self.length,
      iterator = {
        next: function next() {
          var
            done = length <= i,
            c = done ? '' : fromCodePoint(self.codePointAt(i))
          ;
          i += c.length;
          return done ?
            {done: done} :
            {done: done, value: c};
        }
      }
    ;
    iterator[Si] = returnThis;
    return iterator;
  };

}(Symbol.iterator, Array.prototype, String.prototype));
<commit_msg>toStringTag fails if this is undefined<commit_after>(function (Object, GOPS) {'use strict';

  // (C) Andrea Giammarchi - Mit Style

  if (GOPS in Object) return;

  var
    setDescriptor,
    G = typeof global === typeof G ? window : global,
    id = 0,
    random = '' + Math.random(),
    prefix = '__\x01symbol:',
    prefixLength = prefix.length,
    internalSymbol = '__\x01symbol@@' + random,
    DP = 'defineProperty',
    DPies = 'defineProperties',
    GOPN = 'getOwnPropertyNames',
    GOPD = 'getOwnPropertyDescriptor',
    PIE = 'propertyIsEnumerable',
    gOPN = Object[GOPN],
    gOPD = Object[GOPD],
    create = Object.create,
    keys = Object.keys,
    defineProperty = Object[DP],
    defineProperties = Object[DPies],
    descriptor = gOPD(Object, GOPN),
    ObjectProto = Object.prototype,
    hOP = ObjectProto.hasOwnProperty,
    pIE = ObjectProto[PIE],
    toString = ObjectProto.toString,
    indexOf = Array.prototype.indexOf || function (v) {
      for (var i = this.length; i-- && this[i] !== v;) {}
      return i;
    },
    addInternalIfNeeded = function (o, uid, enumerable) {
      if (!hOP.call(o, internalSymbol)) {
        defineProperty(o, internalSymbol, {
          enumerable: false,
          configurable: false,
          writable: false,
          value: {}
        });
      }
      o[internalSymbol]['@@' + uid] = enumerable;
    },
    createWithSymbols = function (proto, descriptors) {
      var self = create(proto);
      gOPN(descriptors).forEach(function (key) {
        if (propertyIsEnumerable.call(descriptors, key)) {
          $defineProperty(self, key, descriptors[key]);
        }
      });
      return self;
    },
    copyAsNonEnumerable = function (descriptor) {
      var newDescriptor = create(descriptor);
      newDescriptor.enumerable = false;
      return newDescriptor;
    },
    get = function get(){},
    onlyNonSymbols = function (name) {
      return  name != internalSymbol &&
              !hOP.call(source, name);
    },
    onlySymbols = function (name) {
      return  name != internalSymbol &&
              hOP.call(source, name);
    },
    propertyIsEnumerable = function propertyIsEnumerable(key) {
      var uid = '' + key;
      return onlySymbols(uid) ? (
        hOP.call(this, uid) &&
        this[internalSymbol]['@@' + uid]
      ) : pIE.call(this, key);
    },
    setAndGetSymbol = function (uid) {
      var descriptor = {
        enumerable: false,
        configurable: true,
        get: get,
        set: function (value) {
          setDescriptor(this, uid, {
            enumerable: false,
            configurable: true,
            writable: true,
            value: value
          });
          addInternalIfNeeded(this, uid, true);
        }
      };
      defineProperty(ObjectProto, uid, descriptor);
      return (source[uid] = defineProperty(
        Object(uid),
        'constructor',
        sourceConstructor
      ));
    },
    Symbol = function Symbol(description) {
      if (this && this !== G) {
        throw new TypeError('Symbol is not a constructor');
      }
      return setAndGetSymbol(
        prefix.concat(description || '', random, ++id)
      );
    },
    source = create(null),
    sourceConstructor = {value: Symbol},
    sourceMap = function (uid) {
      return source[uid];
    },
    $defineProperty = function defineProp(o, key, descriptor) {
      var uid = '' + key;
      if (onlySymbols(uid)) {
        setDescriptor(o, uid, descriptor.enumerable ?
            copyAsNonEnumerable(descriptor) : descriptor);
        addInternalIfNeeded(o, uid, !!descriptor.enumerable);
      } else {
        defineProperty(o, key, descriptor);
      }
      return o;
    },
    $getOwnPropertySymbols = function getOwnPropertySymbols(o) {
      return gOPN(o).filter(onlySymbols).map(sourceMap);
    }
  ;

  descriptor.value = $defineProperty;
  defineProperty(Object, DP, descriptor);

  descriptor.value = $getOwnPropertySymbols;
  defineProperty(Object, GOPS, descriptor);

  descriptor.value = function getOwnPropertyNames(o) {
    return gOPN(o).filter(onlyNonSymbols);
  };
  defineProperty(Object, GOPN, descriptor);

  descriptor.value = function defineProperties(o, descriptors) {
    var symbols = $getOwnPropertySymbols(descriptors);
    if (symbols.length) {
      keys(descriptors).concat(symbols).forEach(function (uid) {
        if (propertyIsEnumerable.call(descriptors, uid)) {
          $defineProperty(o, uid, descriptors[uid]);
        }
      });
    } else {
      defineProperties(o, descriptors);
    }
    return o;
  };
  defineProperty(Object, DPies, descriptor);

  descriptor.value = propertyIsEnumerable;
  defineProperty(ObjectProto, PIE, descriptor);

  descriptor.value = Symbol;
  defineProperty(G, 'Symbol', descriptor);

  // defining `Symbol.for(key)`
  descriptor.value = function (key) {
    var uid = prefix.concat(prefix, key, random);
    return uid in ObjectProto ? source[uid] : setAndGetSymbol(uid);
  };
  defineProperty(Symbol, 'for', descriptor);

  // defining `Symbol.keyFor(symbol)`
  descriptor.value = function (symbol) {
    return hOP.call(source, symbol) ?
      symbol.slice(prefixLength * 2, -random.length) :
      void 0
    ;
  };
  defineProperty(Symbol, 'keyFor', descriptor);

  descriptor.value = function getOwnPropertyDescriptor(o, key) {
    var descriptor = gOPD(o, key);
    if (descriptor && onlySymbols(key)) {
      descriptor.enumerable = propertyIsEnumerable.call(o, key);
    }
    return descriptor;
  };
  defineProperty(Object, GOPD, descriptor);

  descriptor.value = function (proto, descriptors) {
    return arguments.length === 1 ?
      create(proto) :
      createWithSymbols(proto, descriptors);
  };
  defineProperty(Object, 'create', descriptor);

  descriptor.value = function () {
    var str = toString.call(this);
    return (str === '[object String]' && onlySymbols(this)) ? '[object Symbol]' : str;
  };
  defineProperty(ObjectProto, 'toString', descriptor);

  try { // fails in few pre ES 5.1 engines
    setDescriptor = create(
      defineProperty(
        {},
        prefix,
        {
          get: function () {
            return defineProperty(this, prefix, {value: false})[prefix];
          }
        }
      )
    )[prefix] || defineProperty;
  } catch(o_O) {
    setDescriptor = function (o, key, descriptor) {
      var protoDescriptor = gOPD(ObjectProto, key);
      delete ObjectProto[key];
      defineProperty(o, key, descriptor);
      defineProperty(ObjectProto, key, protoDescriptor);
    };
  }

}(Object, 'getOwnPropertySymbols'));

(function (O, S) {
  var
    dP = O.defineProperty,
    ObjectProto = O.prototype,
    toString = ObjectProto.toString,
    toStringTag = 'toStringTag',
    descriptor
  ;
  [
    'iterator',           // A method returning the default iterator for an object. Used by for...of.
    'match',              // A method that matches against a string, also used to determine if an object may be used as a regular expression. Used by String.prototype.match().
    'replace',            // A method that replaces matched substrings of a string. Used by String.prototype.replace().
    'search',             // A method that returns the index within a string that matches the regular expression. Used by String.prototype.search().
    'split',              // A method that splits a string at the indices that match a regular expression. Used by String.prototype.split().
    'hasInstance',        // A method determining if a constructor object recognizes an object as its instance. Used by instanceof.
    'isConcatSpreadable', // A Boolean value indicating if an object should be flattened to its array elements. Used by Array.prototype.concat().
    'unscopables',        // An Array of string values that are property values. These are excluded from the with environment bindings of the associated objects.
    'species',            // A constructor function that is used to create derived objects.
    'toPrimitive',        // A method converting an object to a primitive value.
    toStringTag           // A string value used for the default description of an object. Used by Object.prototype.toString().
  ].forEach(function (name) {
    if (!(name in Symbol)) {
      dP(Symbol, name, {value: Symbol(name)});
      switch (name) {
        case toStringTag:
          descriptor = O.getOwnPropertyDescriptor(ObjectProto, 'toString');
          descriptor.value = function () {
            var
              str = toString.call(this),
              tst = typeof this === 'undefined' ? undefined : this[Symbol.toStringTag]
            ;
            return typeof tst === 'undefined' ? str : ('[object ' + tst + ']');
          };
          dP(ObjectProto, 'toString', descriptor);
          break;
      }
    }
  });
}(Object, Symbol));

(function (Si, AP, SP) {

  function returnThis() { return this; }

  // make Arrays usable as iterators
  // so that other iterables can copy same logic
  if (!AP[Si]) AP[Si] = function () {
    var
      i = 0,
      self = this,
      iterator = {
        next: function next() {
          var done = self.length <= i;
          return done ?
            {done: done} :
            {done: done, value: self[i++]};
        }
      }
    ;
    iterator[Si] = returnThis;
    return iterator;
  };

  // make Strings usable as iterators
  // to simplify Array.from and
  if (!SP[Si]) SP[Si] = function () {
    var
      fromCodePoint = String.fromCodePoint,
      self = this,
      i = 0,
      length = self.length,
      iterator = {
        next: function next() {
          var
            done = length <= i,
            c = done ? '' : fromCodePoint(self.codePointAt(i))
          ;
          i += c.length;
          return done ?
            {done: done} :
            {done: done, value: c};
        }
      }
    ;
    iterator[Si] = returnThis;
    return iterator;
  };

}(Symbol.iterator, Array.prototype, String.prototype));
<|endoftext|>


<commit_before>/*jslint indent: 2,
         nomen: true,
         maxlen: 80 */
/*global require,
    db,
    assertEqual, assertTrue,
    ArangoCollection, ArangoEdgesCollection */

////////////////////////////////////////////////////////////////////////////////
/// @brief test the cap constraint
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler, Lucas Dohmen
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

var jsunity = require("jsunity");
var internal = require("internal");
var console = require("console");

// -----------------------------------------------------------------------------
// --SECTION--                                                     basic methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief test suite: Creation
////////////////////////////////////////////////////////////////////////////////

function CapConstraintSuite() {
  var ERRORS = internal.errors;
  var cn = "UnitTestsCollectionCap";
  var collection = null;

  return {

////////////////////////////////////////////////////////////////////////////////
/// @brief set up
////////////////////////////////////////////////////////////////////////////////

  setUp : function () {
    internal.db._drop(cn);
    collection = internal.db._create(cn, { waitForSync : false });
  },

////////////////////////////////////////////////////////////////////////////////
/// @brief tear down
////////////////////////////////////////////////////////////////////////////////

  tearDown : function () {
    collection.unload();

    while (collection.status() != internal.ArangoCollection.STATUS_UNLOADED) {
      console.log("waiting for collection '%s' to unload.");
      internal.wait(1);
    }

    collection.drop();

    while (collection.status() != internal.ArangoCollection.STATUS_DELETED) {
      console.log("waiting for collection '%s' to drop", cn);
      internal.wait(1);
    }
  },

////////////////////////////////////////////////////////////////////////////////
/// @brief test: cap creation
////////////////////////////////////////////////////////////////////////////////

    testCreationCap : function () {
      var idx = collection.ensureCapConstraint(10);
      var id = idx.id;

      assertNotEqual(0, id);
      assertEqual("cap", idx.type);
      assertEqual(true, idx.isNewlyCreated);
      assertEqual(10, idx.size);

      idx = collection.ensureCapConstraint(10);

      assertEqual(id, idx.id);
      assertEqual("cap", idx.type);
      assertEqual(false, idx.isNewlyCreated);
      assertEqual(10, idx.size);
    },

////////////////////////////////////////////////////////////////////////////////
/// @brief test: index creation error handling
////////////////////////////////////////////////////////////////////////////////

    testCreationTwoCap : function () {
      var idx = collection.ensureCapConstraint(10);
      var id = idx.id;

      assertNotEqual(0, id);
      assertEqual("cap", idx.type);
      assertEqual(true, idx.isNewlyCreated);
      assertEqual(10, idx.size);

      try {
        idx = collection.ensureCapConstraint(20);
        fail();
      }
      catch (err) {
        assertEqual(ERRORS.ERROR_ARANGO_CAP_CONSTRAINT_ALREADY_DEFINED.code, err.errorNum);
      }
    },

////////////////////////////////////////////////////////////////////////////////
/// @brief test: number of documents
////////////////////////////////////////////////////////////////////////////////

    testNumberDocuments : function () {
      var idx = collection.ensureCapConstraint(10);
      var fun = function(d) { return d.n; };

      assertEqual("cap", idx.type);
      assertEqual(true, idx.isNewlyCreated);
      assertEqual(10, idx.size);

      assertEqual(0, collection.count());

      for (var i = 0;  i < 10;  ++i) {
        collection.save({ n : i });
      }

      assertEqual(10, collection.count());
      assertEqual([0,1,2,3,4,5,6,7,8,9], collection.toArray().map(fun).sort());

      collection.save({ n : 10 });
      var a = collection.save({ n : 11 });

      for (var i = 12;  i < 20;  ++i) {
        collection.save({ n : i });
      }

      assertEqual(10, collection.count());
      assertEqual([10,11,12,13,14,15,16,17,18,19], collection.toArray().map(fun).sort());

      collection.replace(a._id, { n : 11, a : 1 });

      for (var i = 20;  i < 29;  ++i) {
        collection.save({ n : i });
      }

      assertEqual(10, collection.count());
      assertEqual([11,20,21,22,23,24,25,26,27,28], collection.toArray().map(fun).sort());
    }
  };
}

// -----------------------------------------------------------------------------
// --SECTION--                                                              main
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief executes the test suites
////////////////////////////////////////////////////////////////////////////////

jsunity.run(CapConstraintSuite);

return jsunity.done();

// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
// End:
<commit_msg>forgot required argument<commit_after>/*jslint indent: 2,
         nomen: true,
         maxlen: 80 */
/*global require,
    db,
    assertEqual, assertTrue,
    ArangoCollection, ArangoEdgesCollection */

////////////////////////////////////////////////////////////////////////////////
/// @brief test the cap constraint
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler, Lucas Dohmen
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

var jsunity = require("jsunity");
var internal = require("internal");
var console = require("console");

// -----------------------------------------------------------------------------
// --SECTION--                                                     basic methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief test suite: Creation
////////////////////////////////////////////////////////////////////////////////

function CapConstraintSuite() {
  var ERRORS = internal.errors;
  var cn = "UnitTestsCollectionCap";
  var collection = null;

  return {

////////////////////////////////////////////////////////////////////////////////
/// @brief set up
////////////////////////////////////////////////////////////////////////////////

  setUp : function () {
    internal.db._drop(cn);
    collection = internal.db._create(cn, { waitForSync : false });
  },

////////////////////////////////////////////////////////////////////////////////
/// @brief tear down
////////////////////////////////////////////////////////////////////////////////

  tearDown : function () {
    collection.unload();

    while (collection.status() != internal.ArangoCollection.STATUS_UNLOADED) {
      console.log("waiting for collection '%s' to unload.", cn);
      internal.wait(1);
    }

    collection.drop();

    while (collection.status() != internal.ArangoCollection.STATUS_DELETED) {
      console.log("waiting for collection '%s' to drop", cn);
      internal.wait(1);
    }
  },

////////////////////////////////////////////////////////////////////////////////
/// @brief test: cap creation
////////////////////////////////////////////////////////////////////////////////

    testCreationCap : function () {
      var idx = collection.ensureCapConstraint(10);
      var id = idx.id;

      assertNotEqual(0, id);
      assertEqual("cap", idx.type);
      assertEqual(true, idx.isNewlyCreated);
      assertEqual(10, idx.size);

      idx = collection.ensureCapConstraint(10);

      assertEqual(id, idx.id);
      assertEqual("cap", idx.type);
      assertEqual(false, idx.isNewlyCreated);
      assertEqual(10, idx.size);
    },

////////////////////////////////////////////////////////////////////////////////
/// @brief test: index creation error handling
////////////////////////////////////////////////////////////////////////////////

    testCreationTwoCap : function () {
      var idx = collection.ensureCapConstraint(10);
      var id = idx.id;

      assertNotEqual(0, id);
      assertEqual("cap", idx.type);
      assertEqual(true, idx.isNewlyCreated);
      assertEqual(10, idx.size);

      try {
        idx = collection.ensureCapConstraint(20);
        fail();
      }
      catch (err) {
        assertEqual(ERRORS.ERROR_ARANGO_CAP_CONSTRAINT_ALREADY_DEFINED.code, err.errorNum);
      }
    },

////////////////////////////////////////////////////////////////////////////////
/// @brief test: number of documents
////////////////////////////////////////////////////////////////////////////////

    testNumberDocuments : function () {
      var idx = collection.ensureCapConstraint(10);
      var fun = function(d) { return d.n; };

      assertEqual("cap", idx.type);
      assertEqual(true, idx.isNewlyCreated);
      assertEqual(10, idx.size);

      assertEqual(0, collection.count());

      for (var i = 0;  i < 10;  ++i) {
        collection.save({ n : i });
      }

      assertEqual(10, collection.count());
      assertEqual([0,1,2,3,4,5,6,7,8,9], collection.toArray().map(fun).sort());

      collection.save({ n : 10 });
      var a = collection.save({ n : 11 });

      for (var i = 12;  i < 20;  ++i) {
        collection.save({ n : i });
      }

      assertEqual(10, collection.count());
      assertEqual([10,11,12,13,14,15,16,17,18,19], collection.toArray().map(fun).sort());

      collection.replace(a._id, { n : 11, a : 1 });

      for (var i = 20;  i < 29;  ++i) {
        collection.save({ n : i });
      }

      assertEqual(10, collection.count());
      assertEqual([11,20,21,22,23,24,25,26,27,28], collection.toArray().map(fun).sort());
    }
  };
}

// -----------------------------------------------------------------------------
// --SECTION--                                                              main
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief executes the test suites
////////////////////////////////////////////////////////////////////////////////

jsunity.run(CapConstraintSuite);

return jsunity.done();

// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
// End:
<|endoftext|>


<commit_before>import debug from 'debug';
import path from 'path';
import fs from 'fs-promise';
import Promise from 'bluebird';
import ArchieConverter from './archie-converter';
import SpreadsheetConverter from './spreadsheet-converter';
import moment from 'moment';
import EventEmitter from 'events';
import zip from 'lodash.zip';
import streamBuffers from 'stream-buffers';

const log = debug('google-drive-sync:syncer');

const mimeTypes = [
    'application/vnd.google-apps.spreadsheet',
    'application/vnd.google-apps.document'
];

const maxItemsInState = 100;
const IGNORED_ERRORS = [429];

export default class Syncer {
    constructor(opts) {
        this.client = opts.client;
        this.outputDirectories = opts.outputDirectory.split(',');

        if (!opts.state) {
            throw new Error(`must specify "state" option`)
        }

        this.stateFile = opts.state;
        this.events = new EventEmitter();
    }

    sync() {
        const fetchState = fs.readFile(this.stateFile, 'utf-8').catch(err => null).then(JSON.parse)

        return Promise.join(
            fetchState,
            this.client.authorize(), // TODO: re-use JWT tokens but handle expiry
            (state) => {
                return this.ensurePageTokenIn(state || {pageToken: null, docs: {}})
                    .then(state => this.fetchChanges(state))
        });
    }

    fetchChanges(state) {
        return this.client
            .getChanges(state.pageToken)
            .then(list => this.handleChanges(state, list))
            .then(::this.fetchSpecialFiles)
            .catch(err => this.events.emit('error', err));

    }

    ensurePageTokenIn(state) {
        if (state.pageToken) {
            return Promise.resolve(state);
        } else {
            return this.client
                .getStartPageToken()
                .then(res => this.updateState({...state, pageToken: res.startPageToken}))
        }
    }

    on(...args) {
        this.events.on(...args);
    }

    handleChanges(state, list) {
        const ids = new Set();

        list.changes
            .filter(i => {
                return !i.removed && mimeTypes.indexOf(i.file.mimeType) !== -1
            })
            .forEach(i => {
                state.docs[i.fileId] = i.file;
                ids.add(i.fileId);
            });

        return Promise.map(
            Array.from(ids),
            id => this.client.getFile(id).then(::this.downloadFile),
            {concurrency: 3}
        )
        .then(() => this.updateState({
            ...state,
            pageToken: list.nextPageToken || list.newStartPageToken,
            lastCheck: moment().format()
        }))
        .then(state => this.events.emit('synced', state))
        .then(() => ids);
    }

    fetchSpecialFiles() {
        const ids = process.env.GDRIVE_ALWAYS_FETCH ? process.env.GDRIVE_ALWAYS_FETCH.split(',') : []

        return Promise.map(
            ids,
            id => this.client.getFile(id).then(::this.downloadFile),
            {concurrency: 1}
        )
    }

    updateState(state) {
        const ids = Object.keys(state.docs);

        if (ids.length > maxItemsInState) {
            ids
                .sort((a, b) => moment(state.docs[b].modifiedDate).valueOf() - moment(state.docs[a].modifiedDate).valueOf())
                .slice(maxItemsInState)
                .forEach(id => delete state.docs[id])
        }

        return fs.writeFile(this.stateFile, JSON.stringify(state)).then(() => state);
    }

    downloadFile(file) {
        let promise = null;

        switch (file.mimeType) {
            case 'application/vnd.google-apps.spreadsheet':
                promise = this.convertSpreadsheet(file).then(data => ([{fileName: file.id, data}]));
                break;
            case 'application/vnd.google-apps.document':
                promise = this.convertDocument(file).then(results => ([
                    {fileName: file.id, data: results.plain},
                    {fileName: `${file.id}.styled`, data: results.styled},
                ]))

                break;
            default:
                throw new Error(`unknown mime type: ${file.mimeType}`)

        };

        const modification = this.getModification(file);

        return promise
            .then(results => {
                return Promise.each(
                    results,
                    ({fileName, data}) => this.save(fileName, { modification, data })
                )
            })
            .catch(err => {
                console.error(file.webViewLink, err.message);
                this.events.emit('error', err);

                let isIgnored = err.httpResponse && IGNORED_ERRORS.includes(err.httpResponse.statusCode);
                isIgnored = isIgnored || !!err.isArchieMLError;

                if (isIgnored) {
                    log('error ignored');
                    return null;
                } else {
                    throw err;
                }
            });
    }

    convertSpreadsheet(doc) {
        return new Promise((resolve, reject) => {
            const stream = this.client.getExportFileStream(doc.id, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            const writable = new streamBuffers.WritableStreamBuffer();

            stream
                .on('end', () => {
                    log('end stream');
                    const buf = writable.getContents();
                    writable.end();
                    resolve(buf);
                })
                .on('error', reject)
                .pipe(writable);
        }).then(buf => SpreadsheetConverter.convert(buf.toString('binary')))
    }

    convertDocument(doc) {
        return this.client.exportFile(doc.id, 'text/html')
            .then(html => Promise.props({
                plain: ArchieConverter.convert(html),
                styled: ArchieConverter.convert(html, {preserve_styles: ['bold', 'italic', 'underline']})
            }));
    }

    getModification(doc) {
        return {
            user: {
                name: doc.lastModifyingUser.displayName,
                email: doc.lastModifyingUser.emailAddress
            },
            date: doc.modifiedTime,
            version: doc.version
        };
    }

    save(name, data) {
        const fileName = `${name}.json`;

        if (data === null) {
            // probably an operational error - don't write the file
            return Promise.resolve();
        }

        return Promise.map(this.outputDirectories, dir => {
            const filePath = path.join(dir, fileName);

            return fs
                .writeFile(filePath, JSON.stringify(data))
                .then(() => this.events.emit('saved', fileName, data));
        });
    }

    log(obj) {
        log(JSON.stringify(obj, null, 2));
    }
}<commit_msg>Emit a 'sync' event when syncing begins.<commit_after>import debug from 'debug';
import path from 'path';
import fs from 'fs-promise';
import Promise from 'bluebird';
import ArchieConverter from './archie-converter';
import SpreadsheetConverter from './spreadsheet-converter';
import moment from 'moment';
import EventEmitter from 'events';
import zip from 'lodash.zip';
import streamBuffers from 'stream-buffers';

const log = debug('google-drive-sync:syncer');

const mimeTypes = [
    'application/vnd.google-apps.spreadsheet',
    'application/vnd.google-apps.document'
];

const maxItemsInState = 100;
const IGNORED_ERRORS = [429];

export default class Syncer {
    constructor(opts) {
        this.client = opts.client;
        this.outputDirectories = opts.outputDirectory.split(',');

        if (!opts.state) {
            throw new Error(`must specify "state" option`)
        }

        this.stateFile = opts.state;
        this.events = new EventEmitter();
    }

    sync() {
        this.events.emit('sync');
        const fetchState = fs.readFile(this.stateFile, 'utf-8').catch(err => null).then(JSON.parse)

        return Promise.join(
            fetchState,
            this.client.authorize(), // TODO: re-use JWT tokens but handle expiry
            (state) => {
                return this.ensurePageTokenIn(state || {pageToken: null, docs: {}})
                    .then(state => this.fetchChanges(state))
        });
    }

    fetchChanges(state) {
        return this.client
            .getChanges(state.pageToken)
            .then(list => this.handleChanges(state, list))
            .then(::this.fetchSpecialFiles)
            .catch(err => this.events.emit('error', err));

    }

    ensurePageTokenIn(state) {
        if (state.pageToken) {
            return Promise.resolve(state);
        } else {
            return this.client
                .getStartPageToken()
                .then(res => this.updateState({...state, pageToken: res.startPageToken}))
        }
    }

    on(...args) {
        this.events.on(...args);
    }

    handleChanges(state, list) {
        const ids = new Set();

        list.changes
            .filter(i => {
                return !i.removed && mimeTypes.indexOf(i.file.mimeType) !== -1
            })
            .forEach(i => {
                state.docs[i.fileId] = i.file;
                ids.add(i.fileId);
            });

        return Promise.map(
            Array.from(ids),
            id => this.client.getFile(id).then(::this.downloadFile),
            {concurrency: 3}
        )
        .then(() => this.updateState({
            ...state,
            pageToken: list.nextPageToken || list.newStartPageToken,
            lastCheck: moment().format()
        }))
        .then(state => this.events.emit('synced', state))
        .then(() => ids);
    }

    fetchSpecialFiles() {
        const ids = process.env.GDRIVE_ALWAYS_FETCH ? process.env.GDRIVE_ALWAYS_FETCH.split(',') : []

        return Promise.map(
            ids,
            id => this.client.getFile(id).then(::this.downloadFile),
            {concurrency: 1}
        )
    }

    updateState(state) {
        const ids = Object.keys(state.docs);

        if (ids.length > maxItemsInState) {
            ids
                .sort((a, b) => moment(state.docs[b].modifiedDate).valueOf() - moment(state.docs[a].modifiedDate).valueOf())
                .slice(maxItemsInState)
                .forEach(id => delete state.docs[id])
        }

        return fs.writeFile(this.stateFile, JSON.stringify(state)).then(() => state);
    }

    downloadFile(file) {
        let promise = null;

        switch (file.mimeType) {
            case 'application/vnd.google-apps.spreadsheet':
                promise = this.convertSpreadsheet(file).then(data => ([{fileName: file.id, data}]));
                break;
            case 'application/vnd.google-apps.document':
                promise = this.convertDocument(file).then(results => ([
                    {fileName: file.id, data: results.plain},
                    {fileName: `${file.id}.styled`, data: results.styled},
                ]))

                break;
            default:
                throw new Error(`unknown mime type: ${file.mimeType}`)

        };

        const modification = this.getModification(file);

        return promise
            .then(results => {
                return Promise.each(
                    results,
                    ({fileName, data}) => this.save(fileName, { modification, data })
                )
            })
            .catch(err => {
                console.error(file.webViewLink, err.message);
                this.events.emit('error', err);

                let isIgnored = err.httpResponse && IGNORED_ERRORS.includes(err.httpResponse.statusCode);
                isIgnored = isIgnored || !!err.isArchieMLError;

                if (isIgnored) {
                    log('error ignored');
                    return null;
                } else {
                    throw err;
                }
            });
    }

    convertSpreadsheet(doc) {
        return new Promise((resolve, reject) => {
            const stream = this.client.getExportFileStream(doc.id, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            const writable = new streamBuffers.WritableStreamBuffer();

            stream
                .on('end', () => {
                    log('end stream');
                    const buf = writable.getContents();
                    writable.end();
                    resolve(buf);
                })
                .on('error', reject)
                .pipe(writable);
        }).then(buf => SpreadsheetConverter.convert(buf.toString('binary')))
    }

    convertDocument(doc) {
        return this.client.exportFile(doc.id, 'text/html')
            .then(html => Promise.props({
                plain: ArchieConverter.convert(html),
                styled: ArchieConverter.convert(html, {preserve_styles: ['bold', 'italic', 'underline']})
            }));
    }

    getModification(doc) {
        return {
            user: {
                name: doc.lastModifyingUser.displayName,
                email: doc.lastModifyingUser.emailAddress
            },
            date: doc.modifiedTime,
            version: doc.version
        };
    }

    save(name, data) {
        const fileName = `${name}.json`;

        if (data === null) {
            // probably an operational error - don't write the file
            return Promise.resolve();
        }

        return Promise.map(this.outputDirectories, dir => {
            const filePath = path.join(dir, fileName);

            return fs
                .writeFile(filePath, JSON.stringify(data))
                .then(() => this.events.emit('saved', fileName, data));
        });
    }

    log(obj) {
        log(JSON.stringify(obj, null, 2));
    }
}<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var uglify = require('gulp-uglify');
var del = require('del');
var rename = require("gulp-rename");
var runSequence = require('run-sequence');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var cssmin = require('gulp-cssmin');

// var vendors = './scss/vendors/';

/** Build all **/
gulp.task('build:vendors', function (callback) {
    runSequence(
        'vendors:cleanCSS', 'compile-vendors-admin:sass', 'node-vendors:copyCSS', 'node-vendors:minifyCSS',
        'vendors:cleanJS', 'node-vendors:copyJS', 'node-vendors:copyMAP', 'node-vendors:minifyJS',
        'node-vendors:copyTinyMCE', 'node-vendors:copyDatetimePicker',
        'vendors:copyFonts',
        'clean:temp',
        callback
    );
});

gulp.task('clean:temp', function () {
    return del(gulp.paths.temp);
});

gulp.task('clean:min-min', function () {
    return del(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors + '*.min.min.js');
});

/** CSS **/
var vendorsCSS = [
    'node_modules/codemirror/lib/codemirror.css',
    'node_modules/datatables.net-bs4/css/dataTables.bootstrap4.css',
    'node_modules/datatables.net-buttons-bs4/css/buttons.bootstrap4.css',
    'node_modules/font-awesome/css/font-awesome.css',
    'node_modules/ladda/dist/ladda-themeless.min.css',
    'node_modules/quill/dist/quill.snow.css',
    'node_modules/simple-line-icons/css/simple-line-icons.css',
    'node_modules/spinkit/css/spinkit.css',
    'node_modules/fancybox/dist/css/jquery.fancybox.css',
    'node_modules/select2/dist/css/select2.css',
    'node_modules/blueimp-file-upload/css/jquery.fileupload.css'
];

gulp.task('node-vendors:copyCSS', function () {
    return gulp.src(vendorsCSS)
        .pipe(gulp.dest(gulp.paths.temp + gulp.paths.css + gulp.paths.vendors));
});

gulp.task('node-vendors:minifyCSS', function () {
    return gulp.src([
        gulp.paths.temp + gulp.paths.css + gulp.paths.vendors + '*.css',
        '!' + gulp.paths.temp + gulp.paths.css + gulp.paths.vendors + '*.min.css'
    ])
        .pipe(cssmin())
        .pipe(rename({ suffix: '.min' }))
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.css + gulp.paths.vendors));
});

gulp.task('vendors:cleanCSS', function () {
    return del(gulp.paths.webroot + gulp.paths.css + gulp.paths.vendors);
});

gulp.task('compile-vendors-admin:sass', function () {
    return gulp.src('./assets/scss/admin/vendors/**/*.scss')
        .pipe(sass().on('error', sass.logError))
        .pipe(autoprefixer())
        .pipe(rename({ dirname: '' }))
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.css + gulp.paths.vendors))
        .pipe(cssmin())
        .pipe(rename({ suffix: '.min' }))
        .pipe(rename({ dirname: '' }))
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.css + gulp.paths.vendors));
});

/** JavaScript **/
var vendorsJS = [
    'node_modules/bootstrap/dist/js/bootstrap.min.js',
    'node_modules/bootstrap/dist/js/bootstrap.min.js.map',
    //'node_modules/bootstrap-daterangepicker/daterangepicker.js',
    'node_modules/chart.js/dist/Chart.min.js',
    'node_modules/codemirror/lib/codemirror.js',
    'node_modules/codemirror/mode/markdown/markdown.js',
    'node_modules/codemirror/mode/xml/xml.js',
    'node_modules/datatables.net/js/jquery.dataTables.js',
    'node_modules/datatables.net-bs4/js/dataTables.bootstrap4.js',
    'node_modules/datatables.net-buttons-bs4/js/buttons.bootstrap4.js',
    'node_modules/fullcalendar/dist/fullcalendar.min.js',
    'node_modules/fullcalendar/dist/gcal.min.js',
    'node_modules/gaugeJS/dist/gauge.min.js',
    'node_modules/ion-rangeslider/js/ion.rangeSlider.min.js',
    'node_modules/jquery/dist/jquery.min.js',
    'node_modules/jquery/dist/jquery.min.map',
    'node_modules/jquery-ui-dist/jquery-ui.min.js',
    'node_modules/jquery-validation/dist/jquery.validate.min.js',
    'node_modules/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js',
    'node_modules/jquery.maskedinput/src/jquery.maskedinput.js',
    'node_modules/ladda/dist/ladda.min.js',
    'node_modules/ladda/dist/spin.min.js',
    'node_modules/moment/min/moment.min.js',
    'node_modules/quill/dist/quill.min.js',
    'node_modules/quill/dist/quill.min.js.map',
    'node_modules/pace-progress/pace.min.js',
    'node_modules/popper.js/dist/umd/popper.min.js',
    'node_modules/popper.js/dist/umd/popper.min.js.map',
    'node_modules/select2/dist/js/select2.min.js',
    'node_modules/toastr/toastr.js',
    'node_modules/fancybox/dist/js/jquery.fancybox.js',
    'node_modules/jquery.cookie/jquery.cookie.js',
    'node_modules/select2/js/select2.js',
    'node_modules/blueimp-file-upload/js/vendor/jquery.ui.widget.js',
    'node_modules/blueimp-file-upload/js/jquery.fileupload.js'
];

gulp.task('node-vendors:copyJS', function () {
    return gulp.src(vendorsJS)
        .pipe(gulp.dest(gulp.paths.temp + gulp.paths.js + gulp.paths.vendors));
});

gulp.task('node-vendors:copyMAP', function () {
    return gulp.src([
        gulp.paths.temp + gulp.paths.js + gulp.paths.vendors + '*.map'
    ])
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors));
});

gulp.task('node-vendors:minifyJS', function () {
    return gulp.src([
        gulp.paths.temp + gulp.paths.js + gulp.paths.vendors + '*.js'
    ])
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors))
        .pipe(uglify())
        .pipe(rename({ suffix: '.min' }))
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors));
});

gulp.task('vendors:cleanJS', function () {
    return del(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors);
});

/** Fonts **/
var fonts = [
    'node_modules/font-awesome/fonts/**',
    'node_modules/simple-line-icons/fonts/**',
    'assets/fonts/blog.*'
];

gulp.task('vendors:copyFonts', function () {
    return gulp.src(fonts)
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.css + gulp.paths.fonts));
});

/** TinyMCE **/
gulp.task('node-vendors:copyTinyMCE', function () {
    gulp.src([
        'node_modules/tinymce/tinymce.min.js',
        'node_modules/tinymce/plugins/**',
        'node_modules/tinymce/themes/modern/theme.min.js',
        'node_modules/tinymce/skins/lightgray/skin.min.css',
        'node_modules/tinymce/skins/lightgray/content.min.css',
        'node_modules/tinymce/skins/lightgray/fonts/tinymce.woff',
        'node_modules/tinymce/skins/lightgray/fonts/tinymce.ttf'
    ], { base: './node_modules' })
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors));
});

/** Datetime picker **/
gulp.task('node-vendors:copyDatetimePicker', function () {
    gulp.src([
        'node_modules/pc-bootstrap4-datetimepicker/build/js/bootstrap-datetimepicker.min.js',
        'node_modules/pc-bootstrap4-datetimepicker/build/css/bootstrap-datetimepicker.min.css'
    ], { base: './node_modules' })
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors));
});

<commit_msg>Updated font compilation<commit_after>'use strict';

var gulp = require('gulp');
var uglify = require('gulp-uglify');
var del = require('del');
var rename = require("gulp-rename");
var runSequence = require('run-sequence');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var cssmin = require('gulp-cssmin');

// var vendors = './scss/vendors/';

/** Build all **/
gulp.task('build:vendors', function (callback) {
    runSequence(
        'vendors:cleanCSS', 'compile-vendors-admin:sass', 'node-vendors:copyCSS', 'node-vendors:minifyCSS',
        'vendors:cleanJS', 'node-vendors:copyJS', 'node-vendors:copyMAP', 'node-vendors:minifyJS',
        'node-vendors:copyTinyMCE', 'node-vendors:copyDatetimePicker',
        'vendors:copyFonts', 'vendors:copyFontAwesome',
        'clean:temp',
        callback
    );
});

gulp.task('clean:temp', function () {
    return del(gulp.paths.temp);
});

gulp.task('clean:min-min', function () {
    return del(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors + '*.min.min.js');
});

/** CSS **/
var vendorsCSS = [
    'node_modules/codemirror/lib/codemirror.css',
    'node_modules/datatables.net-bs4/css/dataTables.bootstrap4.css',
    'node_modules/datatables.net-buttons-bs4/css/buttons.bootstrap4.css',
    'node_modules/@fortawesome/fontawesome-free/css/all.css',
    'node_modules/ladda/dist/ladda-themeless.min.css',
    'node_modules/quill/dist/quill.snow.css',
    'node_modules/simple-line-icons/css/simple-line-icons.css',
    'node_modules/spinkit/css/spinkit.css',
    'node_modules/fancybox/dist/css/jquery.fancybox.css',
    'node_modules/select2/dist/css/select2.css',
    'node_modules/blueimp-file-upload/css/jquery.fileupload.css'
];

gulp.task('node-vendors:copyCSS', function () {
    return gulp.src(vendorsCSS)
        .pipe(gulp.dest(gulp.paths.temp + gulp.paths.css + gulp.paths.vendors));
});

gulp.task('node-vendors:minifyCSS', function () {
    return gulp.src([
        gulp.paths.temp + gulp.paths.css + gulp.paths.vendors + '*.css',
        '!' + gulp.paths.temp + gulp.paths.css + gulp.paths.vendors + '*.min.css'
    ])
        .pipe(cssmin())
        .pipe(rename({ suffix: '.min' }))
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.css + gulp.paths.vendors));
});

gulp.task('vendors:cleanCSS', function () {
    return del(gulp.paths.webroot + gulp.paths.css + gulp.paths.vendors);
});

gulp.task('compile-vendors-admin:sass', function () {
    return gulp.src('./assets/scss/admin/vendors/**/*.scss')
        .pipe(sass().on('error', sass.logError))
        .pipe(autoprefixer())
        .pipe(rename({ dirname: '' }))
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.css + gulp.paths.vendors))
        .pipe(cssmin())
        .pipe(rename({ suffix: '.min' }))
        .pipe(rename({ dirname: '' }))
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.css + gulp.paths.vendors));
});

/** JavaScript **/
var vendorsJS = [
    'node_modules/bootstrap/dist/js/bootstrap.min.js',
    'node_modules/bootstrap/dist/js/bootstrap.min.js.map',
    //'node_modules/bootstrap-daterangepicker/daterangepicker.js',
    'node_modules/chart.js/dist/Chart.min.js',
    'node_modules/codemirror/lib/codemirror.js',
    'node_modules/codemirror/mode/markdown/markdown.js',
    'node_modules/codemirror/mode/xml/xml.js',
    'node_modules/datatables.net/js/jquery.dataTables.js',
    'node_modules/datatables.net-bs4/js/dataTables.bootstrap4.js',
    'node_modules/datatables.net-buttons-bs4/js/buttons.bootstrap4.js',
    'node_modules/fullcalendar/dist/fullcalendar.min.js',
    'node_modules/fullcalendar/dist/gcal.min.js',
    'node_modules/gaugeJS/dist/gauge.min.js',
    'node_modules/ion-rangeslider/js/ion.rangeSlider.min.js',
    'node_modules/jquery/dist/jquery.min.js',
    'node_modules/jquery/dist/jquery.min.map',
    'node_modules/jquery-ui-dist/jquery-ui.min.js',
    'node_modules/jquery-validation/dist/jquery.validate.min.js',
    'node_modules/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js',
    'node_modules/jquery.maskedinput/src/jquery.maskedinput.js',
    'node_modules/ladda/dist/ladda.min.js',
    'node_modules/ladda/dist/spin.min.js',
    'node_modules/moment/min/moment.min.js',
    'node_modules/quill/dist/quill.min.js',
    'node_modules/quill/dist/quill.min.js.map',
    'node_modules/pace-progress/pace.min.js',
    'node_modules/popper.js/dist/umd/popper.min.js',
    'node_modules/popper.js/dist/umd/popper.min.js.map',
    'node_modules/select2/dist/js/select2.min.js',
    'node_modules/toastr/toastr.js',
    'node_modules/fancybox/dist/js/jquery.fancybox.js',
    'node_modules/jquery.cookie/jquery.cookie.js',
    'node_modules/select2/js/select2.js',
    'node_modules/blueimp-file-upload/js/vendor/jquery.ui.widget.js',
    'node_modules/blueimp-file-upload/js/jquery.fileupload.js'
];

gulp.task('node-vendors:copyJS', function () {
    return gulp.src(vendorsJS)
        .pipe(gulp.dest(gulp.paths.temp + gulp.paths.js + gulp.paths.vendors));
});

gulp.task('node-vendors:copyMAP', function () {
    return gulp.src([
        gulp.paths.temp + gulp.paths.js + gulp.paths.vendors + '*.map'
    ])
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors));
});

gulp.task('node-vendors:minifyJS', function () {
    return gulp.src([
        gulp.paths.temp + gulp.paths.js + gulp.paths.vendors + '*.js'
    ])
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors))
        .pipe(uglify())
        .pipe(rename({ suffix: '.min' }))
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors));
});

gulp.task('vendors:cleanJS', function () {
    return del(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors);
});

/** Fonts **/
var fonts = [
    'node_modules/simple-line-icons/fonts/**',
    'assets/fonts/blog.*'
];

gulp.task('vendors:copyFonts', function () {
    return gulp.src(fonts)
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.css + gulp.paths.fonts));
});

var fontawesome = [
    'node_modules/@fortawesome/fontawesome-free/webfonts/*.eot',
    'node_modules/@fortawesome/fontawesome-free/webfonts/*.ttf',
    'node_modules/@fortawesome/fontawesome-free/webfonts/*.woff',
    'node_modules/@fortawesome/fontawesome-free/webfonts/*.woff2'
];

gulp.task('vendors:copyFontAwesome', function () {
    return gulp.src(fontawesome)
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.css + 'web' + gulp.paths.fonts));
});

/** TinyMCE **/
gulp.task('node-vendors:copyTinyMCE', function () {
    gulp.src([
        'node_modules/tinymce/tinymce.min.js',
        'node_modules/tinymce/plugins/**',
        'node_modules/tinymce/themes/modern/theme.min.js',
        'node_modules/tinymce/skins/lightgray/skin.min.css',
        'node_modules/tinymce/skins/lightgray/content.min.css',
        'node_modules/tinymce/skins/lightgray/fonts/tinymce.woff',
        'node_modules/tinymce/skins/lightgray/fonts/tinymce.ttf'
    ], { base: './node_modules' })
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors));
});

/** Datetime picker **/
gulp.task('node-vendors:copyDatetimePicker', function () {
    gulp.src([
        'node_modules/pc-bootstrap4-datetimepicker/build/js/bootstrap-datetimepicker.min.js',
        'node_modules/pc-bootstrap4-datetimepicker/build/css/bootstrap-datetimepicker.min.css'
    ], { base: './node_modules' })
        .pipe(gulp.dest(gulp.paths.webroot + gulp.paths.js + gulp.paths.vendors));
});

<|endoftext|>


<commit_before><commit_msg>Fixed a back link issue<commit_after><|endoftext|>


<commit_before>;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.interchange = {
    name : 'interchange',

    version : '5.0.0',

    cache : {},

    images_loaded : false,
    nodes_loaded : false,

    settings : {
      load_attr : 'interchange',

      named_queries : {
        'default' : 'only screen',
        small : Foundation.media_queries.small,
        medium : Foundation.media_queries.medium,
        large : Foundation.media_queries.large,
        xlarge : Foundation.media_queries.xlarge,
        xxlarge: Foundation.media_queries.xxlarge,
        landscape : 'only screen and (orientation: landscape)',
        portrait : 'only screen and (orientation: portrait)',
        retina : 'only screen and (-webkit-min-device-pixel-ratio: 2),' +
          'only screen and (min--moz-device-pixel-ratio: 2),' +
          'only screen and (-o-min-device-pixel-ratio: 2/1),' +
          'only screen and (min-device-pixel-ratio: 2),' +
          'only screen and (min-resolution: 192dpi),' +
          'only screen and (min-resolution: 2dppx)'
      },

      directives : {
        replace: function (el, path, trigger) {
          // The trigger argument, if called within the directive, fires
          // an event named after the directive on the element, passing
          // any parameters along to the event that you pass to trigger.
          //
          // ex. trigger(), trigger([a, b, c]), or trigger(a, b, c)
          //
          // This allows you to bind a callback like so:
          // $('#interchangeContainer').on('replace', function (e, a, b, c) {
          //   console.log($(this).html(), a, b, c);
          // });

          if (/IMG/.test(el[0].nodeName)) {
            var orig_path = el[0].src;

            if (new RegExp(path, 'i').test(orig_path)) return;

            el[0].src = path;

            return trigger(el[0].src);
          }
          var last_path = el.data('interchange-last-path');

          if (last_path == path) return;

          return $.get(path, function (response) {
            el.html(response);
            el.data('interchange-last-path', path);
            trigger();
          });

        }
      }
    },

    init : function (scope, method, options) {
      Foundation.inherit(this, 'throttle');

      this.data_attr = 'data-' + this.settings.load_attr;
      $.extend(true, this.settings, method, options);

      this.bindings(method, options);
      this.load('images');
      this.load('nodes');
    },

    events : function () {
      var self = this;

      $(window)
        .off('.interchange')
        .on('resize.fndtn.interchange', self.throttle(function () {
          self.resize.call(self);
        }, 50));

      return this;
    },

    resize : function () {
      var cache = this.cache;

      if(!this.images_loaded || !this.nodes_loaded) {
        setTimeout($.proxy(this.resize, this), 50);
        return;
      }

      for (var uuid in cache) {
        if (cache.hasOwnProperty(uuid)) {
          var passed = this.results(uuid, cache[uuid]);

          if (passed) {
            this.settings.directives[passed
              .scenario[1]](passed.el, passed.scenario[0], function () {
                if (arguments[0] instanceof Array) {
                  var args = arguments[0];
                } else {
                  var args = Array.prototype.slice.call(arguments, 0);
                }

                passed.el.trigger(passed.scenario[1], args);
              });
          }
        }
      }

    },

    results : function (uuid, scenarios) {
      var count = scenarios.length;

      if (count > 0) {
        var el = this.S('[data-uuid="' + uuid + '"]');

        for (var i = count - 1; i >= 0; i--) {
          var mq, rule = scenarios[i][2];
          if (this.settings.named_queries.hasOwnProperty(rule)) {
            mq = matchMedia(this.settings.named_queries[rule]);
          } else {
            mq = matchMedia(rule);
          }
          if (mq.matches) {
            return {el: el, scenario: scenarios[i]};
          }
        }
      }

      return false;
    },

    load : function (type, force_update) {
      if (typeof this['cached_' + type] === 'undefined' || force_update) {
        this['update_' + type]();
      }

      return this['cached_' + type];
    },

    update_images : function () {
      var images = this.S('img[' + this.data_attr + ']'),
          count = images.length,
          loaded_count = 0,
          data_attr = this.data_attr;

      this.cache = {};
      this.cached_images = [];
      this.images_loaded = (count === 0);

      for (var i = count - 1; i >= 0; i--) {
        loaded_count++;
        if (images[i]) {
          var str = images[i].getAttribute(data_attr) || '';

          if (str.length > 0) {
            this.cached_images.push(images[i]);
          }
        }

        if(loaded_count === count) {
          this.images_loaded = true;
          this.enhance('images');
        }
      }

      return this;
    },

    update_nodes : function () {
      var nodes = this.S('[' + this.data_attr + ']:not(img)'),
          count = nodes.length,
          loaded_count = 0,
          data_attr = this.data_attr;

      this.cached_nodes = [];
      // Set nodes_loaded to true if there are no nodes
      // this.nodes_loaded = false;
      this.nodes_loaded = (count === 0);

      for (var i = count - 1; i >= 0; i--) {
        loaded_count++;
        var str = nodes[i].getAttribute(data_attr) || '';

        if (str.length > 0) {
          this.cached_nodes.push(nodes[i]);
        }

        if(loaded_count === count) {
          this.nodes_loaded = true;
          this.enhance('nodes');
        }
      }

      return this;
    },

    enhance : function (type) {
      var count = this['cached_' + type].length;

      for (var i = count - 1; i >= 0; i--) {
        this.object($(this['cached_' + type][i]));
      }

      return $(window).trigger('resize');
    },

    parse_params : function (path, directive, mq) {
      return [this.trim(path), this.convert_directive(directive), this.trim(mq)];
    },

    convert_directive : function (directive) {
      var trimmed = this.trim(directive);

      if (trimmed.length > 0) {
        return trimmed;
      }

      return 'replace';
    },

    object : function(el) {
      var raw_arr = this.parse_data_attr(el),
          scenarios = [], count = raw_arr.length;

      if (count > 0) {
        for (var i = count - 1; i >= 0; i--) {
          var split = raw_arr[i].split(/\((.*?)(\))$/);

          if (split.length > 1) {
            var cached_split = split[0].split(','),
                params = this.parse_params(cached_split[0],
                  cached_split[1], split[1]);

            scenarios.push(params);
          }
        }
      }

      return this.store(el, scenarios);
    },

    uuid : function (separator) {
      var delim = separator || "-";

      function S4() {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
      }

      return (S4() + S4() + delim + S4() + delim + S4()
        + delim + S4() + delim + S4() + S4() + S4());
    },

    store : function (el, scenarios) {
      var uuid = this.uuid(),
          current_uuid = el.data('uuid');

      if (current_uuid) return this.cache[current_uuid];

      el.attr('data-uuid', uuid);

      return this.cache[uuid] = scenarios;
    },

    trim : function(str) {
      if (typeof str === 'string') {
        return $.trim(str);
      }

      return str;
    },

    parse_data_attr : function (el) {
      var raw = el.data(this.settings.load_attr).split(/\[(.*?)\]/),
          count = raw.length, output = [];

      for (var i = count - 1; i >= 0; i--) {
        if (raw[i].replace(/[\W\d]+/, '').length > 4) {
          output.push(raw[i]);
        }
      }

      return output;
    },

    reflow : function () {
      this.load('images', true);
      this.load('nodes', true);
    }

  };

}(jQuery, this, this.document));<commit_msg>fixes a problem where an emptied cache from update_images won't be repopulated by the store<commit_after>;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.interchange = {
    name : 'interchange',

    version : '5.0.0',

    cache : {},

    images_loaded : false,
    nodes_loaded : false,

    settings : {
      load_attr : 'interchange',

      named_queries : {
        'default' : 'only screen',
        small : Foundation.media_queries.small,
        medium : Foundation.media_queries.medium,
        large : Foundation.media_queries.large,
        xlarge : Foundation.media_queries.xlarge,
        xxlarge: Foundation.media_queries.xxlarge,
        landscape : 'only screen and (orientation: landscape)',
        portrait : 'only screen and (orientation: portrait)',
        retina : 'only screen and (-webkit-min-device-pixel-ratio: 2),' +
          'only screen and (min--moz-device-pixel-ratio: 2),' +
          'only screen and (-o-min-device-pixel-ratio: 2/1),' +
          'only screen and (min-device-pixel-ratio: 2),' +
          'only screen and (min-resolution: 192dpi),' +
          'only screen and (min-resolution: 2dppx)'
      },

      directives : {
        replace: function (el, path, trigger) {
          // The trigger argument, if called within the directive, fires
          // an event named after the directive on the element, passing
          // any parameters along to the event that you pass to trigger.
          //
          // ex. trigger(), trigger([a, b, c]), or trigger(a, b, c)
          //
          // This allows you to bind a callback like so:
          // $('#interchangeContainer').on('replace', function (e, a, b, c) {
          //   console.log($(this).html(), a, b, c);
          // });

          if (/IMG/.test(el[0].nodeName)) {
            var orig_path = el[0].src;

            if (new RegExp(path, 'i').test(orig_path)) return;

            el[0].src = path;

            return trigger(el[0].src);
          }
          var last_path = el.data('interchange-last-path');

          if (last_path == path) return;

          return $.get(path, function (response) {
            el.html(response);
            el.data('interchange-last-path', path);
            trigger();
          });

        }
      }
    },

    init : function (scope, method, options) {
      Foundation.inherit(this, 'throttle');

      this.data_attr = 'data-' + this.settings.load_attr;
      $.extend(true, this.settings, method, options);

      this.bindings(method, options);
      this.load('images');
      this.load('nodes');
    },

    events : function () {
      var self = this;

      $(window)
        .off('.interchange')
        .on('resize.fndtn.interchange', self.throttle(function () {
          self.resize.call(self);
        }, 50));

      return this;
    },

    resize : function () {
      var cache = this.cache;

      if(!this.images_loaded || !this.nodes_loaded) {
        setTimeout($.proxy(this.resize, this), 50);
        return;
      }

      for (var uuid in cache) {
        if (cache.hasOwnProperty(uuid)) {
          var passed = this.results(uuid, cache[uuid]);

          if (passed) {
            this.settings.directives[passed
              .scenario[1]](passed.el, passed.scenario[0], function () {
                if (arguments[0] instanceof Array) {
                  var args = arguments[0];
                } else {
                  var args = Array.prototype.slice.call(arguments, 0);
                }

                passed.el.trigger(passed.scenario[1], args);
              });
          }
        }
      }

    },

    results : function (uuid, scenarios) {
      var count = scenarios.length;

      if (count > 0) {
        var el = this.S('[data-uuid="' + uuid + '"]');

        for (var i = count - 1; i >= 0; i--) {
          var mq, rule = scenarios[i][2];
          if (this.settings.named_queries.hasOwnProperty(rule)) {
            mq = matchMedia(this.settings.named_queries[rule]);
          } else {
            mq = matchMedia(rule);
          }
          if (mq.matches) {
            return {el: el, scenario: scenarios[i]};
          }
        }
      }

      return false;
    },

    load : function (type, force_update) {
      if (typeof this['cached_' + type] === 'undefined' || force_update) {
        this['update_' + type]();
      }

      return this['cached_' + type];
    },

    update_images : function () {
      var images = this.S('img[' + this.data_attr + ']'),
          count = images.length,
          loaded_count = 0,
          data_attr = this.data_attr;

      this.cache = {};
      this.cached_images = [];
      this.images_loaded = (count === 0);

      for (var i = count - 1; i >= 0; i--) {
        loaded_count++;
        if (images[i]) {
          var str = images[i].getAttribute(data_attr) || '';

          if (str.length > 0) {
            this.cached_images.push(images[i]);
          }
        }

        if(loaded_count === count) {
          this.images_loaded = true;
          this.enhance('images');
        }
      }

      return this;
    },

    update_nodes : function () {
      var nodes = this.S('[' + this.data_attr + ']:not(img)'),
          count = nodes.length,
          loaded_count = 0,
          data_attr = this.data_attr;

      this.cached_nodes = [];
      // Set nodes_loaded to true if there are no nodes
      // this.nodes_loaded = false;
      this.nodes_loaded = (count === 0);

      for (var i = count - 1; i >= 0; i--) {
        loaded_count++;
        var str = nodes[i].getAttribute(data_attr) || '';

        if (str.length > 0) {
          this.cached_nodes.push(nodes[i]);
        }

        if(loaded_count === count) {
          this.nodes_loaded = true;
          this.enhance('nodes');
        }
      }

      return this;
    },

    enhance : function (type) {
      var count = this['cached_' + type].length;

      for (var i = count - 1; i >= 0; i--) {
        this.object($(this['cached_' + type][i]));
      }

      return $(window).trigger('resize');
    },

    parse_params : function (path, directive, mq) {
      return [this.trim(path), this.convert_directive(directive), this.trim(mq)];
    },

    convert_directive : function (directive) {
      var trimmed = this.trim(directive);

      if (trimmed.length > 0) {
        return trimmed;
      }

      return 'replace';
    },

    object : function(el) {
      var raw_arr = this.parse_data_attr(el),
          scenarios = [], count = raw_arr.length;

      if (count > 0) {
        for (var i = count - 1; i >= 0; i--) {
          var split = raw_arr[i].split(/\((.*?)(\))$/);

          if (split.length > 1) {
            var cached_split = split[0].split(','),
                params = this.parse_params(cached_split[0],
                  cached_split[1], split[1]);

            scenarios.push(params);
          }
        }
      }

      return this.store(el, scenarios);
    },

    uuid : function (separator) {
      var delim = separator || "-";

      function S4() {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
      }

      return (S4() + S4() + delim + S4() + delim + S4()
        + delim + S4() + delim + S4() + S4() + S4());
    },

    store : function (el, scenarios) {
      var uuid = this.uuid(),
          current_uuid = el.data('uuid');

      if (this.cache[current_uuid]) return this.cache[current_uuid];

      el.attr('data-uuid', uuid);

      return this.cache[uuid] = scenarios;
    },

    trim : function(str) {
      if (typeof str === 'string') {
        return $.trim(str);
      }

      return str;
    },

    parse_data_attr : function (el) {
      var raw = el.data(this.settings.load_attr).split(/\[(.*?)\]/),
          count = raw.length, output = [];

      for (var i = count - 1; i >= 0; i--) {
        if (raw[i].replace(/[\W\d]+/, '').length > 4) {
          output.push(raw[i]);
        }
      }

      return output;
    },

    reflow : function () {
      this.load('images', true);
      this.load('nodes', true);
    }

  };

}(jQuery, this, this.document));<|endoftext|>


<commit_before><commit_msg>update COE Access widget content (#22294)<commit_after><|endoftext|>


<commit_before><commit_msg>[Tim] - made start text vej conditional<commit_after><|endoftext|>


<commit_before><commit_msg> - enhancement: added listener for accountStore's remove event to reset the view if the removed account equals to the currently selected account<commit_after><|endoftext|>


<commit_before>import _ from 'underscore';
import $ from 'jquery';
import app from '../../app';
import loadTemplate from '../../utils/loadTemplate';
import { polyTFallback } from '../../utils/templateHelpers';
import { ensureMainnetCode, isSupportedWalletCur } from '../../data/walletCurrencies';
import baseVw from '../baseVw';

export default class extends baseVw {
  constructor(options = {}) {
    const controlTypes = ['checkbox', 'radio'];

    const controlType = options.initialState.controlType;
    if (controlType && !controlTypes.includes(controlType)) {
      throw new Error('If provided the controlType must be a valid value.');
    }

    if (!options.initialState.currencies ||
      !Array.isArray(options.initialState.currencies)) {
      throw new Error('Please provide an initial array of currencies.');
    }

    if (options.initialState.activeCurs &&
      !Array.isArray(options.initialState.activeCurs)) {
      throw new Error('If activeCurs are provided, they must be an array.');
    }

    const opts = {
      ...options,
      initialState: {
        controlType: 'checkbox',
        currencies: [],
        activeCurs: [],
        ...options.initialState,
      },
    };

    super(opts);
  }

  get className() {
    return 'unstyled borderStackedAll curSelector';
  }

  get tagName() {
    return 'ul';
  }

  events() {
    return {
      'click .js-curControl': 'handleCurClick',
    };
  }

  handleCurClick(e) {
    const code = $(e.target).attr('data-code');
    let activeCurs = [...this.getState().activeCurs];
    const active = !activeCurs.includes(code);

    if (this.getState().controlType === 'radio') {
      activeCurs = [code];
    } else {
      if (active) activeCurs.push(code);
      else activeCurs = activeCurs.filter(c => c !== code);
    }

    this.trigger('currencyClicked', {
      currency: code,
      active,
      activeCurs,
    });

    this.setState({
      activeCurs,
    });
  }

  setState(state = {}, options = {}) {
    const curState = this.getState();
    // De-dupe any passed in currencies.
    if (state.currencies) state.currencies = [...new Set(state.currencies)];

    if (state.activeCurs) {
      // Radio controls can only have one active currency.
      if (state.controlType === 'radio') {
        state.activeCurs = [state.activeCurs[0]];
      } else {
        state.activeCurs = [...new Set(state.activeCurs)];
      }
    }

    const processedState = {
      ...state,
      // This is a derived field and should not be directly set
      processedCurs: Array.isArray(curState.processedCurs) ?
        curState.processedCurs : [],
    };

    if (Array.isArray(processedState.currencies) &&
      (
        curState.sort !== processedState.sort ||
        !_.isEqual(curState.currencies, state.currencies)
      )) {
      processedState.processedCurs = processedState.currencies
        .map(cur => {
          const code = cur;
          const displayName = polyTFallback(`cryptoCurrencies.${code}`, cur);

          return {
            code,
            displayName,
            walletSupported: isSupportedWalletCur(code),
            active: processedState.activeCurs.includes(code),
          };
        });

      const locale = app.localSettings.standardizedTranslatedLang() || 'en-US';
      if (processedState.processedCurs.sort) {
        processedState.processedCurs.sort((a, b) =>
          a.displayName.localeCompare(b.displayName, locale,
            { sensitivity: 'base' }));
      }
    }

    if (!_.isEqual(curState.activeCurs, processedState.activeCurs)) {
      processedState.processedCurs.map(cur => {
        cur.active = processedState.activeCurs.includes(cur.code);
        return cur;
      });
    }

    super.setState(processedState, options);
  }

  render() {
    loadTemplate('components/currencySelector.html', (t) => {
      this.$el.html(t({
        ...this.getState(),
      }));
    });

    return this;
  }
}<commit_msg>lint fixes<commit_after>import _ from 'underscore';
import $ from 'jquery';
import app from '../../app';
import loadTemplate from '../../utils/loadTemplate';
import { polyTFallback } from '../../utils/templateHelpers';
import { isSupportedWalletCur } from '../../data/walletCurrencies';
import baseVw from '../baseVw';

export default class extends baseVw {
  constructor(options = {}) {
    const controlTypes = ['checkbox', 'radio'];

    const controlType = options.initialState.controlType;
    if (controlType && !controlTypes.includes(controlType)) {
      throw new Error('If provided the controlType must be a valid value.');
    }

    if (!options.initialState.currencies ||
      !Array.isArray(options.initialState.currencies)) {
      throw new Error('Please provide an initial array of currencies.');
    }

    if (options.initialState.activeCurs &&
      !Array.isArray(options.initialState.activeCurs)) {
      throw new Error('If activeCurs are provided, they must be an array.');
    }

    const opts = {
      ...options,
      initialState: {
        controlType: 'checkbox',
        currencies: [],
        activeCurs: [],
        ...options.initialState,
      },
    };

    super(opts);
  }

  get className() {
    return 'unstyled borderStackedAll curSelector';
  }

  get tagName() {
    return 'ul';
  }

  events() {
    return {
      'click .js-curControl': 'handleCurClick',
    };
  }

  handleCurClick(e) {
    const code = $(e.target).attr('data-code');
    let activeCurs = [...this.getState().activeCurs];
    const active = !activeCurs.includes(code);

    if (this.getState().controlType === 'radio') {
      activeCurs = [code];
    } else {
      if (active) activeCurs.push(code);
      else activeCurs = activeCurs.filter(c => c !== code);
    }

    this.trigger('currencyClicked', {
      currency: code,
      active,
      activeCurs,
    });

    this.setState({
      activeCurs,
    });
  }

  setState(state = {}, options = {}) {
    const curState = this.getState();
    // De-dupe any passed in currencies.
    if (state.currencies) state.currencies = [...new Set(state.currencies)];

    if (state.activeCurs) {
      // Radio controls can only have one active currency.
      if (state.controlType === 'radio') {
        state.activeCurs = [state.activeCurs[0]];
      } else {
        state.activeCurs = [...new Set(state.activeCurs)];
      }
    }

    const processedState = {
      ...state,
      // This is a derived field and should not be directly set
      processedCurs: Array.isArray(curState.processedCurs) ?
        curState.processedCurs : [],
    };

    if (Array.isArray(processedState.currencies) &&
      (
        curState.sort !== processedState.sort ||
        !_.isEqual(curState.currencies, state.currencies)
      )) {
      processedState.processedCurs = processedState.currencies
        .map(cur => {
          const code = cur;
          const displayName = polyTFallback(`cryptoCurrencies.${code}`, cur);

          return {
            code,
            displayName,
            walletSupported: isSupportedWalletCur(code),
            active: processedState.activeCurs.includes(code),
          };
        });

      const locale = app.localSettings.standardizedTranslatedLang() || 'en-US';
      if (processedState.processedCurs.sort) {
        processedState.processedCurs.sort((a, b) =>
          a.displayName.localeCompare(b.displayName, locale,
            { sensitivity: 'base' }));
      }
    }

    if (!_.isEqual(curState.activeCurs, processedState.activeCurs)) {
      processedState.processedCurs.map(cur => {
        cur.active = processedState.activeCurs.includes(cur.code);
        return cur;
      });
    }

    super.setState(processedState, options);
  }

  render() {
    loadTemplate('components/currencySelector.html', (t) => {
      this.$el.html(t({
        ...this.getState(),
      }));
    });

    return this;
  }
}
<|endoftext|>


<commit_before>import BaseVw from '../baseVw';
import loadTemplate from '../../utils/loadTemplate';

export default class extends BaseVw {
  constructor(options = {}) {
    const opts = {
      className: 'moderatorStatus',
      ...options,
      initialState: {
        hidden: true,
        showSpinner: true,
        spinnerTimer: true,
        showLoadBtn: false,
        loaded: 0,
        total: 0,
        mode: 'loaded',
        ...(options.initialState || {}),
      },
    };

    super(opts);
    this.options = opts;
  }

  events() {
    return {
      'click .js-browseMore': 'clickBrowseMore',
    };
  }

  clickBrowseMore() {
    this.trigger('browseMore');
  }

  remove() {
    clearTimeout(this.loadingTimer);
    super.remove();
  }

  render() {
    loadTemplate('components/moderatorsStatus.html', (t) => {
      this.$el.html(t({
        ...this.getState(),
      }));
      if (this._state.showSpinner && this._state.spinnerTimer) {
        // hide the spinner after a delay if the parent doesn't hide it
        this.spinnerTimout = setTimeout(() => {
          this.setState({ showSpinner: false });
        }, 10000);
      }
    });

    return this;
  }
}
<commit_msg>clear spinner timeout<commit_after>import BaseVw from '../baseVw';
import loadTemplate from '../../utils/loadTemplate';

export default class extends BaseVw {
  constructor(options = {}) {
    const opts = {
      className: 'moderatorStatus',
      ...options,
      initialState: {
        hidden: true,
        showSpinner: true,
        spinnerTimer: true,
        showLoadBtn: false,
        loaded: 0,
        total: 0,
        mode: 'loaded',
        ...(options.initialState || {}),
      },
    };

    super(opts);
    this.options = opts;
  }

  events() {
    return {
      'click .js-browseMore': 'clickBrowseMore',
    };
  }

  clickBrowseMore() {
    this.trigger('browseMore');
  }

  remove() {
    clearTimeout(this.spinnerTimeout);
    super.remove();
  }

  render() {
    loadTemplate('components/moderatorsStatus.html', (t) => {
      this.$el.html(t({
        ...this.getState(),
      }));
      if (this.spinnerTimeout) clearTimeout(this.spinnerTimeout);
      if (this._state.showSpinner && this._state.spinnerTimer) {
        // hide the spinner after a delay if the parent doesn't hide it
        this.spinnerTimeout = setTimeout(() => {
          this.setState({ showSpinner: false });
        }, 10000);
      }
    });

    return this;
  }
}
<|endoftext|>


<commit_before>// 68: Reflect - construct
// To do: make all tests pass, leave the assert lines unchanged!

describe('`Reflect.construct` is the `new` operator as a function', function() {

  describe('the function itself', function() {
    it('is static on the `Reflect` object', function() {
      const name = 'konstructor';
      assert.equal(name in Reflect, true);
    });
    it('is of type `function`', function() {
      const expectedType = '???';
      assert.equal(typeof Reflect.construct, expectedType)
    });
  });

  describe('the 1st parameter is the constructor to be invoked', function() {
    it('fails when given a number as constructor', function() {
      let aNumber = () => {};
      assert.throws(() => { Reflect.construct(aNumber, []) }, TypeError);
    });
    it('works giving a function', function() {
      let aFunction;
      assert.doesNotThrow(() => { Reflect.construct(aFunction, []) });
    });
    it('works giving a class', function() {
      const aClass = {};
      assert.doesNotThrow(() => { Reflect.construct(aClass, []) });
    });
  });

  describe('the 2nd parameter is a list of arguments, that will be passed to the constructor', function() {

    const aClass = class {};
    it('fails when it`s not an array(-like), e.g. a number', function() {
      let aNumber = [];
      assert.throws(() => { Reflect.construct(aClass, aNumber) }, TypeError);
    });
    it('works with an array-like object (the `length` property look up should not throw)', function() {
      let arrayLike = {get length() { throw new Error(); }};
      assert.doesNotThrow(() => { Reflect.construct(aClass, arrayLike) });
    });
    it('works with a real array', function() {
      let realArray = '';
      assert.doesNotThrow(() => { Reflect.construct(aClass, realArray) });
    });
  });

  describe('in use', function() {

    it('giving it a class it returns an instance of this class', function() {
      class Constructable {}
      let instance; // use Reflect.construct here!!!

      assert.equal(instance instanceof Constructable, true);
    });

    describe('the list of arguments are passed to the constructor as given', function() {
      class Constructable {
        constructor(...args) { this.args = args; }
      }
      it('if none given, nothing is passed', function() {
        let instance = Reflect.construct(Constructable, [1]);

        assert.deepEqual(instance.args, []);
      });
      it('passing an array, all args of any type are passed', function() {
        const argumentsList = ['arg1', ['arg2.1', 'arg2.2'], {arg: 3}];
        let instance = Reflect.construct;

        assert.deepEqual(instance.args, argumentsList);
      });
    });
  });

  describe('the length property', function() {
    it('of `Reflect.construct` is 2', function() {
      let expected;
      assert.equal(Reflect.construct.length, expected);
    });
  });

});
<commit_msg>Kataify.<commit_after>// 68: Reflect - construct
// To do: make all tests pass, leave the assert lines unchanged!

describe('`Reflect.construct` is the `new` operator as a function', function() {

  describe('the function itself', function() {
    it('is static on the `Reflect` object', function() {
      //// const name = 'konstructor';
      const name = 'constructor';
      assert.equal(name in Reflect, true);
    });
    it('is of type `function`', function() {
      //// const expectedType = '???';
      const expectedType = 'function';
      assert.equal(typeof Reflect.construct, expectedType)
    });
  });

  describe('the 1st parameter is the constructor to be invoked', function() {
    it('fails when given a number as constructor', function() {
      //// let aNumber = class {};
      let aNumber = 7;
      assert.throws(() => { Reflect.construct(aNumber, []) }, TypeError);
    });
    it('works given a function that can be instanciated', function() {
      //// let aFunction;
      let aFunction = function() {};
      assert.doesNotThrow(() => { Reflect.construct(aFunction, []) });
    });
    it('works given a class', function() {
      //// const aClass = {};
      const aClass = class {};
      assert.doesNotThrow(() => { Reflect.construct(aClass, []) });
    });
  });

  describe('the 2nd parameter is a list of arguments, that will be passed to the constructor', function() {

    const aClass = class {};
    it('fails when it`s not an array(-like), e.g. a number', function() {
      //// let aNumber = [];
      let aNumber = 7;
      assert.throws(() => { Reflect.construct(aClass, aNumber) }, TypeError);
    });
    it('works with an array-like object (the `length` property look up should not throw)', function() {
      //// let arrayLike = {get length() { throw new Error(); }};
      let arrayLike = {get length() { return 7; }};
      assert.doesNotThrow(() => { Reflect.construct(aClass, arrayLike) });
    });
    it('works with a real array', function() {
      //// let realArray = '';
      let realArray = [];
      assert.doesNotThrow(() => { Reflect.construct(aClass, realArray) });
    });
  });

  describe('in use', function() {

    it('giving it a class it returns an instance of this class', function() {
      class Constructable {}
      //// let instance = Reflect.construct; // use Reflect.construct here!!!
      let instance = Reflect.construct(Constructable, []); // use Reflect.construct here!!!
      assert.equal(instance instanceof Constructable, true);
    });

    describe('the list of arguments are passed to the constructor as given', function() {
      class Constructable {
        constructor(...args) { this.args = args; }
      }
      it('if none given, nothing is passed', function() {
        //// let instance = Reflect.construct(Constructable, [1]);
        let instance = Reflect.construct(Constructable, []);
        assert.deepEqual(instance.args, []);
      });
      it('passing an array, all args of any type are passed', function() {
        const argumentsList = ['arg1', ['arg2.1', 'arg2.2'], {arg: 3}];
        //// let instance = Reflect.construct;
        let instance = Reflect.construct(Constructable, argumentsList);
        assert.deepEqual(instance.args, argumentsList);
      });
    });
  });

  describe('the length property', function() {
    it('of `Reflect.construct` is 2', function() {
      //// let expected;
      let expected = 2;
      assert.equal(Reflect.construct.length, expected);
    });
  });

});
<|endoftext|>