vendor/assets/javascripts/sir-trevor.js in blacklight-spotlight-0.3.1 vs vendor/assets/javascripts/sir-trevor.js in blacklight-spotlight-0.4.1

- old
+ new

@@ -1,16 +1,16 @@ /*! - * Sir Trevor JS v0.5.0-beta1 + * Sir Trevor JS v0.5.0-beta3 * * Released under the MIT license * www.opensource.org/licenses/MIT * - * 2015-01-09 + * 2015-03-04 */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.SirTrevor=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.SirTrevor = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ module.exports = require('./src/'); },{"./src/":176}],2:[function(require,module,exports){ // Array.prototype.find - MIT License (c) 2013 Paul Miller <http://paulmillr.com> // For all details and docs: https://github.com/paulmillr/array.prototype.find @@ -822,14 +822,14 @@ module.exports = baseCreate; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"lodash._isnative":14,"lodash.isobject":29,"lodash.noop":15}],14:[function(require,module,exports){ -module.exports=require(8) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash._basecreatecallback/node_modules/lodash._setbinddata/node_modules/lodash._isnative/index.js":8}],15:[function(require,module,exports){ -module.exports=require(9) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash._basecreatecallback/node_modules/lodash._setbinddata/node_modules/lodash.noop/index.js":9}],16:[function(require,module,exports){ +arguments[4][8][0].apply(exports,arguments) +},{"dup":8}],15:[function(require,module,exports){ +arguments[4][9][0].apply(exports,arguments) +},{"dup":9}],16:[function(require,module,exports){ /** * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/> * Build: `lodash modularize modern exports="npm" -o ./npm/` * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE> @@ -906,16 +906,16 @@ } module.exports = baseCreateWrapper; },{"lodash._basecreate":17,"lodash._setbinddata":7,"lodash._slice":20,"lodash.isobject":29}],17:[function(require,module,exports){ -module.exports=require(13) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash._basecreatecallback/node_modules/lodash.bind/node_modules/lodash._createwrapper/node_modules/lodash._basebind/node_modules/lodash._basecreate/index.js":13,"lodash._isnative":18,"lodash.isobject":29,"lodash.noop":19}],18:[function(require,module,exports){ -module.exports=require(8) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash._basecreatecallback/node_modules/lodash._setbinddata/node_modules/lodash._isnative/index.js":8}],19:[function(require,module,exports){ -module.exports=require(9) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash._basecreatecallback/node_modules/lodash._setbinddata/node_modules/lodash.noop/index.js":9}],20:[function(require,module,exports){ +arguments[4][13][0].apply(exports,arguments) +},{"dup":13,"lodash._isnative":18,"lodash.isobject":29,"lodash.noop":19}],18:[function(require,module,exports){ +arguments[4][8][0].apply(exports,arguments) +},{"dup":8}],19:[function(require,module,exports){ +arguments[4][9][0].apply(exports,arguments) +},{"dup":9}],20:[function(require,module,exports){ /** * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/> * Build: `lodash modularize modern exports="npm" -o ./npm/` * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE> @@ -1026,12 +1026,12 @@ module.exports = support; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"lodash._isnative":23}],23:[function(require,module,exports){ -module.exports=require(8) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash._basecreatecallback/node_modules/lodash._setbinddata/node_modules/lodash._isnative/index.js":8}],24:[function(require,module,exports){ +arguments[4][8][0].apply(exports,arguments) +},{"dup":8}],24:[function(require,module,exports){ /** * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/> * Build: `lodash modularize modern exports="npm" -o ./npm/` * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE> @@ -1088,12 +1088,12 @@ }; module.exports = keys; },{"lodash._isnative":26,"lodash._shimkeys":27,"lodash.isobject":29}],26:[function(require,module,exports){ -module.exports=require(8) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash._basecreatecallback/node_modules/lodash._setbinddata/node_modules/lodash._isnative/index.js":8}],27:[function(require,module,exports){ +arguments[4][8][0].apply(exports,arguments) +},{"dup":8}],27:[function(require,module,exports){ /** * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/> * Build: `lodash modularize modern exports="npm" -o ./npm/` * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE> @@ -1200,12 +1200,12 @@ } module.exports = isObject; },{"lodash._objecttypes":30}],30:[function(require,module,exports){ -module.exports=require(24) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash._objecttypes/index.js":24}],31:[function(require,module,exports){ +arguments[4][24][0].apply(exports,arguments) +},{"dup":24}],31:[function(require,module,exports){ /** * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/> * Build: `lodash modularize modern exports="npm" -o ./npm/` * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE> @@ -1641,12 +1641,12 @@ }; module.exports = defaults; },{"lodash._objecttypes":38,"lodash.keys":44}],38:[function(require,module,exports){ -module.exports=require(24) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash._objecttypes/index.js":24}],39:[function(require,module,exports){ +arguments[4][24][0].apply(exports,arguments) +},{"dup":24}],39:[function(require,module,exports){ /** * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/> * Build: `lodash modularize modern exports="npm" -o ./npm/` * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE> @@ -1745,20 +1745,20 @@ var reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); module.exports = reUnescapedHtml; },{"lodash._htmlescapes":43,"lodash.keys":44}],43:[function(require,module,exports){ -module.exports=require(41) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.template/node_modules/lodash.escape/node_modules/lodash._escapehtmlchar/node_modules/lodash._htmlescapes/index.js":41}],44:[function(require,module,exports){ -module.exports=require(25) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash.keys/index.js":25,"lodash._isnative":45,"lodash._shimkeys":46,"lodash.isobject":29}],45:[function(require,module,exports){ -module.exports=require(8) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash._basecreatecallback/node_modules/lodash._setbinddata/node_modules/lodash._isnative/index.js":8}],46:[function(require,module,exports){ -module.exports=require(27) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash.keys/node_modules/lodash._shimkeys/index.js":27,"lodash._objecttypes":47}],47:[function(require,module,exports){ -module.exports=require(24) -},{"/Users/andrewwalker/sites/sir-trevor-js/node_modules/lodash.isempty/node_modules/lodash.forown/node_modules/lodash._objecttypes/index.js":24}],48:[function(require,module,exports){ +arguments[4][41][0].apply(exports,arguments) +},{"dup":41}],44:[function(require,module,exports){ +arguments[4][25][0].apply(exports,arguments) +},{"dup":25,"lodash._isnative":45,"lodash._shimkeys":46,"lodash.isobject":29}],45:[function(require,module,exports){ +arguments[4][8][0].apply(exports,arguments) +},{"dup":8}],46:[function(require,module,exports){ +arguments[4][27][0].apply(exports,arguments) +},{"dup":27,"lodash._objecttypes":47}],47:[function(require,module,exports){ +arguments[4][24][0].apply(exports,arguments) +},{"dup":24}],48:[function(require,module,exports){ /** * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/> * Build: `lodash modularize modern exports="npm" -o ./npm/` * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE> @@ -1937,37 +1937,37 @@ module.exports = assignShim; },{"object-keys":52}],52:[function(require,module,exports){ -"use strict"; +'use strict'; // modified from https://github.com/es-shims/es5-shim var has = Object.prototype.hasOwnProperty; -var toString = Object.prototype.toString; +var toStr = Object.prototype.toString; var isArgs = require('./isArguments'); -var hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'); -var hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'); +var hasDontEnumBug = !({ 'toString': null }).propertyIsEnumerable('toString'); +var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype'); var dontEnums = [ - "toString", - "toLocaleString", - "valueOf", - "hasOwnProperty", - "isPrototypeOf", - "propertyIsEnumerable", - "constructor" + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' ]; var keysShim = function keys(object) { var isObject = object !== null && typeof object === 'object'; - var isFunction = toString.call(object) === '[object Function]'; + var isFunction = toStr.call(object) === '[object Function]'; var isArguments = isArgs(object); - var isString = isObject && toString.call(object) === '[object String]'; + var isString = isObject && toStr.call(object) === '[object String]'; var theKeys = []; if (!isObject && !isFunction && !isArguments) { - throw new TypeError("Object.keys called on a non-object"); + throw new TypeError('Object.keys called on a non-object'); } var skipProto = hasProtoEnumBug && isFunction; if (isString && object.length > 0 && !has.call(object, 0)) { for (var i = 0; i < object.length; ++i) { @@ -1989,13 +1989,13 @@ if (hasDontEnumBug) { var ctor = object.constructor; var skipConstructor = ctor && ctor.prototype === object; - for (var j = 0; j < dontEnums.length; ++j) { - if (!(skipConstructor && dontEnums[j] === 'constructor') && has.call(object, dontEnums[j])) { - theKeys.push(dontEnums[j]); + for (var k = 0; k < dontEnums.length; ++k) { + if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) { + theKeys.push(dontEnums[k]); } } } return theKeys; }; @@ -2007,3849 +2007,4894 @@ return Object.keys || keysShim; }; module.exports = keysShim; - },{"./isArguments":53}],53:[function(require,module,exports){ -"use strict"; +'use strict'; -var toString = Object.prototype.toString; +var toStr = Object.prototype.toString; module.exports = function isArguments(value) { - var str = toString.call(value); - var isArguments = str === '[object Arguments]'; - if (!isArguments) { - isArguments = str !== '[object Array]' + var str = toStr.call(value); + var isArgs = str === '[object Arguments]'; + if (!isArgs) { + isArgs = str !== '[object Array]' && value !== null && typeof value === 'object' && typeof value.length === 'number' && value.length >= 0 - && toString.call(value.callee) === '[object Function]'; + && toStr.call(value.callee) === '[object Function]'; } - return isArguments; + return isArgs; }; - },{}],54:[function(require,module,exports){ /** * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ -function universalModule() { - var $Object = Object; +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + global.Immutable = factory() +}(this, function () { 'use strict';var SLICE$0 = Array.prototype.slice; -function createClass(ctor, methods, staticMethods, superClass) { - var proto; - if (superClass) { - var superProto = superClass.prototype; - proto = $Object.create(superProto); - } else { - proto = ctor.prototype; + function createClass(ctor, superClass) { + if (superClass) { + ctor.prototype = Object.create(superClass.prototype); + } + ctor.prototype.constructor = ctor; } - $Object.keys(methods).forEach(function (key) { - proto[key] = methods[key]; - }); - $Object.keys(staticMethods).forEach(function (key) { - ctor[key] = staticMethods[key]; - }); - proto.constructor = ctor; - ctor.prototype = proto; - return ctor; -} -function superCall(self, proto, name, args) { - return $Object.getPrototypeOf(proto)[name].apply(self, args); -} + // Used for setting prototype methods that IE8 chokes on. + var DELETE = 'delete'; -function defaultSuperCall(self, proto, args) { - superCall(self, proto, 'constructor', args); -} + // Constants describing the size of trie nodes. + var SHIFT = 5; // Resulted in best performance after ______? + var SIZE = 1 << SHIFT; + var MASK = SIZE - 1; -var $traceurRuntime = {}; -$traceurRuntime.createClass = createClass; -$traceurRuntime.superCall = superCall; -$traceurRuntime.defaultSuperCall = defaultSuperCall; -"use strict"; -function is(first, second) { - if (first === second) { - return first !== 0 || second !== 0 || 1 / first === 1 / second; + // A consistent shared value representing "not set" which equals nothing other + // than itself, and nothing that could be provided externally. + var NOT_SET = {}; + + // Boolean references, Rough equivalent of `bool &`. + var CHANGE_LENGTH = { value: false }; + var DID_ALTER = { value: false }; + + function MakeRef(ref) { + ref.value = false; + return ref; } - if (first !== first) { - return second !== second; + + function SetRef(ref) { + ref && (ref.value = true); } - if (first && typeof first.equals === 'function') { - return first.equals(second); + + // A function which returns a value representing an "owner" for transient writes + // to tries. The return value will only ever equal itself, and will not equal + // the return of any subsequent call of this function. + function OwnerID() {} + + // http://jsperf.com/copy-array-inline + function arrCopy(arr, offset) { + offset = offset || 0; + var len = Math.max(0, arr.length - offset); + var newArr = new Array(len); + for (var ii = 0; ii < len; ii++) { + newArr[ii] = arr[ii + offset]; + } + return newArr; } - return false; -} -function invariant(condition, error) { - if (!condition) - throw new Error(error); -} -var DELETE = 'delete'; -var SHIFT = 5; -var SIZE = 1 << SHIFT; -var MASK = SIZE - 1; -var NOT_SET = {}; -var CHANGE_LENGTH = {value: false}; -var DID_ALTER = {value: false}; -function MakeRef(ref) { - ref.value = false; - return ref; -} -function SetRef(ref) { - ref && (ref.value = true); -} -function OwnerID() {} -function arrCopy(arr, offset) { - offset = offset || 0; - var len = Math.max(0, arr.length - offset); - var newArr = new Array(len); - for (var ii = 0; ii < len; ii++) { - newArr[ii] = arr[ii + offset]; + + function ensureSize(iter) { + if (iter.size === undefined) { + iter.size = iter.__iterate(returnTrue); + } + return iter.size; } - return newArr; -} -function assertNotInfinite(size) { - invariant(size !== Infinity, 'Cannot perform this action with an infinite size.'); -} -function ensureSize(iter) { - if (iter.size === undefined) { - iter.size = iter.__iterate(returnTrue); + + function wrapIndex(iter, index) { + return index >= 0 ? (+index) : ensureSize(iter) + (+index); } - return iter.size; -} -function wrapIndex(iter, index) { - return index >= 0 ? (+index) : ensureSize(iter) + (+index); -} -function returnTrue() { - return true; -} -function wholeSlice(begin, end, size) { - return (begin === 0 || (size !== undefined && begin <= -size)) && (end === undefined || (size !== undefined && end >= size)); -} -function resolveBegin(begin, size) { - return resolveIndex(begin, size, 0); -} -function resolveEnd(end, size) { - return resolveIndex(end, size, size); -} -function resolveIndex(index, size, defaultIndex) { - return index === undefined ? defaultIndex : index < 0 ? Math.max(0, size + index) : size === undefined ? index : Math.min(size, index); -} -function hash(o) { - if (!o) { - return 0; + + function returnTrue() { + return true; } - if (o === true) { - return 1; + + function wholeSlice(begin, end, size) { + return (begin === 0 || (size !== undefined && begin <= -size)) && + (end === undefined || (size !== undefined && end >= size)); } - var type = typeof o; - if (type === 'number') { - if ((o | 0) === o) { - return o & HASH_MAX_VAL; - } - o = '' + o; - type = 'string'; + + function resolveBegin(begin, size) { + return resolveIndex(begin, size, 0); } - if (type === 'string') { - return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o); + + function resolveEnd(end, size) { + return resolveIndex(end, size, size); } - if (o.hashCode) { - return hash(typeof o.hashCode === 'function' ? o.hashCode() : o.hashCode); + + function resolveIndex(index, size, defaultIndex) { + return index === undefined ? + defaultIndex : + index < 0 ? + Math.max(0, size + index) : + size === undefined ? + index : + Math.min(size, index); } - return hashJSObj(o); -} -function cachedHashString(string) { - var hash = stringHashCache[string]; - if (hash === undefined) { - hash = hashString(string); - if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) { - STRING_HASH_CACHE_SIZE = 0; - stringHashCache = {}; + + function Iterable(value) { + return isIterable(value) ? value : Seq(value); } - STRING_HASH_CACHE_SIZE++; - stringHashCache[string] = hash; + + + createClass(KeyedIterable, Iterable); + function KeyedIterable(value) { + return isKeyed(value) ? value : KeyedSeq(value); + } + + + createClass(IndexedIterable, Iterable); + function IndexedIterable(value) { + return isIndexed(value) ? value : IndexedSeq(value); + } + + + createClass(SetIterable, Iterable); + function SetIterable(value) { + return isIterable(value) && !isAssociative(value) ? value : SetSeq(value); + } + + + + function isIterable(maybeIterable) { + return !!(maybeIterable && maybeIterable[IS_ITERABLE_SENTINEL]); } - return hash; -} -function hashString(string) { - var hash = 0; - for (var ii = 0; ii < string.length; ii++) { - hash = (31 * hash + string.charCodeAt(ii)) & HASH_MAX_VAL; + + function isKeyed(maybeKeyed) { + return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL]); } - return hash; -} -function hashJSObj(obj) { - var hash = weakMap && weakMap.get(obj); - if (hash) - return hash; - hash = obj[UID_HASH_KEY]; - if (hash) - return hash; - if (!canDefineProperty) { - hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY]; - if (hash) - return hash; - hash = getIENodeHash(obj); - if (hash) - return hash; + + function isIndexed(maybeIndexed) { + return !!(maybeIndexed && maybeIndexed[IS_INDEXED_SENTINEL]); } - if (Object.isExtensible && !Object.isExtensible(obj)) { - throw new Error('Non-extensible objects are not allowed as keys.'); + + function isAssociative(maybeAssociative) { + return isKeyed(maybeAssociative) || isIndexed(maybeAssociative); } - hash = ++objHashUID & HASH_MAX_VAL; - if (weakMap) { - weakMap.set(obj, hash); - } else if (canDefineProperty) { - Object.defineProperty(obj, UID_HASH_KEY, { - 'enumerable': false, - 'configurable': false, - 'writable': false, - 'value': hash - }); - } else if (obj.propertyIsEnumerable && obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable) { - obj.propertyIsEnumerable = function() { - return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments); + + function isOrdered(maybeOrdered) { + return !!(maybeOrdered && maybeOrdered[IS_ORDERED_SENTINEL]); + } + + Iterable.isIterable = isIterable; + Iterable.isKeyed = isKeyed; + Iterable.isIndexed = isIndexed; + Iterable.isAssociative = isAssociative; + Iterable.isOrdered = isOrdered; + + Iterable.Keyed = KeyedIterable; + Iterable.Indexed = IndexedIterable; + Iterable.Set = SetIterable; + + + var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; + var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; + var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@'; + var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; + + /* global Symbol */ + + var ITERATE_KEYS = 0; + var ITERATE_VALUES = 1; + var ITERATE_ENTRIES = 2; + + var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = '@@iterator'; + + var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL; + + + function Iterator(next) { + this.next = next; + } + + Iterator.prototype.toString = function() { + return '[Iterator]'; }; - obj.propertyIsEnumerable[UID_HASH_KEY] = hash; - } else if (obj.nodeType) { - obj[UID_HASH_KEY] = hash; - } else { - throw new Error('Unable to set a non-enumerable property on object.'); + + + Iterator.KEYS = ITERATE_KEYS; + Iterator.VALUES = ITERATE_VALUES; + Iterator.ENTRIES = ITERATE_ENTRIES; + + Iterator.prototype.inspect = + Iterator.prototype.toSource = function () { return this.toString(); } + Iterator.prototype[ITERATOR_SYMBOL] = function () { + return this; + }; + + + function iteratorValue(type, k, v, iteratorResult) { + var value = type === 0 ? k : type === 1 ? v : [k, v]; + iteratorResult ? (iteratorResult.value = value) : (iteratorResult = { + value: value, done: false + }); + return iteratorResult; } - return hash; -} -var canDefineProperty = (function() { - try { - Object.defineProperty({}, 'x', {}); - return true; - } catch (e) { - return false; + + function iteratorDone() { + return { value: undefined, done: true }; } -}()); -function getIENodeHash(node) { - if (node && node.nodeType > 0) { - switch (node.nodeType) { - case 1: - return node.uniqueID; - case 9: - return node.documentElement && node.documentElement.uniqueID; + + function hasIterator(maybeIterable) { + return !!getIteratorFn(maybeIterable); + } + + function isIterator(maybeIterator) { + return maybeIterator && typeof maybeIterator.next === 'function'; + } + + function getIterator(iterable) { + var iteratorFn = getIteratorFn(iterable); + return iteratorFn && iteratorFn.call(iterable); + } + + function getIteratorFn(iterable) { + var iteratorFn = iterable && ( + (REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) || + iterable[FAUX_ITERATOR_SYMBOL] + ); + if (typeof iteratorFn === 'function') { + return iteratorFn; } } -} -var weakMap = typeof WeakMap === 'function' && new WeakMap(); -var HASH_MAX_VAL = 0x7FFFFFFF; -var objHashUID = 0; -var UID_HASH_KEY = '__immutablehash__'; -if (typeof Symbol === 'function') { - UID_HASH_KEY = Symbol(UID_HASH_KEY); -} -var STRING_HASH_CACHE_MIN_STRLEN = 16; -var STRING_HASH_CACHE_MAX_SIZE = 255; -var STRING_HASH_CACHE_SIZE = 0; -var stringHashCache = {}; -var ITERATE_KEYS = 0; -var ITERATE_VALUES = 1; -var ITERATE_ENTRIES = 2; -var FAUX_ITERATOR_SYMBOL = '@@iterator'; -var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; -var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL; -var Iterator = function Iterator(next) { - this.next = next; -}; -($traceurRuntime.createClass)(Iterator, {toString: function() { - return '[Iterator]'; - }}, {}); -Iterator.KEYS = ITERATE_KEYS; -Iterator.VALUES = ITERATE_VALUES; -Iterator.ENTRIES = ITERATE_ENTRIES; -var IteratorPrototype = Iterator.prototype; -IteratorPrototype.inspect = IteratorPrototype.toSource = function() { - return this.toString(); -}; -IteratorPrototype[ITERATOR_SYMBOL] = function() { - return this; -}; -function iteratorValue(type, k, v, iteratorResult) { - var value = type === 0 ? k : type === 1 ? v : [k, v]; - iteratorResult ? (iteratorResult.value = value) : (iteratorResult = { - value: value, - done: false - }); - return iteratorResult; -} -function iteratorDone() { - return { - value: undefined, - done: true - }; -} -function hasIterator(maybeIterable) { - return !!_iteratorFn(maybeIterable); -} -function isIterator(maybeIterator) { - return maybeIterator && typeof maybeIterator.next === 'function'; -} -function getIterator(iterable) { - var iteratorFn = _iteratorFn(iterable); - return iteratorFn && iteratorFn.call(iterable); -} -function _iteratorFn(iterable) { - var iteratorFn = iterable && ((REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) || iterable[FAUX_ITERATOR_SYMBOL]); - if (typeof iteratorFn === 'function') { - return iteratorFn; + + function isArrayLike(value) { + return value && typeof value.length === 'number'; } -} -var Iterable = function Iterable(value) { - return isIterable(value) ? value : Seq(value); -}; -var $Iterable = Iterable; -($traceurRuntime.createClass)(Iterable, { - toArray: function() { - assertNotInfinite(this.size); - var array = new Array(this.size || 0); - this.valueSeq().__iterate((function(v, i) { - array[i] = v; - })); - return array; - }, - toIndexedSeq: function() { - return new ToIndexedSequence(this); - }, - toJS: function() { - return this.toSeq().map((function(value) { - return value && typeof value.toJS === 'function' ? value.toJS() : value; - })).__toJS(); - }, - toKeyedSeq: function() { - return new ToKeyedSequence(this, true); - }, - toMap: function() { - assertNotInfinite(this.size); - return Map(this.toKeyedSeq()); - }, - toObject: function() { - assertNotInfinite(this.size); - var object = {}; - this.__iterate((function(v, k) { - object[k] = v; - })); - return object; - }, - toOrderedMap: function() { - assertNotInfinite(this.size); - return OrderedMap(this.toKeyedSeq()); - }, - toOrderedSet: function() { - assertNotInfinite(this.size); - return OrderedSet(isKeyed(this) ? this.valueSeq() : this); - }, - toSet: function() { - assertNotInfinite(this.size); - return Set(isKeyed(this) ? this.valueSeq() : this); - }, - toSetSeq: function() { - return new ToSetSequence(this); - }, - toSeq: function() { - return isIndexed(this) ? this.toIndexedSeq() : isKeyed(this) ? this.toKeyedSeq() : this.toSetSeq(); - }, - toStack: function() { - assertNotInfinite(this.size); - return Stack(isKeyed(this) ? this.valueSeq() : this); - }, - toList: function() { - assertNotInfinite(this.size); - return List(isKeyed(this) ? this.valueSeq() : this); - }, - toString: function() { - return '[Iterable]'; - }, - __toString: function(head, tail) { - if (this.size === 0) { - return head + tail; + + createClass(Seq, Iterable); + function Seq(value) { + return value === null || value === undefined ? emptySequence() : + isIterable(value) ? value.toSeq() : seqFromValue(value); } - return head + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + tail; - }, - concat: function() { - for (var values = [], - $__2 = 0; $__2 < arguments.length; $__2++) - values[$__2] = arguments[$__2]; - return reify(this, concatFactory(this, values)); - }, - contains: function(searchValue) { - return this.some((function(value) { - return is(value, searchValue); - })); - }, - entries: function() { - return this.__iterator(ITERATE_ENTRIES); - }, - every: function(predicate, context) { - var returnValue = true; - this.__iterate((function(v, k, c) { - if (!predicate.call(context, v, k, c)) { - returnValue = false; - return false; + + Seq.of = function(/*...values*/) { + return Seq(arguments); + }; + + Seq.prototype.toSeq = function() { + return this; + }; + + Seq.prototype.toString = function() { + return this.__toString('Seq {', '}'); + }; + + Seq.prototype.cacheResult = function() { + if (!this._cache && this.__iterateUncached) { + this._cache = this.entrySeq().toArray(); + this.size = this._cache.length; } - })); - return returnValue; - }, - filter: function(predicate, context) { - return reify(this, filterFactory(this, predicate, context, true)); - }, - find: function(predicate, context, notSetValue) { - var foundValue = notSetValue; - this.__iterate((function(v, k, c) { - if (predicate.call(context, v, k, c)) { - foundValue = v; - return false; - } - })); - return foundValue; - }, - forEach: function(sideEffect, context) { - return this.__iterate(context ? sideEffect.bind(context) : sideEffect); - }, - join: function(separator) { - separator = separator !== undefined ? '' + separator : ','; - var joined = ''; - var isFirst = true; - this.__iterate((function(v) { - isFirst ? (isFirst = false) : (joined += separator); - joined += v !== null && v !== undefined ? v : ''; - })); - return joined; - }, - keys: function() { - return this.__iterator(ITERATE_KEYS); - }, - map: function(mapper, context) { - return reify(this, mapFactory(this, mapper, context)); - }, - reduce: function(reducer, initialReduction, context) { - var reduction; - var useFirst; - if (arguments.length < 2) { - useFirst = true; - } else { - reduction = initialReduction; + return this; + }; + + // abstract __iterateUncached(fn, reverse) + + Seq.prototype.__iterate = function(fn, reverse) { + return seqIterate(this, fn, reverse, true); + }; + + // abstract __iteratorUncached(type, reverse) + + Seq.prototype.__iterator = function(type, reverse) { + return seqIterator(this, type, reverse, true); + }; + + + + createClass(KeyedSeq, Seq); + function KeyedSeq(value) { + return value === null || value === undefined ? + emptySequence().toKeyedSeq() : + isIterable(value) ? + (isKeyed(value) ? value.toSeq() : value.fromEntrySeq()) : + keyedSeqFromValue(value); } - this.__iterate((function(v, k, c) { - if (useFirst) { - useFirst = false; - reduction = v; - } else { - reduction = reducer.call(context, reduction, v, k, c); - } - })); - return reduction; - }, - reduceRight: function(reducer, initialReduction, context) { - var reversed = this.toKeyedSeq().reverse(); - return reversed.reduce.apply(reversed, arguments); - }, - reverse: function() { - return reify(this, reverseFactory(this, true)); - }, - slice: function(begin, end) { - if (wholeSlice(begin, end, this.size)) { + + KeyedSeq.of = function(/*...values*/) { + return KeyedSeq(arguments); + }; + + KeyedSeq.prototype.toKeyedSeq = function() { return this; + }; + + KeyedSeq.prototype.toSeq = function() { + return this; + }; + + + + createClass(IndexedSeq, Seq); + function IndexedSeq(value) { + return value === null || value === undefined ? emptySequence() : + !isIterable(value) ? indexedSeqFromValue(value) : + isKeyed(value) ? value.entrySeq() : value.toIndexedSeq(); } - var resolvedBegin = resolveBegin(begin, this.size); - var resolvedEnd = resolveEnd(end, this.size); - if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) { - return this.toSeq().cacheResult().slice(begin, end); + + IndexedSeq.of = function(/*...values*/) { + return IndexedSeq(arguments); + }; + + IndexedSeq.prototype.toIndexedSeq = function() { + return this; + }; + + IndexedSeq.prototype.toString = function() { + return this.__toString('Seq [', ']'); + }; + + IndexedSeq.prototype.__iterate = function(fn, reverse) { + return seqIterate(this, fn, reverse, false); + }; + + IndexedSeq.prototype.__iterator = function(type, reverse) { + return seqIterator(this, type, reverse, false); + }; + + + + createClass(SetSeq, Seq); + function SetSeq(value) { + return ( + value === null || value === undefined ? emptySequence() : + !isIterable(value) ? indexedSeqFromValue(value) : + isKeyed(value) ? value.entrySeq() : value + ).toSetSeq(); } - var skipped = resolvedBegin === 0 ? this : this.skip(resolvedBegin); - return reify(this, resolvedEnd === undefined || resolvedEnd === this.size ? skipped : skipped.take(resolvedEnd - resolvedBegin)); - }, - some: function(predicate, context) { - return !this.every(not(predicate), context); - }, - sort: function(comparator) { - return reify(this, sortFactory(this, comparator)); - }, - values: function() { - return this.__iterator(ITERATE_VALUES); - }, - butLast: function() { - return this.slice(0, -1); - }, - count: function(predicate, context) { - return ensureSize(predicate ? this.toSeq().filter(predicate, context) : this); - }, - countBy: function(grouper, context) { - return countByFactory(this, grouper, context); - }, - equals: function(other) { - if (this === other) { - return true; + + SetSeq.of = function(/*...values*/) { + return SetSeq(arguments); + }; + + SetSeq.prototype.toSetSeq = function() { + return this; + }; + + + + Seq.isSeq = isSeq; + Seq.Keyed = KeyedSeq; + Seq.Set = SetSeq; + Seq.Indexed = IndexedSeq; + + var IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@'; + + Seq.prototype[IS_SEQ_SENTINEL] = true; + + + + // #pragma Root Sequences + + createClass(ArraySeq, IndexedSeq); + function ArraySeq(array) { + this._array = array; + this.size = array.length; } - if (!other || typeof other.equals !== 'function') { - return false; + + ArraySeq.prototype.get = function(index, notSetValue) { + return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue; + }; + + ArraySeq.prototype.__iterate = function(fn, reverse) { + var array = this._array; + var maxIndex = array.length - 1; + for (var ii = 0; ii <= maxIndex; ii++) { + if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) { + return ii + 1; + } + } + return ii; + }; + + ArraySeq.prototype.__iterator = function(type, reverse) { + var array = this._array; + var maxIndex = array.length - 1; + var ii = 0; + return new Iterator(function() + {return ii > maxIndex ? + iteratorDone() : + iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++])} + ); + }; + + + + createClass(ObjectSeq, KeyedSeq); + function ObjectSeq(object) { + var keys = Object.keys(object); + this._object = object; + this._keys = keys; + this.size = keys.length; } - if (this.size !== undefined && other.size !== undefined) { - if (this.size !== other.size) { - return false; + + ObjectSeq.prototype.get = function(key, notSetValue) { + if (notSetValue !== undefined && !this.has(key)) { + return notSetValue; } - if (this.size === 0 && other.size === 0) { - return true; + return this._object[key]; + }; + + ObjectSeq.prototype.has = function(key) { + return this._object.hasOwnProperty(key); + }; + + ObjectSeq.prototype.__iterate = function(fn, reverse) { + var object = this._object; + var keys = this._keys; + var maxIndex = keys.length - 1; + for (var ii = 0; ii <= maxIndex; ii++) { + var key = keys[reverse ? maxIndex - ii : ii]; + if (fn(object[key], key, this) === false) { + return ii + 1; + } } + return ii; + }; + + ObjectSeq.prototype.__iterator = function(type, reverse) { + var object = this._object; + var keys = this._keys; + var maxIndex = keys.length - 1; + var ii = 0; + return new Iterator(function() { + var key = keys[reverse ? maxIndex - ii : ii]; + return ii++ > maxIndex ? + iteratorDone() : + iteratorValue(type, key, object[key]); + }); + }; + + ObjectSeq.prototype[IS_ORDERED_SENTINEL] = true; + + + createClass(IterableSeq, IndexedSeq); + function IterableSeq(iterable) { + this._iterable = iterable; + this.size = iterable.length || iterable.size; } - if (this.__hash !== undefined && other.__hash !== undefined && this.__hash !== other.__hash) { - return false; - } - return this.__deepEquals(other); - }, - __deepEquals: function(other) { - return deepEqual(this, other); - }, - entrySeq: function() { - var iterable = this; - if (iterable._cache) { - return new ArraySeq(iterable._cache); - } - var entriesSequence = iterable.toSeq().map(entryMapper).toIndexedSeq(); - entriesSequence.fromEntrySeq = (function() { - return iterable.toSeq(); - }); - return entriesSequence; - }, - filterNot: function(predicate, context) { - return this.filter(not(predicate), context); - }, - findLast: function(predicate, context, notSetValue) { - return this.toKeyedSeq().reverse().find(predicate, context, notSetValue); - }, - first: function() { - return this.find(returnTrue); - }, - flatMap: function(mapper, context) { - return reify(this, flatMapFactory(this, mapper, context)); - }, - flatten: function(depth) { - return reify(this, flattenFactory(this, depth, true)); - }, - fromEntrySeq: function() { - return new FromEntriesSequence(this); - }, - get: function(searchKey, notSetValue) { - return this.find((function(_, key) { - return is(key, searchKey); - }), undefined, notSetValue); - }, - getIn: function(searchKeyPath, notSetValue) { - var nested = this; - if (searchKeyPath) { - for (var ii = 0; ii < searchKeyPath.length; ii++) { - nested = nested && nested.get ? nested.get(searchKeyPath[ii], NOT_SET) : NOT_SET; - if (nested === NOT_SET) { - return notSetValue; + + IterableSeq.prototype.__iterateUncached = function(fn, reverse) { + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var iterable = this._iterable; + var iterator = getIterator(iterable); + var iterations = 0; + if (isIterator(iterator)) { + var step; + while (!(step = iterator.next()).done) { + if (fn(step.value, iterations++, this) === false) { + break; + } } } + return iterations; + }; + + IterableSeq.prototype.__iteratorUncached = function(type, reverse) { + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + var iterable = this._iterable; + var iterator = getIterator(iterable); + if (!isIterator(iterator)) { + return new Iterator(iteratorDone); + } + var iterations = 0; + return new Iterator(function() { + var step = iterator.next(); + return step.done ? step : iteratorValue(type, iterations++, step.value); + }); + }; + + + + createClass(IteratorSeq, IndexedSeq); + function IteratorSeq(iterator) { + this._iterator = iterator; + this._iteratorCache = []; } - return nested; - }, - groupBy: function(grouper, context) { - return groupByFactory(this, grouper, context); - }, - has: function(searchKey) { - return this.get(searchKey, NOT_SET) !== NOT_SET; - }, - isSubset: function(iter) { - iter = typeof iter.contains === 'function' ? iter : $Iterable(iter); - return this.every((function(value) { - return iter.contains(value); - })); - }, - isSuperset: function(iter) { - return iter.isSubset(this); - }, - keySeq: function() { - return this.toSeq().map(keyMapper).toIndexedSeq(); - }, - last: function() { - return this.toSeq().reverse().first(); - }, - max: function(comparator) { - return maxFactory(this, comparator); - }, - maxBy: function(mapper, comparator) { - return maxFactory(this, comparator, mapper); - }, - min: function(comparator) { - return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator); - }, - minBy: function(mapper, comparator) { - return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator, mapper); - }, - rest: function() { - return this.slice(1); - }, - skip: function(amount) { - return reify(this, skipFactory(this, amount, true)); - }, - skipLast: function(amount) { - return reify(this, this.toSeq().reverse().skip(amount).reverse()); - }, - skipWhile: function(predicate, context) { - return reify(this, skipWhileFactory(this, predicate, context, true)); - }, - skipUntil: function(predicate, context) { - return this.skipWhile(not(predicate), context); - }, - sortBy: function(mapper, comparator) { - return reify(this, sortFactory(this, comparator, mapper)); - }, - take: function(amount) { - return reify(this, takeFactory(this, amount)); - }, - takeLast: function(amount) { - return reify(this, this.toSeq().reverse().take(amount).reverse()); - }, - takeWhile: function(predicate, context) { - return reify(this, takeWhileFactory(this, predicate, context)); - }, - takeUntil: function(predicate, context) { - return this.takeWhile(not(predicate), context); - }, - valueSeq: function() { - return this.toIndexedSeq(); - }, - hashCode: function() { - return this.__hash || (this.__hash = this.size === Infinity ? 0 : this.reduce((function(h, v, k) { - return (h + (hash(v) ^ (v === k ? 0 : hash(k)))) & HASH_MAX_VAL; - }), 0)); - } -}, {}); -var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; -var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; -var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@'; -var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; -var IterablePrototype = Iterable.prototype; -IterablePrototype[IS_ITERABLE_SENTINEL] = true; -IterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.values; -IterablePrototype.toJSON = IterablePrototype.toJS; -IterablePrototype.__toJS = IterablePrototype.toArray; -IterablePrototype.__toStringMapper = quoteString; -IterablePrototype.inspect = IterablePrototype.toSource = function() { - return this.toString(); -}; -IterablePrototype.chain = IterablePrototype.flatMap; -(function() { - try { - Object.defineProperty(IterablePrototype, 'length', {get: function() { - if (!Iterable.noLengthWarning) { - var stack; - try { - throw new Error(); - } catch (error) { - stack = error.stack; - } - if (stack.indexOf('_wrapObject') === -1) { - console && console.warn && console.warn('iterable.length has been deprecated, ' + 'use iterable.size or iterable.count(). ' + 'This warning will become a silent error in a future version. ' + stack); - return this.size; - } + + IteratorSeq.prototype.__iterateUncached = function(fn, reverse) { + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var iterator = this._iterator; + var cache = this._iteratorCache; + var iterations = 0; + while (iterations < cache.length) { + if (fn(cache[iterations], iterations++, this) === false) { + return iterations; } - }}); - } catch (e) {} -})(); -var KeyedIterable = function KeyedIterable(value) { - return isKeyed(value) ? value : KeyedSeq(value); -}; -($traceurRuntime.createClass)(KeyedIterable, { - flip: function() { - return reify(this, flipFactory(this)); - }, - findKey: function(predicate, context) { - var foundKey; - this.__iterate((function(v, k, c) { - if (predicate.call(context, v, k, c)) { - foundKey = k; - return false; } - })); - return foundKey; - }, - findLastKey: function(predicate, context) { - return this.toSeq().reverse().findKey(predicate, context); - }, - keyOf: function(searchValue) { - return this.findKey((function(value) { - return is(value, searchValue); - })); - }, - lastKeyOf: function(searchValue) { - return this.toSeq().reverse().keyOf(searchValue); - }, - mapEntries: function(mapper, context) { - var $__0 = this; - var iterations = 0; - return reify(this, this.toSeq().map((function(v, k) { - return mapper.call(context, [k, v], iterations++, $__0); - })).fromEntrySeq()); - }, - mapKeys: function(mapper, context) { - var $__0 = this; - return reify(this, this.toSeq().flip().map((function(k, v) { - return mapper.call(context, k, v, $__0); - })).flip()); + var step; + while (!(step = iterator.next()).done) { + var val = step.value; + cache[iterations] = val; + if (fn(val, iterations++, this) === false) { + break; + } + } + return iterations; + }; + + IteratorSeq.prototype.__iteratorUncached = function(type, reverse) { + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + var iterator = this._iterator; + var cache = this._iteratorCache; + var iterations = 0; + return new Iterator(function() { + if (iterations >= cache.length) { + var step = iterator.next(); + if (step.done) { + return step; + } + cache[iterations] = step.value; + } + return iteratorValue(type, iterations, cache[iterations++]); + }); + }; + + + + + // # pragma Helper functions + + function isSeq(maybeSeq) { + return !!(maybeSeq && maybeSeq[IS_SEQ_SENTINEL]); } -}, {}, Iterable); -var KeyedIterablePrototype = KeyedIterable.prototype; -KeyedIterablePrototype[IS_KEYED_SENTINEL] = true; -KeyedIterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.entries; -KeyedIterablePrototype.__toJS = IterablePrototype.toObject; -KeyedIterablePrototype.__toStringMapper = (function(v, k) { - return k + ': ' + quoteString(v); -}); -var IndexedIterable = function IndexedIterable(value) { - return isIndexed(value) ? value : IndexedSeq(value); -}; -($traceurRuntime.createClass)(IndexedIterable, { - toKeyedSeq: function() { - return new ToKeyedSequence(this, false); - }, - filter: function(predicate, context) { - return reify(this, filterFactory(this, predicate, context, false)); - }, - findIndex: function(predicate, context) { - var key = this.toKeyedSeq().findKey(predicate, context); - return key === undefined ? -1 : key; - }, - indexOf: function(searchValue) { - var key = this.toKeyedSeq().keyOf(searchValue); - return key === undefined ? -1 : key; - }, - lastIndexOf: function(searchValue) { - var key = this.toKeyedSeq().lastKeyOf(searchValue); - return key === undefined ? -1 : key; - }, - reverse: function() { - return reify(this, reverseFactory(this, false)); - }, - splice: function(index, removeNum) { - var numArgs = arguments.length; - removeNum = Math.max(removeNum | 0, 0); - if (numArgs === 0 || (numArgs === 2 && !removeNum)) { - return this; - } - index = resolveBegin(index, this.size); - var spliced = this.slice(0, index); - return reify(this, numArgs === 1 ? spliced : spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum))); - }, - findLastIndex: function(predicate, context) { - var key = this.toKeyedSeq().findLastKey(predicate, context); - return key === undefined ? -1 : key; - }, - first: function() { - return this.get(0); - }, - flatten: function(depth) { - return reify(this, flattenFactory(this, depth, false)); - }, - get: function(index, notSetValue) { - index = wrapIndex(this, index); - return (index < 0 || (this.size === Infinity || (this.size !== undefined && index > this.size))) ? notSetValue : this.find((function(_, key) { - return key === index; - }), undefined, notSetValue); - }, - has: function(index) { - index = wrapIndex(this, index); - return index >= 0 && (this.size !== undefined ? this.size === Infinity || index < this.size : this.indexOf(index) !== -1); - }, - interpose: function(separator) { - return reify(this, interposeFactory(this, separator)); - }, - last: function() { - return this.get(-1); - }, - skip: function(amount) { - var iter = this; - var skipSeq = skipFactory(iter, amount, false); - if (isSeq(iter) && skipSeq !== iter) { - skipSeq.get = function(index, notSetValue) { - index = wrapIndex(this, index); - return index >= 0 ? iter.get(index + amount, notSetValue) : notSetValue; - }; - } - return reify(this, skipSeq); - }, - skipWhile: function(predicate, context) { - return reify(this, skipWhileFactory(this, predicate, context, false)); - }, - take: function(amount) { - var iter = this; - var takeSeq = takeFactory(iter, amount); - if (isSeq(iter) && takeSeq !== iter) { - takeSeq.get = function(index, notSetValue) { - index = wrapIndex(this, index); - return index >= 0 && index < amount ? iter.get(index, notSetValue) : notSetValue; - }; - } - return reify(this, takeSeq); + + var EMPTY_SEQ; + + function emptySequence() { + return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([])); } -}, {}, Iterable); -IndexedIterable.prototype[IS_INDEXED_SENTINEL] = true; -IndexedIterable.prototype[IS_ORDERED_SENTINEL] = true; -var SetIterable = function SetIterable(value) { - return isIterable(value) && !isAssociative(value) ? value : SetSeq(value); -}; -($traceurRuntime.createClass)(SetIterable, { - get: function(value, notSetValue) { - return this.has(value) ? value : notSetValue; - }, - contains: function(value) { - return this.has(value); - }, - keySeq: function() { - return this.valueSeq(); - } -}, {}, Iterable); -SetIterable.prototype.has = IterablePrototype.contains; -function isIterable(maybeIterable) { - return !!(maybeIterable && maybeIterable[IS_ITERABLE_SENTINEL]); -} -function isKeyed(maybeKeyed) { - return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL]); -} -function isIndexed(maybeIndexed) { - return !!(maybeIndexed && maybeIndexed[IS_INDEXED_SENTINEL]); -} -function isAssociative(maybeAssociative) { - return isKeyed(maybeAssociative) || isIndexed(maybeAssociative); -} -function isOrdered(maybeOrdered) { - return !!(maybeOrdered && maybeOrdered[IS_ORDERED_SENTINEL]); -} -Iterable.isIterable = isIterable; -Iterable.isKeyed = isKeyed; -Iterable.isIndexed = isIndexed; -Iterable.isAssociative = isAssociative; -Iterable.isOrdered = isOrdered; -Iterable.Keyed = KeyedIterable; -Iterable.Indexed = IndexedIterable; -Iterable.Set = SetIterable; -Iterable.Iterator = Iterator; -function keyMapper(v, k) { - return k; -} -function entryMapper(v, k) { - return [k, v]; -} -function not(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; -} -function neg(predicate) { - return function() { - return -predicate.apply(this, arguments); - }; -} -function quoteString(value) { - return typeof value === 'string' ? JSON.stringify(value) : value; -} -function defaultNegComparator(a, b) { - return a > b ? -1 : a < b ? 1 : 0; -} -function deepEqual(a, b) { - var bothNotAssociative = !isAssociative(a) && !isAssociative(b); - if (isOrdered(a)) { - if (!isOrdered(b)) { - return false; + + function keyedSeqFromValue(value) { + var seq = + Array.isArray(value) ? new ArraySeq(value).fromEntrySeq() : + isIterator(value) ? new IteratorSeq(value).fromEntrySeq() : + hasIterator(value) ? new IterableSeq(value).fromEntrySeq() : + typeof value === 'object' ? new ObjectSeq(value) : + undefined; + if (!seq) { + throw new TypeError( + 'Expected Array or iterable object of [k, v] entries, '+ + 'or keyed object: ' + value + ); } - var entries = a.entries(); - return b.every((function(v, k) { - var entry = entries.next().value; - return entry && is(entry[1], v) && (bothNotAssociative || is(entry[0], k)); - })) && entries.next().done; + return seq; } - var flipped = false; - if (a.size === undefined) { - if (b.size === undefined) { - a.cacheResult(); - } else { - flipped = true; - var _ = a; - a = b; - b = _; + + function indexedSeqFromValue(value) { + var seq = maybeIndexedSeqFromValue(value); + if (!seq) { + throw new TypeError( + 'Expected Array or iterable object of values: ' + value + ); } + return seq; } - var allEqual = true; - var bSize = b.__iterate((function(v, k) { - if (bothNotAssociative ? !a.has(v) : flipped ? !is(v, a.get(k, NOT_SET)) : !is(a.get(k, NOT_SET), v)) { - allEqual = false; - return false; + + function seqFromValue(value) { + var seq = maybeIndexedSeqFromValue(value) || + (typeof value === 'object' && new ObjectSeq(value)); + if (!seq) { + throw new TypeError( + 'Expected Array or iterable object of values, or keyed object: ' + value + ); } - })); - return allEqual && a.size === bSize; -} -function mixin(ctor, methods) { - var proto = ctor.prototype; - var keyCopier = (function(key) { - proto[key] = methods[key]; - }); - Object.keys(methods).forEach(keyCopier); - Object.getOwnPropertySymbols && Object.getOwnPropertySymbols(methods).forEach(keyCopier); - return ctor; -} -var Seq = function Seq(value) { - return value === null || value === undefined ? emptySequence() : isIterable(value) ? value.toSeq() : seqFromValue(value); -}; -var $Seq = Seq; -($traceurRuntime.createClass)(Seq, { - toSeq: function() { - return this; - }, - toString: function() { - return this.__toString('Seq {', '}'); - }, - cacheResult: function() { - if (!this._cache && this.__iterateUncached) { - this._cache = this.entrySeq().toArray(); - this.size = this._cache.length; - } - return this; - }, - __iterate: function(fn, reverse) { - return seqIterate(this, fn, reverse, true); - }, - __iterator: function(type, reverse) { - return seqIterator(this, type, reverse, true); + return seq; } -}, {of: function() { - return $Seq(arguments); - }}, Iterable); -var KeyedSeq = function KeyedSeq(value) { - return value === null || value === undefined ? emptySequence().toKeyedSeq() : isIterable(value) ? (isKeyed(value) ? value.toSeq() : value.fromEntrySeq()) : keyedSeqFromValue(value); -}; -var $KeyedSeq = KeyedSeq; -($traceurRuntime.createClass)(KeyedSeq, { - toKeyedSeq: function() { - return this; - }, - toSeq: function() { - return this; + + function maybeIndexedSeqFromValue(value) { + return ( + isArrayLike(value) ? new ArraySeq(value) : + isIterator(value) ? new IteratorSeq(value) : + hasIterator(value) ? new IterableSeq(value) : + undefined + ); } -}, {of: function() { - return $KeyedSeq(arguments); - }}, Seq); -mixin(KeyedSeq, KeyedIterable.prototype); -var IndexedSeq = function IndexedSeq(value) { - return value === null || value === undefined ? emptySequence() : !isIterable(value) ? indexedSeqFromValue(value) : isKeyed(value) ? value.entrySeq() : value.toIndexedSeq(); -}; -var $IndexedSeq = IndexedSeq; -($traceurRuntime.createClass)(IndexedSeq, { - toIndexedSeq: function() { - return this; - }, - toString: function() { - return this.__toString('Seq [', ']'); - }, - __iterate: function(fn, reverse) { - return seqIterate(this, fn, reverse, false); - }, - __iterator: function(type, reverse) { - return seqIterator(this, type, reverse, false); - } -}, {of: function() { - return $IndexedSeq(arguments); - }}, Seq); -mixin(IndexedSeq, IndexedIterable.prototype); -var SetSeq = function SetSeq(value) { - return (value === null || value === undefined ? emptySequence() : !isIterable(value) ? indexedSeqFromValue(value) : isKeyed(value) ? value.entrySeq() : value).toSetSeq(); -}; -var $SetSeq = SetSeq; -($traceurRuntime.createClass)(SetSeq, {toSetSeq: function() { - return this; - }}, {of: function() { - return $SetSeq(arguments); - }}, Seq); -mixin(SetSeq, SetIterable.prototype); -Seq.isSeq = isSeq; -Seq.Keyed = KeyedSeq; -Seq.Set = SetSeq; -Seq.Indexed = IndexedSeq; -var IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@'; -Seq.prototype[IS_SEQ_SENTINEL] = true; -var ArraySeq = function ArraySeq(array) { - this._array = array; - this.size = array.length; -}; -($traceurRuntime.createClass)(ArraySeq, { - get: function(index, notSetValue) { - return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue; - }, - __iterate: function(fn, reverse) { - var array = this._array; - var maxIndex = array.length - 1; - for (var ii = 0; ii <= maxIndex; ii++) { - if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) { - return ii + 1; + + function seqIterate(seq, fn, reverse, useKeys) { + var cache = seq._cache; + if (cache) { + var maxIndex = cache.length - 1; + for (var ii = 0; ii <= maxIndex; ii++) { + var entry = cache[reverse ? maxIndex - ii : ii]; + if (fn(entry[1], useKeys ? entry[0] : ii, seq) === false) { + return ii + 1; + } } + return ii; } - return ii; - }, - __iterator: function(type, reverse) { - var array = this._array; - var maxIndex = array.length - 1; - var ii = 0; - return new Iterator((function() { - return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++]); - })); + return seq.__iterateUncached(fn, reverse); } -}, {}, IndexedSeq); -var ObjectSeq = function ObjectSeq(object) { - var keys = Object.keys(object); - this._object = object; - this._keys = keys; - this.size = keys.length; -}; -($traceurRuntime.createClass)(ObjectSeq, { - get: function(key, notSetValue) { - if (notSetValue !== undefined && !this.has(key)) { - return notSetValue; + + function seqIterator(seq, type, reverse, useKeys) { + var cache = seq._cache; + if (cache) { + var maxIndex = cache.length - 1; + var ii = 0; + return new Iterator(function() { + var entry = cache[reverse ? maxIndex - ii : ii]; + return ii++ > maxIndex ? + iteratorDone() : + iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]); + }); } - return this._object[key]; - }, - has: function(key) { - return this._object.hasOwnProperty(key); - }, - __iterate: function(fn, reverse) { - var object = this._object; - var keys = this._keys; - var maxIndex = keys.length - 1; - for (var ii = 0; ii <= maxIndex; ii++) { - var key = keys[reverse ? maxIndex - ii : ii]; - if (fn(object[key], key, this) === false) { - return ii + 1; - } - } - return ii; - }, - __iterator: function(type, reverse) { - var object = this._object; - var keys = this._keys; - var maxIndex = keys.length - 1; - var ii = 0; - return new Iterator((function() { - var key = keys[reverse ? maxIndex - ii : ii]; - return ii++ > maxIndex ? iteratorDone() : iteratorValue(type, key, object[key]); - })); + return seq.__iteratorUncached(type, reverse); } -}, {}, KeyedSeq); -ObjectSeq.prototype[IS_ORDERED_SENTINEL] = true; -var IterableSeq = function IterableSeq(iterable) { - this._iterable = iterable; - this.size = iterable.length || iterable.size; -}; -($traceurRuntime.createClass)(IterableSeq, { - __iterateUncached: function(fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); + + createClass(Collection, Iterable); + function Collection() { + throw TypeError('Abstract'); } - var iterable = this._iterable; - var iterator = getIterator(iterable); - var iterations = 0; - if (isIterator(iterator)) { - var step; - while (!(step = iterator.next()).done) { - if (fn(step.value, iterations++, this) === false) { - break; - } - } + + + createClass(KeyedCollection, Collection);function KeyedCollection() {} + + createClass(IndexedCollection, Collection);function IndexedCollection() {} + + createClass(SetCollection, Collection);function SetCollection() {} + + + Collection.Keyed = KeyedCollection; + Collection.Indexed = IndexedCollection; + Collection.Set = SetCollection; + + /** + * An extension of the "same-value" algorithm as [described for use by ES6 Map + * and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality) + * + * NaN is considered the same as NaN, however -0 and 0 are considered the same + * value, which is different from the algorithm described by + * [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). + * + * This is extended further to allow Objects to describe the values they + * represent, by way of `valueOf` or `equals` (and `hashCode`). + * + * Note: because of this extension, the key equality of Immutable.Map and the + * value equality of Immutable.Set will differ from ES6 Map and Set. + * + * ### Defining custom values + * + * The easiest way to describe the value an object represents is by implementing + * `valueOf`. For example, `Date` represents a value by returning a unix + * timestamp for `valueOf`: + * + * var date1 = new Date(1234567890000); // Fri Feb 13 2009 ... + * var date2 = new Date(1234567890000); + * date1.valueOf(); // 1234567890000 + * assert( date1 !== date2 ); + * assert( Immutable.is( date1, date2 ) ); + * + * Note: overriding `valueOf` may have other implications if you use this object + * where JavaScript expects a primitive, such as implicit string coercion. + * + * For more complex types, especially collections, implementing `valueOf` may + * not be performant. An alternative is to implement `equals` and `hashCode`. + * + * `equals` takes another object, presumably of similar type, and returns true + * if the it is equal. Equality is symmetrical, so the same result should be + * returned if this and the argument are flipped. + * + * assert( a.equals(b) === b.equals(a) ); + * + * `hashCode` returns a 32bit integer number representing the object which will + * be used to determine how to store the value object in a Map or Set. You must + * provide both or neither methods, one must not exist without the other. + * + * Also, an important relationship between these methods must be upheld: if two + * values are equal, they *must* return the same hashCode. If the values are not + * equal, they might have the same hashCode; this is called a hash collision, + * and while undesirable for performance reasons, it is acceptable. + * + * if (a.equals(b)) { + * assert( a.hashCode() === b.hashCode() ); + * } + * + * All Immutable collections implement `equals` and `hashCode`. + * + */ + function is(valueA, valueB) { + if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { + return true; } - return iterations; - }, - __iteratorUncached: function(type, reverse) { - if (reverse) { - return this.cacheResult().__iterator(type, reverse); + if (!valueA || !valueB) { + return false; } - var iterable = this._iterable; - var iterator = getIterator(iterable); - if (!isIterator(iterator)) { - return new Iterator(iteratorDone); + if (typeof valueA.valueOf === 'function' && + typeof valueB.valueOf === 'function') { + valueA = valueA.valueOf(); + valueB = valueB.valueOf(); } - var iterations = 0; - return new Iterator((function() { - var step = iterator.next(); - return step.done ? step : iteratorValue(type, iterations++, step.value); - })); + return typeof valueA.equals === 'function' && + typeof valueB.equals === 'function' ? + valueA.equals(valueB) : + valueA === valueB || (valueA !== valueA && valueB !== valueB); } -}, {}, IndexedSeq); -var IteratorSeq = function IteratorSeq(iterator) { - this._iterator = iterator; - this._iteratorCache = []; -}; -($traceurRuntime.createClass)(IteratorSeq, { - __iterateUncached: function(fn, reverse) { - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); + + function fromJS(json, converter) { + return converter ? + fromJSWith(converter, json, '', {'': json}) : + fromJSDefault(json); + } + + function fromJSWith(converter, json, key, parentJSON) { + if (Array.isArray(json)) { + return converter.call(parentJSON, key, IndexedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)})); } - var iterator = this._iterator; - var cache = this._iteratorCache; - var iterations = 0; - while (iterations < cache.length) { - if (fn(cache[iterations], iterations++, this) === false) { - return iterations; - } + if (isPlainObj(json)) { + return converter.call(parentJSON, key, KeyedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)})); } - var step; - while (!(step = iterator.next()).done) { - var val = step.value; - cache[iterations] = val; - if (fn(val, iterations++, this) === false) { - break; - } + return json; + } + + function fromJSDefault(json) { + if (Array.isArray(json)) { + return IndexedSeq(json).map(fromJSDefault).toList(); } - return iterations; - }, - __iteratorUncached: function(type, reverse) { - if (reverse) { - return this.cacheResult().__iterator(type, reverse); + if (isPlainObj(json)) { + return KeyedSeq(json).map(fromJSDefault).toMap(); } - var iterator = this._iterator; - var cache = this._iteratorCache; - var iterations = 0; - return new Iterator((function() { - if (iterations >= cache.length) { - var step = iterator.next(); - if (step.done) { - return step; - } - cache[iterations] = step.value; - } - return iteratorValue(type, iterations, cache[iterations++]); - })); + return json; } -}, {}, IndexedSeq); -function isSeq(maybeSeq) { - return !!(maybeSeq && maybeSeq[IS_SEQ_SENTINEL]); -} -var EMPTY_SEQ; -function emptySequence() { - return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([])); -} -function keyedSeqFromValue(value) { - var seq = Array.isArray(value) ? new ArraySeq(value).fromEntrySeq() : isIterator(value) ? new IteratorSeq(value).fromEntrySeq() : hasIterator(value) ? new IterableSeq(value).fromEntrySeq() : typeof value === 'object' ? new ObjectSeq(value) : undefined; - if (!seq) { - throw new TypeError('Expected Array or iterable object of [k, v] entries, ' + 'or keyed object: ' + value); + + function isPlainObj(value) { + return value && value.constructor === Object; } - return seq; -} -function indexedSeqFromValue(value) { - var seq = maybeIndexedSeqFromValue(value); - if (!seq) { - throw new TypeError('Expected Array or iterable object of values: ' + value); + + var Math__imul = + typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 ? + Math.imul : + function Math__imul(a, b) { + a = a | 0; // int + b = b | 0; // int + var c = a & 0xffff; + var d = b & 0xffff; + // Shift by 0 fixes the sign on the high part. + return (c * d) + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0) | 0; // int + }; + + // v8 has an optimization for storing 31-bit signed numbers. + // Values which have either 00 or 11 as the high order bits qualify. + // This function drops the highest order bit in a signed number, maintaining + // the sign bit. + function smi(i32) { + return ((i32 >>> 1) & 0x40000000) | (i32 & 0xBFFFFFFF); } - return seq; -} -function seqFromValue(value) { - var seq = maybeIndexedSeqFromValue(value) || (typeof value === 'object' && new ObjectSeq(value)); - if (!seq) { - throw new TypeError('Expected Array or iterable object of values, or keyed object: ' + value); - } - return seq; -} -function maybeIndexedSeqFromValue(value) { - return (isArrayLike(value) ? new ArraySeq(value) : isIterator(value) ? new IteratorSeq(value) : hasIterator(value) ? new IterableSeq(value) : undefined); -} -function isArrayLike(value) { - return value && typeof value.length === 'number'; -} -function seqIterate(seq, fn, reverse, useKeys) { - assertNotInfinite(seq.size); - var cache = seq._cache; - if (cache) { - var maxIndex = cache.length - 1; - for (var ii = 0; ii <= maxIndex; ii++) { - var entry = cache[reverse ? maxIndex - ii : ii]; - if (fn(entry[1], useKeys ? entry[0] : ii, seq) === false) { - return ii + 1; + + function hash(o) { + if (o === false || o === null || o === undefined) { + return 0; + } + if (typeof o.valueOf === 'function') { + o = o.valueOf(); + if (o === false || o === null || o === undefined) { + return 0; } } - return ii; - } - return seq.__iterateUncached(fn, reverse); -} -function seqIterator(seq, type, reverse, useKeys) { - var cache = seq._cache; - if (cache) { - var maxIndex = cache.length - 1; - var ii = 0; - return new Iterator((function() { - var entry = cache[reverse ? maxIndex - ii : ii]; - return ii++ > maxIndex ? iteratorDone() : iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]); - })); - } - return seq.__iteratorUncached(type, reverse); -} -function fromJS(json, converter) { - return converter ? _fromJSWith(converter, json, '', {'': json}) : _fromJSDefault(json); -} -function _fromJSWith(converter, json, key, parentJSON) { - if (Array.isArray(json)) { - return converter.call(parentJSON, key, IndexedSeq(json).map((function(v, k) { - return _fromJSWith(converter, v, k, json); - }))); - } - if (isPlainObj(json)) { - return converter.call(parentJSON, key, KeyedSeq(json).map((function(v, k) { - return _fromJSWith(converter, v, k, json); - }))); - } - return json; -} -function _fromJSDefault(json) { - if (Array.isArray(json)) { - return IndexedSeq(json).map(_fromJSDefault).toList(); - } - if (isPlainObj(json)) { - return KeyedSeq(json).map(_fromJSDefault).toMap(); - } - return json; -} -function isPlainObj(value) { - return value && value.constructor === Object; -} -var Collection = function Collection() { - throw TypeError('Abstract'); -}; -($traceurRuntime.createClass)(Collection, {}, {}, Iterable); -var KeyedCollection = function KeyedCollection() { - $traceurRuntime.defaultSuperCall(this, $KeyedCollection.prototype, arguments); -}; -var $KeyedCollection = KeyedCollection; -($traceurRuntime.createClass)(KeyedCollection, {}, {}, Collection); -mixin(KeyedCollection, KeyedIterable.prototype); -var IndexedCollection = function IndexedCollection() { - $traceurRuntime.defaultSuperCall(this, $IndexedCollection.prototype, arguments); -}; -var $IndexedCollection = IndexedCollection; -($traceurRuntime.createClass)(IndexedCollection, {}, {}, Collection); -mixin(IndexedCollection, IndexedIterable.prototype); -var SetCollection = function SetCollection() { - $traceurRuntime.defaultSuperCall(this, $SetCollection.prototype, arguments); -}; -var $SetCollection = SetCollection; -($traceurRuntime.createClass)(SetCollection, {}, {}, Collection); -mixin(SetCollection, SetIterable.prototype); -Collection.Keyed = KeyedCollection; -Collection.Indexed = IndexedCollection; -Collection.Set = SetCollection; -var Map = function Map(value) { - return value === null || value === undefined ? emptyMap() : isMap(value) ? value : emptyMap().merge(KeyedIterable(value)); -}; -($traceurRuntime.createClass)(Map, { - toString: function() { - return this.__toString('Map {', '}'); - }, - get: function(k, notSetValue) { - return this._root ? this._root.get(0, undefined, k, notSetValue) : notSetValue; - }, - set: function(k, v) { - return updateMap(this, k, v); - }, - setIn: function(keyPath, v) { - invariant(keyPath.length > 0, 'Requires non-empty key path.'); - return this.updateIn(keyPath, (function() { - return v; - })); - }, - remove: function(k) { - return updateMap(this, k, NOT_SET); - }, - removeIn: function(keyPath) { - invariant(keyPath.length > 0, 'Requires non-empty key path.'); - return this.updateIn(keyPath, (function() { - return NOT_SET; - })); - }, - update: function(k, notSetValue, updater) { - return arguments.length === 1 ? k(this) : this.updateIn([k], notSetValue, updater); - }, - updateIn: function(keyPath, notSetValue, updater) { - if (!updater) { - updater = notSetValue; - notSetValue = undefined; + if (o === true) { + return 1; } - return keyPath.length === 0 ? updater(this) : updateInDeepMap(this, keyPath, notSetValue, updater, 0); - }, - clear: function() { - if (this.size === 0) { - return this; - } - if (this.__ownerID) { - this.size = 0; - this._root = null; - this.__hash = undefined; - this.__altered = true; - return this; - } - return emptyMap(); - }, - merge: function() { - return mergeIntoMapWith(this, undefined, arguments); - }, - mergeWith: function(merger) { - for (var iters = [], - $__3 = 1; $__3 < arguments.length; $__3++) - iters[$__3 - 1] = arguments[$__3]; - return mergeIntoMapWith(this, merger, iters); - }, - mergeDeep: function() { - return mergeIntoMapWith(this, deepMerger(undefined), arguments); - }, - mergeDeepWith: function(merger) { - for (var iters = [], - $__4 = 1; $__4 < arguments.length; $__4++) - iters[$__4 - 1] = arguments[$__4]; - return mergeIntoMapWith(this, deepMerger(merger), iters); - }, - sort: function(comparator) { - return OrderedMap(sortFactory(this, comparator)); - }, - sortBy: function(mapper, comparator) { - return OrderedMap(sortFactory(this, comparator, mapper)); - }, - withMutations: function(fn) { - var mutable = this.asMutable(); - fn(mutable); - return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this; - }, - asMutable: function() { - return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); - }, - asImmutable: function() { - return this.__ensureOwner(); - }, - wasAltered: function() { - return this.__altered; - }, - __iterator: function(type, reverse) { - return new MapIterator(this, type, reverse); - }, - __iterate: function(fn, reverse) { - var $__0 = this; - var iterations = 0; - this._root && this._root.iterate((function(entry) { - iterations++; - return fn(entry[1], entry[0], $__0); - }), reverse); - return iterations; - }, - __ensureOwner: function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - if (!ownerID) { - this.__ownerID = ownerID; - this.__altered = false; - return this; - } - return makeMap(this.size, this._root, ownerID, this.__hash); - } -}, {}, KeyedCollection); -function isMap(maybeMap) { - return !!(maybeMap && maybeMap[IS_MAP_SENTINEL]); -} -Map.isMap = isMap; -var IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@'; -var MapPrototype = Map.prototype; -MapPrototype[IS_MAP_SENTINEL] = true; -MapPrototype[DELETE] = MapPrototype.remove; -var ArrayMapNode = function ArrayMapNode(ownerID, entries) { - this.ownerID = ownerID; - this.entries = entries; -}; -var $ArrayMapNode = ArrayMapNode; -($traceurRuntime.createClass)(ArrayMapNode, { - get: function(shift, keyHash, key, notSetValue) { - var entries = this.entries; - for (var ii = 0, - len = entries.length; ii < len; ii++) { - if (is(key, entries[ii][0])) { - return entries[ii][1]; + var type = typeof o; + if (type === 'number') { + var h = o | 0; + if (h !== o) { + h ^= o * 0xFFFFFFFF; } - } - return notSetValue; - }, - update: function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - var removed = value === NOT_SET; - var entries = this.entries; - var idx = 0; - for (var len = entries.length; idx < len; idx++) { - if (is(key, entries[idx][0])) { - break; + while (o > 0xFFFFFFFF) { + o /= 0xFFFFFFFF; + h ^= o; } + return smi(h); } - var exists = idx < len; - if (exists ? entries[idx][1] === value : removed) { - return this; + if (type === 'string') { + return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o); } - SetRef(didAlter); - (removed || !exists) && SetRef(didChangeSize); - if (removed && entries.length === 1) { - return; + if (typeof o.hashCode === 'function') { + return o.hashCode(); } - if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) { - return createNodes(ownerID, entries, key, value); - } - var isEditable = ownerID && ownerID === this.ownerID; - var newEntries = isEditable ? entries : arrCopy(entries); - if (exists) { - if (removed) { - idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); - } else { - newEntries[idx] = [key, value]; + return hashJSObj(o); + } + + function cachedHashString(string) { + var hash = stringHashCache[string]; + if (hash === undefined) { + hash = hashString(string); + if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) { + STRING_HASH_CACHE_SIZE = 0; + stringHashCache = {}; } - } else { - newEntries.push([key, value]); + STRING_HASH_CACHE_SIZE++; + stringHashCache[string] = hash; } - if (isEditable) { - this.entries = newEntries; - return this; + return hash; + } + + // http://jsperf.com/hashing-strings + function hashString(string) { + // This is the hash from JVM + // The hash code for a string is computed as + // s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1], + // where s[i] is the ith character of the string and n is the length of + // the string. We "mod" the result to make it between 0 (inclusive) and 2^31 + // (exclusive) by dropping high bits. + var hash = 0; + for (var ii = 0; ii < string.length; ii++) { + hash = 31 * hash + string.charCodeAt(ii) | 0; } - return new $ArrayMapNode(ownerID, newEntries); + return smi(hash); } -}, {}); -var BitmapIndexedNode = function BitmapIndexedNode(ownerID, bitmap, nodes) { - this.ownerID = ownerID; - this.bitmap = bitmap; - this.nodes = nodes; -}; -var $BitmapIndexedNode = BitmapIndexedNode; -($traceurRuntime.createClass)(BitmapIndexedNode, { - get: function(shift, keyHash, key, notSetValue) { - if (keyHash === undefined) { - keyHash = hash(key); + + function hashJSObj(obj) { + var hash = weakMap && weakMap.get(obj); + if (hash) return hash; + + hash = obj[UID_HASH_KEY]; + if (hash) return hash; + + if (!canDefineProperty) { + hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY]; + if (hash) return hash; + + hash = getIENodeHash(obj); + if (hash) return hash; } - var bit = (1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK)); - var bitmap = this.bitmap; - return (bitmap & bit) === 0 ? notSetValue : this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, keyHash, key, notSetValue); - }, - update: function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - if (keyHash === undefined) { - keyHash = hash(key); + + if (Object.isExtensible && !Object.isExtensible(obj)) { + throw new Error('Non-extensible objects are not allowed as keys.'); } - var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - var bit = 1 << keyHashFrag; - var bitmap = this.bitmap; - var exists = (bitmap & bit) !== 0; - if (!exists && value === NOT_SET) { - return this; + + hash = ++objHashUID; + if (objHashUID & 0x40000000) { + objHashUID = 0; } - var idx = popCount(bitmap & (bit - 1)); - var nodes = this.nodes; - var node = exists ? nodes[idx] : undefined; - var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter); - if (newNode === node) { - return this; + + if (weakMap) { + weakMap.set(obj, hash); + } else if (canDefineProperty) { + Object.defineProperty(obj, UID_HASH_KEY, { + 'enumerable': false, + 'configurable': false, + 'writable': false, + 'value': hash + }); + } else if (obj.propertyIsEnumerable && + obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable) { + // Since we can't define a non-enumerable property on the object + // we'll hijack one of the less-used non-enumerable properties to + // save our hash on it. Since this is a function it will not show up in + // `JSON.stringify` which is what we want. + obj.propertyIsEnumerable = function() { + return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments); + }; + obj.propertyIsEnumerable[UID_HASH_KEY] = hash; + } else if (obj.nodeType) { + // At this point we couldn't get the IE `uniqueID` to use as a hash + // and we couldn't use a non-enumerable property to exploit the + // dontEnum bug so we simply add the `UID_HASH_KEY` on the node + // itself. + obj[UID_HASH_KEY] = hash; + } else { + throw new Error('Unable to set a non-enumerable property on object.'); } - if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) { - return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode); - } - if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) { - return nodes[idx ^ 1]; - } - if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) { - return newNode; - } - var isEditable = ownerID && ownerID === this.ownerID; - var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit; - var newNodes = exists ? newNode ? setIn(nodes, idx, newNode, isEditable) : spliceOut(nodes, idx, isEditable) : spliceIn(nodes, idx, newNode, isEditable); - if (isEditable) { - this.bitmap = newBitmap; - this.nodes = newNodes; - return this; - } - return new $BitmapIndexedNode(ownerID, newBitmap, newNodes); + + return hash; } -}, {}); -var HashArrayMapNode = function HashArrayMapNode(ownerID, count, nodes) { - this.ownerID = ownerID; - this.count = count; - this.nodes = nodes; -}; -var $HashArrayMapNode = HashArrayMapNode; -($traceurRuntime.createClass)(HashArrayMapNode, { - get: function(shift, keyHash, key, notSetValue) { - if (keyHash === undefined) { - keyHash = hash(key); + + // True if Object.defineProperty works as expected. IE8 fails this test. + var canDefineProperty = (function() { + try { + Object.defineProperty({}, 'x', {}); + return true; + } catch (e) { + return false; } - var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - var node = this.nodes[idx]; - return node ? node.get(shift + SHIFT, keyHash, key, notSetValue) : notSetValue; - }, - update: function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - if (keyHash === undefined) { - keyHash = hash(key); - } - var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - var removed = value === NOT_SET; - var nodes = this.nodes; - var node = nodes[idx]; - if (removed && !node) { - return this; - } - var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter); - if (newNode === node) { - return this; - } - var newCount = this.count; - if (!node) { - newCount++; - } else if (!newNode) { - newCount--; - if (newCount < MIN_HASH_ARRAY_MAP_SIZE) { - return packNodes(ownerID, nodes, newCount, idx); + }()); + + // IE has a `uniqueID` property on DOM nodes. We can construct the hash from it + // and avoid memory leaks from the IE cloneNode bug. + function getIENodeHash(node) { + if (node && node.nodeType > 0) { + switch (node.nodeType) { + case 1: // Element + return node.uniqueID; + case 9: // Document + return node.documentElement && node.documentElement.uniqueID; } } - var isEditable = ownerID && ownerID === this.ownerID; - var newNodes = setIn(nodes, idx, newNode, isEditable); - if (isEditable) { - this.count = newCount; - this.nodes = newNodes; - return this; - } - return new $HashArrayMapNode(ownerID, newCount, newNodes); } -}, {}); -var HashCollisionNode = function HashCollisionNode(ownerID, keyHash, entries) { - this.ownerID = ownerID; - this.keyHash = keyHash; - this.entries = entries; -}; -var $HashCollisionNode = HashCollisionNode; -($traceurRuntime.createClass)(HashCollisionNode, { - get: function(shift, keyHash, key, notSetValue) { - var entries = this.entries; - for (var ii = 0, - len = entries.length; ii < len; ii++) { - if (is(key, entries[ii][0])) { - return entries[ii][1]; - } + + // If possible, use a WeakMap. + var weakMap = typeof WeakMap === 'function' && new WeakMap(); + + var objHashUID = 0; + + var UID_HASH_KEY = '__immutablehash__'; + if (typeof Symbol === 'function') { + UID_HASH_KEY = Symbol(UID_HASH_KEY); + } + + var STRING_HASH_CACHE_MIN_STRLEN = 16; + var STRING_HASH_CACHE_MAX_SIZE = 255; + var STRING_HASH_CACHE_SIZE = 0; + var stringHashCache = {}; + + function invariant(condition, error) { + if (!condition) throw new Error(error); + } + + function assertNotInfinite(size) { + invariant( + size !== Infinity, + 'Cannot perform this action with an infinite size.' + ); + } + + createClass(ToKeyedSequence, KeyedSeq); + function ToKeyedSequence(indexed, useKeys) { + this._iter = indexed; + this._useKeys = useKeys; + this.size = indexed.size; } - return notSetValue; - }, - update: function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - if (keyHash === undefined) { - keyHash = hash(key); - } - var removed = value === NOT_SET; - if (keyHash !== this.keyHash) { - if (removed) { - return this; + + ToKeyedSequence.prototype.get = function(key, notSetValue) { + return this._iter.get(key, notSetValue); + }; + + ToKeyedSequence.prototype.has = function(key) { + return this._iter.has(key); + }; + + ToKeyedSequence.prototype.valueSeq = function() { + return this._iter.valueSeq(); + }; + + ToKeyedSequence.prototype.reverse = function() {var this$0 = this; + var reversedSequence = reverseFactory(this, true); + if (!this._useKeys) { + reversedSequence.valueSeq = function() {return this$0._iter.toSeq().reverse()}; } - SetRef(didAlter); - SetRef(didChangeSize); - return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]); - } - var entries = this.entries; - var idx = 0; - for (var len = entries.length; idx < len; idx++) { - if (is(key, entries[idx][0])) { - break; + return reversedSequence; + }; + + ToKeyedSequence.prototype.map = function(mapper, context) {var this$0 = this; + var mappedSequence = mapFactory(this, mapper, context); + if (!this._useKeys) { + mappedSequence.valueSeq = function() {return this$0._iter.toSeq().map(mapper, context)}; } - } - var exists = idx < len; - if (exists ? entries[idx][1] === value : removed) { - return this; - } - SetRef(didAlter); - (removed || !exists) && SetRef(didChangeSize); - if (removed && len === 2) { - return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]); - } - var isEditable = ownerID && ownerID === this.ownerID; - var newEntries = isEditable ? entries : arrCopy(entries); - if (exists) { - if (removed) { - idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); - } else { - newEntries[idx] = [key, value]; + return mappedSequence; + }; + + ToKeyedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; + var ii; + return this._iter.__iterate( + this._useKeys ? + function(v, k) {return fn(v, k, this$0)} : + ((ii = reverse ? resolveSize(this) : 0), + function(v ) {return fn(v, reverse ? --ii : ii++, this$0)}), + reverse + ); + }; + + ToKeyedSequence.prototype.__iterator = function(type, reverse) { + if (this._useKeys) { + return this._iter.__iterator(type, reverse); } - } else { - newEntries.push([key, value]); + var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + var ii = reverse ? resolveSize(this) : 0; + return new Iterator(function() { + var step = iterator.next(); + return step.done ? step : + iteratorValue(type, reverse ? --ii : ii++, step.value, step); + }); + }; + + ToKeyedSequence.prototype[IS_ORDERED_SENTINEL] = true; + + + createClass(ToIndexedSequence, IndexedSeq); + function ToIndexedSequence(iter) { + this._iter = iter; + this.size = iter.size; } - if (isEditable) { - this.entries = newEntries; - return this; + + ToIndexedSequence.prototype.contains = function(value) { + return this._iter.contains(value); + }; + + ToIndexedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; + var iterations = 0; + return this._iter.__iterate(function(v ) {return fn(v, iterations++, this$0)}, reverse); + }; + + ToIndexedSequence.prototype.__iterator = function(type, reverse) { + var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + var iterations = 0; + return new Iterator(function() { + var step = iterator.next(); + return step.done ? step : + iteratorValue(type, iterations++, step.value, step) + }); + }; + + + + createClass(ToSetSequence, SetSeq); + function ToSetSequence(iter) { + this._iter = iter; + this.size = iter.size; } - return new $HashCollisionNode(ownerID, this.keyHash, newEntries); - } -}, {}); -var ValueNode = function ValueNode(ownerID, keyHash, entry) { - this.ownerID = ownerID; - this.keyHash = keyHash; - this.entry = entry; -}; -var $ValueNode = ValueNode; -($traceurRuntime.createClass)(ValueNode, { - get: function(shift, keyHash, key, notSetValue) { - return is(key, this.entry[0]) ? this.entry[1] : notSetValue; - }, - update: function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - var removed = value === NOT_SET; - var keyMatch = is(key, this.entry[0]); - if (keyMatch ? value === this.entry[1] : removed) { - return this; + + ToSetSequence.prototype.has = function(key) { + return this._iter.contains(key); + }; + + ToSetSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; + return this._iter.__iterate(function(v ) {return fn(v, v, this$0)}, reverse); + }; + + ToSetSequence.prototype.__iterator = function(type, reverse) { + var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + return new Iterator(function() { + var step = iterator.next(); + return step.done ? step : + iteratorValue(type, step.value, step.value, step); + }); + }; + + + + createClass(FromEntriesSequence, KeyedSeq); + function FromEntriesSequence(entries) { + this._iter = entries; + this.size = entries.size; } - SetRef(didAlter); - if (removed) { - SetRef(didChangeSize); - return; + + FromEntriesSequence.prototype.entrySeq = function() { + return this._iter.toSeq(); + }; + + FromEntriesSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; + return this._iter.__iterate(function(entry ) { + // Check if entry exists first so array access doesn't throw for holes + // in the parent iteration. + if (entry) { + validateEntry(entry); + return fn(entry[1], entry[0], this$0); + } + }, reverse); + }; + + FromEntriesSequence.prototype.__iterator = function(type, reverse) { + var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + return new Iterator(function() { + while (true) { + var step = iterator.next(); + if (step.done) { + return step; + } + var entry = step.value; + // Check if entry exists first so array access doesn't throw for holes + // in the parent iteration. + if (entry) { + validateEntry(entry); + return type === ITERATE_ENTRIES ? step : + iteratorValue(type, entry[0], entry[1], step); + } + } + }); + }; + + + ToIndexedSequence.prototype.cacheResult = + ToKeyedSequence.prototype.cacheResult = + ToSetSequence.prototype.cacheResult = + FromEntriesSequence.prototype.cacheResult = + cacheResultThrough; + + + function flipFactory(iterable) { + var flipSequence = makeSequence(iterable); + flipSequence._iter = iterable; + flipSequence.size = iterable.size; + flipSequence.flip = function() {return iterable}; + flipSequence.reverse = function () { + var reversedSequence = iterable.reverse.apply(this); // super.reverse() + reversedSequence.flip = function() {return iterable.reverse()}; + return reversedSequence; + }; + flipSequence.has = function(key ) {return iterable.contains(key)}; + flipSequence.contains = function(key ) {return iterable.has(key)}; + flipSequence.cacheResult = cacheResultThrough; + flipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; + return iterable.__iterate(function(v, k) {return fn(k, v, this$0) !== false}, reverse); } - if (keyMatch) { - if (ownerID && ownerID === this.ownerID) { - this.entry[1] = value; - return this; + flipSequence.__iteratorUncached = function(type, reverse) { + if (type === ITERATE_ENTRIES) { + var iterator = iterable.__iterator(type, reverse); + return new Iterator(function() { + var step = iterator.next(); + if (!step.done) { + var k = step.value[0]; + step.value[0] = step.value[1]; + step.value[1] = k; + } + return step; + }); } - return new $ValueNode(ownerID, this.keyHash, [key, value]); + return iterable.__iterator( + type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES, + reverse + ); } - SetRef(didChangeSize); - return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]); + return flipSequence; } -}, {}); -ArrayMapNode.prototype.iterate = HashCollisionNode.prototype.iterate = function(fn, reverse) { - var entries = this.entries; - for (var ii = 0, - maxIndex = entries.length - 1; ii <= maxIndex; ii++) { - if (fn(entries[reverse ? maxIndex - ii : ii]) === false) { - return false; + + + function mapFactory(iterable, mapper, context) { + var mappedSequence = makeSequence(iterable); + mappedSequence.size = iterable.size; + mappedSequence.has = function(key ) {return iterable.has(key)}; + mappedSequence.get = function(key, notSetValue) { + var v = iterable.get(key, NOT_SET); + return v === NOT_SET ? + notSetValue : + mapper.call(context, v, key, iterable); + }; + mappedSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; + return iterable.__iterate( + function(v, k, c) {return fn(mapper.call(context, v, k, c), k, this$0) !== false}, + reverse + ); } + mappedSequence.__iteratorUncached = function (type, reverse) { + var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); + return new Iterator(function() { + var step = iterator.next(); + if (step.done) { + return step; + } + var entry = step.value; + var key = entry[0]; + return iteratorValue( + type, + key, + mapper.call(context, entry[1], key, iterable), + step + ); + }); + } + return mappedSequence; } -}; -BitmapIndexedNode.prototype.iterate = HashArrayMapNode.prototype.iterate = function(fn, reverse) { - var nodes = this.nodes; - for (var ii = 0, - maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { - var node = nodes[reverse ? maxIndex - ii : ii]; - if (node && node.iterate(fn, reverse) === false) { - return false; + + + function reverseFactory(iterable, useKeys) { + var reversedSequence = makeSequence(iterable); + reversedSequence._iter = iterable; + reversedSequence.size = iterable.size; + reversedSequence.reverse = function() {return iterable}; + if (iterable.flip) { + reversedSequence.flip = function () { + var flipSequence = flipFactory(iterable); + flipSequence.reverse = function() {return iterable.flip()}; + return flipSequence; + }; } + reversedSequence.get = function(key, notSetValue) + {return iterable.get(useKeys ? key : -1 - key, notSetValue)}; + reversedSequence.has = function(key ) + {return iterable.has(useKeys ? key : -1 - key)}; + reversedSequence.contains = function(value ) {return iterable.contains(value)}; + reversedSequence.cacheResult = cacheResultThrough; + reversedSequence.__iterate = function (fn, reverse) {var this$0 = this; + return iterable.__iterate(function(v, k) {return fn(v, k, this$0)}, !reverse); + }; + reversedSequence.__iterator = + function(type, reverse) {return iterable.__iterator(type, !reverse)}; + return reversedSequence; } -}; -ValueNode.prototype.iterate = function(fn, reverse) { - return fn(this.entry); -}; -var MapIterator = function MapIterator(map, type, reverse) { - this._type = type; - this._reverse = reverse; - this._stack = map._root && mapIteratorFrame(map._root); -}; -($traceurRuntime.createClass)(MapIterator, {next: function() { - var type = this._type; - var stack = this._stack; - while (stack) { - var node = stack.node; - var index = stack.index++; - var maxIndex; - if (node.entry) { - if (index === 0) { - return mapIteratorValue(type, node.entry); + + + function filterFactory(iterable, predicate, context, useKeys) { + var filterSequence = makeSequence(iterable); + if (useKeys) { + filterSequence.has = function(key ) { + var v = iterable.get(key, NOT_SET); + return v !== NOT_SET && !!predicate.call(context, v, key, iterable); + }; + filterSequence.get = function(key, notSetValue) { + var v = iterable.get(key, NOT_SET); + return v !== NOT_SET && predicate.call(context, v, key, iterable) ? + v : notSetValue; + }; + } + filterSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; + var iterations = 0; + iterable.__iterate(function(v, k, c) { + if (predicate.call(context, v, k, c)) { + iterations++; + return fn(v, useKeys ? k : iterations - 1, this$0); } - } else if (node.entries) { - maxIndex = node.entries.length - 1; - if (index <= maxIndex) { - return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]); - } - } else { - maxIndex = node.nodes.length - 1; - if (index <= maxIndex) { - var subNode = node.nodes[this._reverse ? maxIndex - index : index]; - if (subNode) { - if (subNode.entry) { - return mapIteratorValue(type, subNode.entry); - } - stack = this._stack = mapIteratorFrame(subNode, stack); + }, reverse); + return iterations; + }; + filterSequence.__iteratorUncached = function (type, reverse) { + var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); + var iterations = 0; + return new Iterator(function() { + while (true) { + var step = iterator.next(); + if (step.done) { + return step; } - continue; + var entry = step.value; + var key = entry[0]; + var value = entry[1]; + if (predicate.call(context, value, key, iterable)) { + return iteratorValue(type, useKeys ? key : iterations++, value, step); + } } - } - stack = this._stack = this._stack.__prev; + }); } - return iteratorDone(); - }}, {}, Iterator); -function mapIteratorValue(type, entry) { - return iteratorValue(type, entry[0], entry[1]); -} -function mapIteratorFrame(node, prev) { - return { - node: node, - index: 0, - __prev: prev - }; -} -function makeMap(size, root, ownerID, hash) { - var map = Object.create(MapPrototype); - map.size = size; - map._root = root; - map.__ownerID = ownerID; - map.__hash = hash; - map.__altered = false; - return map; -} -var EMPTY_MAP; -function emptyMap() { - return EMPTY_MAP || (EMPTY_MAP = makeMap(0)); -} -function updateMap(map, k, v) { - var newRoot; - var newSize; - if (!map._root) { - if (v === NOT_SET) { - return map; - } - newSize = 1; - newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]); - } else { - var didChangeSize = MakeRef(CHANGE_LENGTH); - var didAlter = MakeRef(DID_ALTER); - newRoot = updateNode(map._root, map.__ownerID, 0, undefined, k, v, didChangeSize, didAlter); - if (!didAlter.value) { - return map; - } - newSize = map.size + (didChangeSize.value ? v === NOT_SET ? -1 : 1 : 0); + return filterSequence; } - if (map.__ownerID) { - map.size = newSize; - map._root = newRoot; - map.__hash = undefined; - map.__altered = true; - return map; + + + function countByFactory(iterable, grouper, context) { + var groups = Map().asMutable(); + iterable.__iterate(function(v, k) { + groups.update( + grouper.call(context, v, k, iterable), + 0, + function(a ) {return a + 1} + ); + }); + return groups.asImmutable(); } - return newRoot ? makeMap(newSize, newRoot) : emptyMap(); -} -function updateNode(node, ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { - if (!node) { - if (value === NOT_SET) { - return node; - } - SetRef(didAlter); - SetRef(didChangeSize); - return new ValueNode(ownerID, keyHash, [key, value]); - } - return node.update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter); -} -function isLeafNode(node) { - return node.constructor === ValueNode || node.constructor === HashCollisionNode; -} -function mergeIntoNode(node, ownerID, shift, keyHash, entry) { - if (node.keyHash === keyHash) { - return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]); - } - var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK; - var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; - var newNode; - var nodes = idx1 === idx2 ? [mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] : ((newNode = new ValueNode(ownerID, keyHash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]); - return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes); -} -function createNodes(ownerID, entries, key, value) { - if (!ownerID) { - ownerID = new OwnerID(); - } - var node = new ValueNode(ownerID, hash(key), [key, value]); - for (var ii = 0; ii < entries.length; ii++) { - var entry = entries[ii]; - node = node.update(ownerID, 0, undefined, entry[0], entry[1]); - } - return node; -} -function packNodes(ownerID, nodes, count, excluding) { - var bitmap = 0; - var packedII = 0; - var packedNodes = new Array(count); - for (var ii = 0, - bit = 1, - len = nodes.length; ii < len; ii++, bit <<= 1) { - var node = nodes[ii]; - if (node !== undefined && ii !== excluding) { - bitmap |= bit; - packedNodes[packedII++] = node; - } - } - return new BitmapIndexedNode(ownerID, bitmap, packedNodes); -} -function expandNodes(ownerID, nodes, bitmap, including, node) { - var count = 0; - var expandedNodes = new Array(SIZE); - for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) { - expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined; - } - expandedNodes[including] = node; - return new HashArrayMapNode(ownerID, count + 1, expandedNodes); -} -function mergeIntoMapWith(map, merger, iterables) { - var iters = []; - for (var ii = 0; ii < iterables.length; ii++) { - var value = iterables[ii]; - var iter = KeyedIterable(value); - if (!isIterable(value)) { - iter = iter.map((function(v) { - return fromJS(v); - })); - } - iters.push(iter); - } - return mergeIntoCollectionWith(map, merger, iters); -} -function deepMerger(merger) { - return (function(existing, value) { - return existing && existing.mergeDeepWith && isIterable(value) ? existing.mergeDeepWith(merger, value) : merger ? merger(existing, value) : value; - }); -} -function mergeIntoCollectionWith(collection, merger, iters) { - if (iters.length === 0) { - return collection; - } - return collection.withMutations((function(collection) { - var mergeIntoMap = merger ? (function(value, key) { - collection.update(key, NOT_SET, (function(existing) { - return existing === NOT_SET ? value : merger(existing, value); - })); - }) : (function(value, key) { - collection.set(key, value); + + + function groupByFactory(iterable, grouper, context) { + var isKeyedIter = isKeyed(iterable); + var groups = (isOrdered(iterable) ? OrderedMap() : Map()).asMutable(); + iterable.__iterate(function(v, k) { + groups.update( + grouper.call(context, v, k, iterable), + function(a ) {return (a = a || [], a.push(isKeyedIter ? [k, v] : v), a)} + ); }); - for (var ii = 0; ii < iters.length; ii++) { - iters[ii].forEach(mergeIntoMap); - } - })); -} -function updateInDeepMap(collection, keyPath, notSetValue, updater, offset) { - invariant(!collection || collection.set, 'updateIn with invalid keyPath'); - var key = keyPath[offset]; - var existing = collection ? collection.get(key, NOT_SET) : NOT_SET; - var existingValue = existing === NOT_SET ? undefined : existing; - var value = offset === keyPath.length - 1 ? updater(existing === NOT_SET ? notSetValue : existing) : updateInDeepMap(existingValue, keyPath, notSetValue, updater, offset + 1); - return value === existingValue ? collection : value === NOT_SET ? collection && collection.remove(key) : (collection || emptyMap()).set(key, value); -} -function popCount(x) { - x = x - ((x >> 1) & 0x55555555); - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x = x + (x >> 8); - x = x + (x >> 16); - return x & 0x7f; -} -function setIn(array, idx, val, canEdit) { - var newArray = canEdit ? array : arrCopy(array); - newArray[idx] = val; - return newArray; -} -function spliceIn(array, idx, val, canEdit) { - var newLen = array.length + 1; - if (canEdit && idx + 1 === newLen) { - array[idx] = val; - return array; + var coerce = iterableClass(iterable); + return groups.map(function(arr ) {return reify(iterable, coerce(arr))}); } - var newArray = new Array(newLen); - var after = 0; - for (var ii = 0; ii < newLen; ii++) { - if (ii === idx) { - newArray[ii] = val; - after = -1; - } else { - newArray[ii] = array[ii + after]; + + + function sliceFactory(iterable, begin, end, useKeys) { + var originalSize = iterable.size; + + if (wholeSlice(begin, end, originalSize)) { + return iterable; } - } - return newArray; -} -function spliceOut(array, idx, canEdit) { - var newLen = array.length - 1; - if (canEdit && idx === newLen) { - array.pop(); - return array; - } - var newArray = new Array(newLen); - var after = 0; - for (var ii = 0; ii < newLen; ii++) { - if (ii === idx) { - after = 1; + + var resolvedBegin = resolveBegin(begin, originalSize); + var resolvedEnd = resolveEnd(end, originalSize); + + // begin or end will be NaN if they were provided as negative numbers and + // this iterable's size is unknown. In that case, cache first so there is + // a known size. + if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) { + return sliceFactory(iterable.toSeq().cacheResult(), begin, end, useKeys); } - newArray[ii] = array[ii + after]; - } - return newArray; -} -var MAX_ARRAY_MAP_SIZE = SIZE / 4; -var MAX_BITMAP_INDEXED_SIZE = SIZE / 2; -var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4; -var ToKeyedSequence = function ToKeyedSequence(indexed, useKeys) { - this._iter = indexed; - this._useKeys = useKeys; - this.size = indexed.size; -}; -($traceurRuntime.createClass)(ToKeyedSequence, { - get: function(key, notSetValue) { - return this._iter.get(key, notSetValue); - }, - has: function(key) { - return this._iter.has(key); - }, - valueSeq: function() { - return this._iter.valueSeq(); - }, - reverse: function() { - var $__0 = this; - var reversedSequence = reverseFactory(this, true); - if (!this._useKeys) { - reversedSequence.valueSeq = (function() { - return $__0._iter.toSeq().reverse(); - }); + + var sliceSize = resolvedEnd - resolvedBegin; + if (sliceSize < 0) { + sliceSize = 0; } - return reversedSequence; - }, - map: function(mapper, context) { - var $__0 = this; - var mappedSequence = mapFactory(this, mapper, context); - if (!this._useKeys) { - mappedSequence.valueSeq = (function() { - return $__0._iter.toSeq().map(mapper, context); - }); + + var sliceSeq = makeSequence(iterable); + + sliceSeq.size = sliceSize === 0 ? sliceSize : iterable.size && sliceSize || undefined; + + if (!useKeys && isSeq(iterable) && sliceSize >= 0) { + sliceSeq.get = function (index, notSetValue) { + index = wrapIndex(this, index); + return index >= 0 && index < sliceSize ? + iterable.get(index + resolvedBegin, notSetValue) : + notSetValue; + } } - return mappedSequence; - }, - __iterate: function(fn, reverse) { - var $__0 = this; - var ii; - return this._iter.__iterate(this._useKeys ? (function(v, k) { - return fn(v, k, $__0); - }) : ((ii = reverse ? resolveSize(this) : 0), (function(v) { - return fn(v, reverse ? --ii : ii++, $__0); - })), reverse); - }, - __iterator: function(type, reverse) { - if (this._useKeys) { - return this._iter.__iterator(type, reverse); - } - var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); - var ii = reverse ? resolveSize(this) : 0; - return new Iterator((function() { - var step = iterator.next(); - return step.done ? step : iteratorValue(type, reverse ? --ii : ii++, step.value, step); - })); - } -}, {}, KeyedSeq); -ToKeyedSequence.prototype[IS_ORDERED_SENTINEL] = true; -var ToIndexedSequence = function ToIndexedSequence(iter) { - this._iter = iter; - this.size = iter.size; -}; -($traceurRuntime.createClass)(ToIndexedSequence, { - contains: function(value) { - return this._iter.contains(value); - }, - __iterate: function(fn, reverse) { - var $__0 = this; - var iterations = 0; - return this._iter.__iterate((function(v) { - return fn(v, iterations++, $__0); - }), reverse); - }, - __iterator: function(type, reverse) { - var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); - var iterations = 0; - return new Iterator((function() { - var step = iterator.next(); - return step.done ? step : iteratorValue(type, iterations++, step.value, step); - })); - } -}, {}, IndexedSeq); -var ToSetSequence = function ToSetSequence(iter) { - this._iter = iter; - this.size = iter.size; -}; -($traceurRuntime.createClass)(ToSetSequence, { - has: function(key) { - return this._iter.contains(key); - }, - __iterate: function(fn, reverse) { - var $__0 = this; - return this._iter.__iterate((function(v) { - return fn(v, v, $__0); - }), reverse); - }, - __iterator: function(type, reverse) { - var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); - return new Iterator((function() { - var step = iterator.next(); - return step.done ? step : iteratorValue(type, step.value, step.value, step); - })); - } -}, {}, SetSeq); -var FromEntriesSequence = function FromEntriesSequence(entries) { - this._iter = entries; - this.size = entries.size; -}; -($traceurRuntime.createClass)(FromEntriesSequence, { - entrySeq: function() { - return this._iter.toSeq(); - }, - __iterate: function(fn, reverse) { - var $__0 = this; - return this._iter.__iterate((function(entry) { - if (entry) { - validateEntry(entry); - return fn(entry[1], entry[0], $__0); + + sliceSeq.__iterateUncached = function(fn, reverse) {var this$0 = this; + if (sliceSize === 0) { + return 0; } - }), reverse); - }, - __iterator: function(type, reverse) { - var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); - return new Iterator((function() { - while (true) { - var step = iterator.next(); - if (step.done) { - return step; + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var skipped = 0; + var isSkipping = true; + var iterations = 0; + iterable.__iterate(function(v, k) { + if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) { + iterations++; + return fn(v, useKeys ? k : iterations - 1, this$0) !== false && + iterations !== sliceSize; } - var entry = step.value; - if (entry) { - validateEntry(entry); - return type === ITERATE_ENTRIES ? step : iteratorValue(type, entry[0], entry[1], step); - } + }); + return iterations; + }; + + sliceSeq.__iteratorUncached = function(type, reverse) { + if (sliceSize && reverse) { + return this.cacheResult().__iterator(type, reverse); } - })); - } -}, {}, KeyedSeq); -ToIndexedSequence.prototype.cacheResult = ToKeyedSequence.prototype.cacheResult = ToSetSequence.prototype.cacheResult = FromEntriesSequence.prototype.cacheResult = cacheResultThrough; -function flipFactory(iterable) { - var flipSequence = makeSequence(iterable); - flipSequence._iter = iterable; - flipSequence.size = iterable.size; - flipSequence.flip = (function() { - return iterable; - }); - flipSequence.reverse = function() { - var reversedSequence = iterable.reverse.apply(this); - reversedSequence.flip = (function() { - return iterable.reverse(); - }); - return reversedSequence; - }; - flipSequence.has = (function(key) { - return iterable.contains(key); - }); - flipSequence.contains = (function(key) { - return iterable.has(key); - }); - flipSequence.cacheResult = cacheResultThrough; - flipSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - return iterable.__iterate((function(v, k) { - return fn(k, v, $__0) !== false; - }), reverse); - }; - flipSequence.__iteratorUncached = function(type, reverse) { - if (type === ITERATE_ENTRIES) { - var iterator = iterable.__iterator(type, reverse); - return new Iterator((function() { + // Don't bother instantiating parent iterator if taking 0. + var iterator = sliceSize && iterable.__iterator(type, reverse); + var skipped = 0; + var iterations = 0; + return new Iterator(function() { + while (skipped++ !== resolvedBegin) { + iterator.next(); + } + if (++iterations > sliceSize) { + return iteratorDone(); + } var step = iterator.next(); - if (!step.done) { - var k = step.value[0]; - step.value[0] = step.value[1]; - step.value[1] = k; + if (useKeys || type === ITERATE_VALUES) { + return step; + } else if (type === ITERATE_KEYS) { + return iteratorValue(type, iterations - 1, undefined, step); + } else { + return iteratorValue(type, iterations - 1, step.value[1], step); } - return step; - })); + }); } - return iterable.__iterator(type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES, reverse); - }; - return flipSequence; -} -function mapFactory(iterable, mapper, context) { - var mappedSequence = makeSequence(iterable); - mappedSequence.size = iterable.size; - mappedSequence.has = (function(key) { - return iterable.has(key); - }); - mappedSequence.get = (function(key, notSetValue) { - var v = iterable.get(key, NOT_SET); - return v === NOT_SET ? notSetValue : mapper.call(context, v, key, iterable); - }); - mappedSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - return iterable.__iterate((function(v, k, c) { - return fn(mapper.call(context, v, k, c), k, $__0) !== false; - }), reverse); - }; - mappedSequence.__iteratorUncached = function(type, reverse) { - var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); - return new Iterator((function() { - var step = iterator.next(); - if (step.done) { - return step; + + return sliceSeq; + } + + + function takeWhileFactory(iterable, predicate, context) { + var takeSequence = makeSequence(iterable); + takeSequence.__iterateUncached = function(fn, reverse) {var this$0 = this; + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); } - var entry = step.value; - var key = entry[0]; - return iteratorValue(type, key, mapper.call(context, entry[1], key, iterable), step); - })); - }; - return mappedSequence; -} -function reverseFactory(iterable, useKeys) { - var reversedSequence = makeSequence(iterable); - reversedSequence._iter = iterable; - reversedSequence.size = iterable.size; - reversedSequence.reverse = (function() { - return iterable; - }); - if (iterable.flip) { - reversedSequence.flip = function() { - var flipSequence = flipFactory(iterable); - flipSequence.reverse = (function() { - return iterable.flip(); - }); - return flipSequence; + var iterations = 0; + iterable.__iterate(function(v, k, c) + {return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$0)} + ); + return iterations; }; - } - reversedSequence.get = (function(key, notSetValue) { - return iterable.get(useKeys ? key : -1 - key, notSetValue); - }); - reversedSequence.has = (function(key) { - return iterable.has(useKeys ? key : -1 - key); - }); - reversedSequence.contains = (function(value) { - return iterable.contains(value); - }); - reversedSequence.cacheResult = cacheResultThrough; - reversedSequence.__iterate = function(fn, reverse) { - var $__0 = this; - return iterable.__iterate((function(v, k) { - return fn(v, k, $__0); - }), !reverse); - }; - reversedSequence.__iterator = (function(type, reverse) { - return iterable.__iterator(type, !reverse); - }); - return reversedSequence; -} -function filterFactory(iterable, predicate, context, useKeys) { - var filterSequence = makeSequence(iterable); - if (useKeys) { - filterSequence.has = (function(key) { - var v = iterable.get(key, NOT_SET); - return v !== NOT_SET && !!predicate.call(context, v, key, iterable); - }); - filterSequence.get = (function(key, notSetValue) { - var v = iterable.get(key, NOT_SET); - return v !== NOT_SET && predicate.call(context, v, key, iterable) ? v : notSetValue; - }); - } - filterSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - var iterations = 0; - iterable.__iterate((function(v, k, c) { - if (predicate.call(context, v, k, c)) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, $__0); + takeSequence.__iteratorUncached = function(type, reverse) {var this$0 = this; + if (reverse) { + return this.cacheResult().__iterator(type, reverse); } - }), reverse); - return iterations; - }; - filterSequence.__iteratorUncached = function(type, reverse) { - var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); - var iterations = 0; - return new Iterator((function() { - while (true) { + var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); + var iterating = true; + return new Iterator(function() { + if (!iterating) { + return iteratorDone(); + } var step = iterator.next(); if (step.done) { return step; } var entry = step.value; - var key = entry[0]; - var value = entry[1]; - if (predicate.call(context, value, key, iterable)) { - return iteratorValue(type, useKeys ? key : iterations++, value, step); + var k = entry[0]; + var v = entry[1]; + if (!predicate.call(context, v, k, this$0)) { + iterating = false; + return iteratorDone(); } - } - })); - }; - return filterSequence; -} -function countByFactory(iterable, grouper, context) { - var groups = Map().asMutable(); - iterable.__iterate((function(v, k) { - groups.update(grouper.call(context, v, k, iterable), 0, (function(a) { - return a + 1; - })); - })); - return groups.asImmutable(); -} -function groupByFactory(iterable, grouper, context) { - var isKeyedIter = isKeyed(iterable); - var groups = Map().asMutable(); - iterable.__iterate((function(v, k) { - groups.update(grouper.call(context, v, k, iterable), [], (function(a) { - return (a.push(isKeyedIter ? [k, v] : v), a); - })); - })); - var coerce = iterableClass(iterable); - return groups.map((function(arr) { - return reify(iterable, coerce(arr)); - })); -} -function takeFactory(iterable, amount) { - if (amount > iterable.size) { - return iterable; + return type === ITERATE_ENTRIES ? step : + iteratorValue(type, k, v, step); + }); + }; + return takeSequence; } - if (amount < 0) { - amount = 0; - } - var takeSequence = makeSequence(iterable); - takeSequence.size = iterable.size && Math.min(iterable.size, amount); - takeSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - if (amount === 0) { - return 0; - } - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterations = 0; - iterable.__iterate((function(v, k) { - return ++iterations && fn(v, k, $__0) !== false && iterations < amount; - })); - return iterations; - }; - takeSequence.__iteratorUncached = function(type, reverse) { - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterator = amount && iterable.__iterator(type, reverse); - var iterations = 0; - return new Iterator((function() { - if (iterations++ > amount) { - return iteratorDone(); + + + function skipWhileFactory(iterable, predicate, context, useKeys) { + var skipSequence = makeSequence(iterable); + skipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); } - return iterator.next(); - })); - }; - return takeSequence; -} -function takeWhileFactory(iterable, predicate, context) { - var takeSequence = makeSequence(iterable); - takeSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var iterations = 0; - iterable.__iterate((function(v, k, c) { - return predicate.call(context, v, k, c) && ++iterations && fn(v, k, $__0); - })); - return iterations; - }; - takeSequence.__iteratorUncached = function(type, reverse) { - var $__0 = this; - if (reverse) { - return this.cacheResult().__iterator(type, reverse); - } - var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); - var iterating = true; - return new Iterator((function() { - if (!iterating) { - return iteratorDone(); + var isSkipping = true; + var iterations = 0; + iterable.__iterate(function(v, k, c) { + if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) { + iterations++; + return fn(v, useKeys ? k : iterations - 1, this$0); + } + }); + return iterations; + }; + skipSequence.__iteratorUncached = function(type, reverse) {var this$0 = this; + if (reverse) { + return this.cacheResult().__iterator(type, reverse); } - var step = iterator.next(); - if (step.done) { - return step; - } - var entry = step.value; - var k = entry[0]; - var v = entry[1]; - if (!predicate.call(context, v, k, $__0)) { - iterating = false; - return iteratorDone(); - } - return type === ITERATE_ENTRIES ? step : iteratorValue(type, k, v, step); - })); - }; - return takeSequence; -} -function skipFactory(iterable, amount, useKeys) { - if (amount <= 0) { - return iterable; + var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); + var skipping = true; + var iterations = 0; + return new Iterator(function() { + var step, k, v; + do { + step = iterator.next(); + if (step.done) { + if (useKeys || type === ITERATE_VALUES) { + return step; + } else if (type === ITERATE_KEYS) { + return iteratorValue(type, iterations++, undefined, step); + } else { + return iteratorValue(type, iterations++, step.value[1], step); + } + } + var entry = step.value; + k = entry[0]; + v = entry[1]; + skipping && (skipping = predicate.call(context, v, k, this$0)); + } while (skipping); + return type === ITERATE_ENTRIES ? step : + iteratorValue(type, k, v, step); + }); + }; + return skipSequence; } - var skipSequence = makeSequence(iterable); - skipSequence.size = iterable.size && Math.max(0, iterable.size - amount); - skipSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); - } - var skipped = 0; - var isSkipping = true; - var iterations = 0; - iterable.__iterate((function(v, k) { - if (!(isSkipping && (isSkipping = skipped++ < amount))) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, $__0); + + + function concatFactory(iterable, values) { + var isKeyedIterable = isKeyed(iterable); + var iters = [iterable].concat(values).map(function(v ) { + if (!isIterable(v)) { + v = isKeyedIterable ? + keyedSeqFromValue(v) : + indexedSeqFromValue(Array.isArray(v) ? v : [v]); + } else if (isKeyedIterable) { + v = KeyedIterable(v); } - })); - return iterations; - }; - skipSequence.__iteratorUncached = function(type, reverse) { - if (reverse) { - return this.cacheResult().__iterator(type, reverse); + return v; + }).filter(function(v ) {return v.size !== 0}); + + if (iters.length === 0) { + return iterable; } - var iterator = amount && iterable.__iterator(type, reverse); - var skipped = 0; - var iterations = 0; - return new Iterator((function() { - while (skipped < amount) { - skipped++; - iterator.next(); + + if (iters.length === 1) { + var singleton = iters[0]; + if (singleton === iterable || + isKeyedIterable && isKeyed(singleton) || + isIndexed(iterable) && isIndexed(singleton)) { + return singleton; } - var step = iterator.next(); - if (useKeys || type === ITERATE_VALUES) { - return step; - } else if (type === ITERATE_KEYS) { - return iteratorValue(type, iterations++, undefined, step); - } else { - return iteratorValue(type, iterations++, step.value[1], step); - } - })); - }; - return skipSequence; -} -function skipWhileFactory(iterable, predicate, context, useKeys) { - var skipSequence = makeSequence(iterable); - skipSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - if (reverse) { - return this.cacheResult().__iterate(fn, reverse); } - var isSkipping = true; - var iterations = 0; - iterable.__iterate((function(v, k, c) { - if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) { - iterations++; - return fn(v, useKeys ? k : iterations - 1, $__0); + + var concatSeq = new ArraySeq(iters); + if (isKeyedIterable) { + concatSeq = concatSeq.toKeyedSeq(); + } else if (!isIndexed(iterable)) { + concatSeq = concatSeq.toSetSeq(); + } + concatSeq = concatSeq.flatten(true); + concatSeq.size = iters.reduce( + function(sum, seq) { + if (sum !== undefined) { + var size = seq.size; + if (size !== undefined) { + return sum + size; + } + } + }, + 0 + ); + return concatSeq; + } + + + function flattenFactory(iterable, depth, useKeys) { + var flatSequence = makeSequence(iterable); + flatSequence.__iterateUncached = function(fn, reverse) { + var iterations = 0; + var stopped = false; + function flatDeep(iter, currentDepth) {var this$0 = this; + iter.__iterate(function(v, k) { + if ((!depth || currentDepth < depth) && isIterable(v)) { + flatDeep(v, currentDepth + 1); + } else if (fn(v, useKeys ? k : iterations++, this$0) === false) { + stopped = true; + } + return !stopped; + }, reverse); } - })); - return iterations; - }; - skipSequence.__iteratorUncached = function(type, reverse) { - var $__0 = this; - if (reverse) { - return this.cacheResult().__iterator(type, reverse); + flatDeep(iterable, 0); + return iterations; } - var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); - var skipping = true; - var iterations = 0; - return new Iterator((function() { - var step, - k, - v; - do { - step = iterator.next(); - if (step.done) { - if (useKeys || type === ITERATE_VALUES) { - return step; - } else if (type === ITERATE_KEYS) { - return iteratorValue(type, iterations++, undefined, step); + flatSequence.__iteratorUncached = function(type, reverse) { + var iterator = iterable.__iterator(type, reverse); + var stack = []; + var iterations = 0; + return new Iterator(function() { + while (iterator) { + var step = iterator.next(); + if (step.done !== false) { + iterator = stack.pop(); + continue; + } + var v = step.value; + if (type === ITERATE_ENTRIES) { + v = v[1]; + } + if ((!depth || stack.length < depth) && isIterable(v)) { + stack.push(iterator); + iterator = v.__iterator(type, reverse); } else { - return iteratorValue(type, iterations++, step.value[1], step); + return useKeys ? step : iteratorValue(type, iterations++, v, step); } } - var entry = step.value; - k = entry[0]; - v = entry[1]; - skipping && (skipping = predicate.call(context, v, k, $__0)); - } while (skipping); - return type === ITERATE_ENTRIES ? step : iteratorValue(type, k, v, step); - })); - }; - return skipSequence; -} -function concatFactory(iterable, values) { - var isKeyedIterable = isKeyed(iterable); - var iters = new ArraySeq([iterable].concat(values)).map((function(v) { - if (!isIterable(v)) { - v = isKeyedIterable ? keyedSeqFromValue(v) : indexedSeqFromValue(Array.isArray(v) ? v : [v]); - } else if (isKeyedIterable) { - v = KeyedIterable(v); + return iteratorDone(); + }); } - return v; - })); - if (isKeyedIterable) { - iters = iters.toKeyedSeq(); - } else if (!isIndexed(iterable)) { - iters = iters.toSetSeq(); + return flatSequence; } - var flat = iters.flatten(true); - flat.size = iters.reduce((function(sum, seq) { - if (sum !== undefined) { - var size = seq.size; - if (size !== undefined) { - return sum + size; - } - } - }), 0); - return flat; -} -function flattenFactory(iterable, depth, useKeys) { - var flatSequence = makeSequence(iterable); - flatSequence.__iterateUncached = function(fn, reverse) { - var iterations = 0; - var stopped = false; - function flatDeep(iter, currentDepth) { - var $__0 = this; - iter.__iterate((function(v, k) { - if ((!depth || currentDepth < depth) && isIterable(v)) { - flatDeep(v, currentDepth + 1); - } else if (fn(v, useKeys ? k : iterations++, $__0) === false) { - stopped = true; + + + function flatMapFactory(iterable, mapper, context) { + var coerce = iterableClass(iterable); + return iterable.toSeq().map( + function(v, k) {return coerce(mapper.call(context, v, k, iterable))} + ).flatten(true); + } + + + function interposeFactory(iterable, separator) { + var interposedSequence = makeSequence(iterable); + interposedSequence.size = iterable.size && iterable.size * 2 -1; + interposedSequence.__iterateUncached = function(fn, reverse) {var this$0 = this; + var iterations = 0; + iterable.__iterate(function(v, k) + {return (!iterations || fn(separator, iterations++, this$0) !== false) && + fn(v, iterations++, this$0) !== false}, + reverse + ); + return iterations; + }; + interposedSequence.__iteratorUncached = function(type, reverse) { + var iterator = iterable.__iterator(ITERATE_VALUES, reverse); + var iterations = 0; + var step; + return new Iterator(function() { + if (!step || iterations % 2) { + step = iterator.next(); + if (step.done) { + return step; + } } - return !stopped; - }), reverse); + return iterations % 2 ? + iteratorValue(type, iterations++, separator) : + iteratorValue(type, iterations++, step.value, step); + }); + }; + return interposedSequence; + } + + + function sortFactory(iterable, comparator, mapper) { + if (!comparator) { + comparator = defaultComparator; } - flatDeep(iterable, 0); - return iterations; - }; - flatSequence.__iteratorUncached = function(type, reverse) { - var iterator = iterable.__iterator(type, reverse); - var stack = []; - var iterations = 0; - return new Iterator((function() { - while (iterator) { - var step = iterator.next(); - if (step.done !== false) { - iterator = stack.pop(); - continue; + var isKeyedIterable = isKeyed(iterable); + var index = 0; + var entries = iterable.toSeq().map( + function(v, k) {return [k, v, index++, mapper ? mapper(v, k, iterable) : v]} + ).toArray(); + entries.sort(function(a, b) {return comparator(a[3], b[3]) || a[2] - b[2]}).forEach( + isKeyedIterable ? + function(v, i) { entries[i].length = 2; } : + function(v, i) { entries[i] = v[1]; } + ); + return isKeyedIterable ? KeyedSeq(entries) : + isIndexed(iterable) ? IndexedSeq(entries) : + SetSeq(entries); + } + + + function maxFactory(iterable, comparator, mapper) { + if (!comparator) { + comparator = defaultComparator; + } + if (mapper) { + var entry = iterable.toSeq() + .map(function(v, k) {return [v, mapper(v, k, iterable)]}) + .reduce(function(a, b) {return maxCompare(comparator, a[1], b[1]) ? b : a}); + return entry && entry[0]; + } else { + return iterable.reduce(function(a, b) {return maxCompare(comparator, a, b) ? b : a}); + } + } + + function maxCompare(comparator, a, b) { + var comp = comparator(b, a); + // b is considered the new max if the comparator declares them equal, but + // they are not equal and b is in fact a nullish value. + return (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || comp > 0; + } + + + function zipWithFactory(keyIter, zipper, iters) { + var zipSequence = makeSequence(keyIter); + zipSequence.size = new ArraySeq(iters).map(function(i ) {return i.size}).min(); + // Note: this a generic base implementation of __iterate in terms of + // __iterator which may be more generically useful in the future. + zipSequence.__iterate = function(fn, reverse) { + /* generic: + var iterator = this.__iterator(ITERATE_ENTRIES, reverse); + var step; + var iterations = 0; + while (!(step = iterator.next()).done) { + iterations++; + if (fn(step.value[1], step.value[0], this) === false) { + break; } - var v = step.value; - if (type === ITERATE_ENTRIES) { - v = v[1]; - } - if ((!depth || stack.length < depth) && isIterable(v)) { - stack.push(iterator); - iterator = v.__iterator(type, reverse); - } else { - return useKeys ? step : iteratorValue(type, iterations++, v, step); - } } - return iteratorDone(); - })); - }; - return flatSequence; -} -function flatMapFactory(iterable, mapper, context) { - var coerce = iterableClass(iterable); - return iterable.toSeq().map((function(v, k) { - return coerce(mapper.call(context, v, k, iterable)); - })).flatten(true); -} -function interposeFactory(iterable, separator) { - var interposedSequence = makeSequence(iterable); - interposedSequence.size = iterable.size && iterable.size * 2 - 1; - interposedSequence.__iterateUncached = function(fn, reverse) { - var $__0 = this; - var iterations = 0; - iterable.__iterate((function(v, k) { - return (!iterations || fn(separator, iterations++, $__0) !== false) && fn(v, iterations++, $__0) !== false; - }), reverse); - return iterations; - }; - interposedSequence.__iteratorUncached = function(type, reverse) { - var iterator = iterable.__iterator(ITERATE_VALUES, reverse); - var iterations = 0; - var step; - return new Iterator((function() { - if (!step || iterations % 2) { - step = iterator.next(); - if (step.done) { - return step; + return iterations; + */ + // indexed: + var iterator = this.__iterator(ITERATE_VALUES, reverse); + var step; + var iterations = 0; + while (!(step = iterator.next()).done) { + if (fn(step.value, iterations++, this) === false) { + break; } } - return iterations % 2 ? iteratorValue(type, iterations++, separator) : iteratorValue(type, iterations++, step.value, step); - })); - }; - return interposedSequence; -} -function sortFactory(iterable, comparator, mapper) { - if (!comparator) { - comparator = defaultComparator; + return iterations; + }; + zipSequence.__iteratorUncached = function(type, reverse) { + var iterators = iters.map(function(i ) + {return (i = Iterable(i), getIterator(reverse ? i.reverse() : i))} + ); + var iterations = 0; + var isDone = false; + return new Iterator(function() { + var steps; + if (!isDone) { + steps = iterators.map(function(i ) {return i.next()}); + isDone = steps.some(function(s ) {return s.done}); + } + if (isDone) { + return iteratorDone(); + } + return iteratorValue( + type, + iterations++, + zipper.apply(null, steps.map(function(s ) {return s.value})) + ); + }); + }; + return zipSequence } - var isKeyedIterable = isKeyed(iterable); - var index = 0; - var entries = iterable.toSeq().map((function(v, k) { - return [k, v, index++, mapper ? mapper(v, k, iterable) : v]; - })).toArray(); - entries.sort((function(a, b) { - return comparator(a[3], b[3]) || a[2] - b[2]; - })).forEach(isKeyedIterable ? (function(v, i) { - entries[i].length = 2; - }) : (function(v, i) { - entries[i] = v[1]; - })); - return isKeyedIterable ? KeyedSeq(entries) : isIndexed(iterable) ? IndexedSeq(entries) : SetSeq(entries); -} -function maxFactory(iterable, comparator, mapper) { - if (!comparator) { - comparator = defaultComparator; + + + // #pragma Helper Functions + + function reify(iter, seq) { + return isSeq(iter) ? seq : iter.constructor(seq); } - if (mapper) { - var entry = iterable.toSeq().map((function(v, k) { - return [v, mapper(v, k, iterable)]; - })).reduce((function(max, next) { - return comparator(next[1], max[1]) > 0 ? next : max; - })); - return entry && entry[0]; - } else { - return iterable.reduce((function(max, next) { - return comparator(next, max) > 0 ? next : max; - })); + + function validateEntry(entry) { + if (entry !== Object(entry)) { + throw new TypeError('Expected [K, V] tuple: ' + entry); + } } -} -function reify(iter, seq) { - return isSeq(iter) ? seq : iter.constructor(seq); -} -function validateEntry(entry) { - if (entry !== Object(entry)) { - throw new TypeError('Expected [K, V] tuple: ' + entry); + + function resolveSize(iter) { + assertNotInfinite(iter.size); + return ensureSize(iter); } -} -function resolveSize(iter) { - assertNotInfinite(iter.size); - return ensureSize(iter); -} -function iterableClass(iterable) { - return isKeyed(iterable) ? KeyedIterable : isIndexed(iterable) ? IndexedIterable : SetIterable; -} -function makeSequence(iterable) { - return Object.create((isKeyed(iterable) ? KeyedSeq : isIndexed(iterable) ? IndexedSeq : SetSeq).prototype); -} -function cacheResultThrough() { - if (this._iter.cacheResult) { - this._iter.cacheResult(); - this.size = this._iter.size; - return this; - } else { - return Seq.prototype.cacheResult.call(this); + + function iterableClass(iterable) { + return isKeyed(iterable) ? KeyedIterable : + isIndexed(iterable) ? IndexedIterable : + SetIterable; } -} -function defaultComparator(a, b) { - return a > b ? 1 : a < b ? -1 : 0; -} -var List = function List(value) { - var empty = emptyList(); - if (value === null || value === undefined) { - return empty; + + function makeSequence(iterable) { + return Object.create( + ( + isKeyed(iterable) ? KeyedSeq : + isIndexed(iterable) ? IndexedSeq : + SetSeq + ).prototype + ); } - if (isList(value)) { - return value; + + function cacheResultThrough() { + if (this._iter.cacheResult) { + this._iter.cacheResult(); + this.size = this._iter.size; + return this; + } else { + return Seq.prototype.cacheResult.call(this); + } } - value = IndexedIterable(value); - var size = value.size; - if (size === 0) { - return empty; + + function defaultComparator(a, b) { + return a > b ? 1 : a < b ? -1 : 0; } - if (size > 0 && size < SIZE) { - return makeList(0, size, SHIFT, null, new VNode(value.toArray())); + + function forceIterator(keyPath) { + var iter = getIterator(keyPath); + if (!iter) { + // Array might not be iterable in this environment, so we need a fallback + // to our wrapped type. + if (!isArrayLike(keyPath)) { + throw new TypeError('Expected iterable or array-like: ' + keyPath); + } + iter = getIterator(Iterable(keyPath)); + } + return iter; } - return empty.merge(value); -}; -($traceurRuntime.createClass)(List, { - toString: function() { - return this.__toString('List [', ']'); - }, - get: function(index, notSetValue) { - index = wrapIndex(this, index); - if (index < 0 || index >= this.size) { - return notSetValue; + + createClass(Map, KeyedCollection); + + // @pragma Construction + + function Map(value) { + return value === null || value === undefined ? emptyMap() : + isMap(value) ? value : + emptyMap().withMutations(function(map ) { + var iter = KeyedIterable(value); + assertNotInfinite(iter.size); + iter.forEach(function(v, k) {return map.set(k, v)}); + }); } - index += this._origin; - var node = listNodeFor(this, index); - return node && node.array[index & MASK]; - }, - set: function(index, value) { - return updateList(this, index, value); - }, - remove: function(index) { - return !this.has(index) ? this : index === 0 ? this.shift() : index === this.size - 1 ? this.pop() : this.splice(index, 1); - }, - clear: function() { - if (this.size === 0) { - return this; - } - if (this.__ownerID) { - this.size = this._origin = this._capacity = 0; - this._level = SHIFT; - this._root = this._tail = null; - this.__hash = undefined; - this.__altered = true; - return this; - } - return emptyList(); - }, - push: function() { - var values = arguments; - var oldSize = this.size; - return this.withMutations((function(list) { - setListBounds(list, 0, oldSize + values.length); - for (var ii = 0; ii < values.length; ii++) { - list.set(oldSize + ii, values[ii]); + + Map.prototype.toString = function() { + return this.__toString('Map {', '}'); + }; + + // @pragma Access + + Map.prototype.get = function(k, notSetValue) { + return this._root ? + this._root.get(0, undefined, k, notSetValue) : + notSetValue; + }; + + // @pragma Modification + + Map.prototype.set = function(k, v) { + return updateMap(this, k, v); + }; + + Map.prototype.setIn = function(keyPath, v) { + return this.updateIn(keyPath, NOT_SET, function() {return v}); + }; + + Map.prototype.remove = function(k) { + return updateMap(this, k, NOT_SET); + }; + + Map.prototype.deleteIn = function(keyPath) { + return this.updateIn(keyPath, function() {return NOT_SET}); + }; + + Map.prototype.update = function(k, notSetValue, updater) { + return arguments.length === 1 ? + k(this) : + this.updateIn([k], notSetValue, updater); + }; + + Map.prototype.updateIn = function(keyPath, notSetValue, updater) { + if (!updater) { + updater = notSetValue; + notSetValue = undefined; } - })); - }, - pop: function() { - return setListBounds(this, 0, -1); - }, - unshift: function() { - var values = arguments; - return this.withMutations((function(list) { - setListBounds(list, -values.length); - for (var ii = 0; ii < values.length; ii++) { - list.set(ii, values[ii]); + var updatedValue = updateInDeepMap( + this, + forceIterator(keyPath), + notSetValue, + updater + ); + return updatedValue === NOT_SET ? undefined : updatedValue; + }; + + Map.prototype.clear = function() { + if (this.size === 0) { + return this; } - })); - }, - shift: function() { - return setListBounds(this, 1); - }, - merge: function() { - return mergeIntoListWith(this, undefined, arguments); - }, - mergeWith: function(merger) { - for (var iters = [], - $__5 = 1; $__5 < arguments.length; $__5++) - iters[$__5 - 1] = arguments[$__5]; - return mergeIntoListWith(this, merger, iters); - }, - mergeDeep: function() { - return mergeIntoListWith(this, deepMerger(undefined), arguments); - }, - mergeDeepWith: function(merger) { - for (var iters = [], - $__6 = 1; $__6 < arguments.length; $__6++) - iters[$__6 - 1] = arguments[$__6]; - return mergeIntoListWith(this, deepMerger(merger), iters); - }, - setSize: function(size) { - return setListBounds(this, 0, size); - }, - slice: function(begin, end) { - var size = this.size; - if (wholeSlice(begin, end, size)) { - return this; - } - return setListBounds(this, resolveBegin(begin, size), resolveEnd(end, size)); - }, - __iterator: function(type, reverse) { - return new ListIterator(this, type, reverse); - }, - __iterate: function(fn, reverse) { - var $__0 = this; - var iterations = 0; - var eachFn = (function(v) { - return fn(v, iterations++, $__0); - }); - var tailOffset = getTailOffset(this._capacity); - if (reverse) { - iterateVNode(this._tail, 0, tailOffset - this._origin, this._capacity - this._origin, eachFn, reverse) && iterateVNode(this._root, this._level, -this._origin, tailOffset - this._origin, eachFn, reverse); - } else { - iterateVNode(this._root, this._level, -this._origin, tailOffset - this._origin, eachFn, reverse) && iterateVNode(this._tail, 0, tailOffset - this._origin, this._capacity - this._origin, eachFn, reverse); - } - return iterations; - }, - __ensureOwner: function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - if (!ownerID) { - this.__ownerID = ownerID; - return this; - } - return makeList(this._origin, this._capacity, this._level, this._root, this._tail, ownerID, this.__hash); + if (this.__ownerID) { + this.size = 0; + this._root = null; + this.__hash = undefined; + this.__altered = true; + return this; + } + return emptyMap(); + }; + + // @pragma Composition + + Map.prototype.merge = function(/*...iters*/) { + return mergeIntoMapWith(this, undefined, arguments); + }; + + Map.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); + return mergeIntoMapWith(this, merger, iters); + }; + + Map.prototype.mergeIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1); + return this.updateIn(keyPath, emptyMap(), function(m ) {return m.merge.apply(m, iters)}); + }; + + Map.prototype.mergeDeep = function(/*...iters*/) { + return mergeIntoMapWith(this, deepMerger(undefined), arguments); + }; + + Map.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1); + return mergeIntoMapWith(this, deepMerger(merger), iters); + }; + + Map.prototype.mergeDeepIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1); + return this.updateIn(keyPath, emptyMap(), function(m ) {return m.mergeDeep.apply(m, iters)}); + }; + + Map.prototype.sort = function(comparator) { + // Late binding + return OrderedMap(sortFactory(this, comparator)); + }; + + Map.prototype.sortBy = function(mapper, comparator) { + // Late binding + return OrderedMap(sortFactory(this, comparator, mapper)); + }; + + // @pragma Mutability + + Map.prototype.withMutations = function(fn) { + var mutable = this.asMutable(); + fn(mutable); + return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this; + }; + + Map.prototype.asMutable = function() { + return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); + }; + + Map.prototype.asImmutable = function() { + return this.__ensureOwner(); + }; + + Map.prototype.wasAltered = function() { + return this.__altered; + }; + + Map.prototype.__iterator = function(type, reverse) { + return new MapIterator(this, type, reverse); + }; + + Map.prototype.__iterate = function(fn, reverse) {var this$0 = this; + var iterations = 0; + this._root && this._root.iterate(function(entry ) { + iterations++; + return fn(entry[1], entry[0], this$0); + }, reverse); + return iterations; + }; + + Map.prototype.__ensureOwner = function(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + if (!ownerID) { + this.__ownerID = ownerID; + this.__altered = false; + return this; + } + return makeMap(this.size, this._root, ownerID, this.__hash); + }; + + + function isMap(maybeMap) { + return !!(maybeMap && maybeMap[IS_MAP_SENTINEL]); } -}, {of: function() { - return this(arguments); - }}, IndexedCollection); -function isList(maybeList) { - return !!(maybeList && maybeList[IS_LIST_SENTINEL]); -} -List.isList = isList; -var IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@'; -var ListPrototype = List.prototype; -ListPrototype[IS_LIST_SENTINEL] = true; -ListPrototype[DELETE] = ListPrototype.remove; -ListPrototype.setIn = MapPrototype.setIn; -ListPrototype.removeIn = MapPrototype.removeIn; -ListPrototype.update = MapPrototype.update; -ListPrototype.updateIn = MapPrototype.updateIn; -ListPrototype.withMutations = MapPrototype.withMutations; -ListPrototype.asMutable = MapPrototype.asMutable; -ListPrototype.asImmutable = MapPrototype.asImmutable; -ListPrototype.wasAltered = MapPrototype.wasAltered; -var VNode = function VNode(array, ownerID) { - this.array = array; - this.ownerID = ownerID; -}; -var $VNode = VNode; -($traceurRuntime.createClass)(VNode, { - removeBefore: function(ownerID, level, index) { - if (index === level ? 1 << level : 0 || this.array.length === 0) { - return this; + + Map.isMap = isMap; + + var IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@'; + + var MapPrototype = Map.prototype; + MapPrototype[IS_MAP_SENTINEL] = true; + MapPrototype[DELETE] = MapPrototype.remove; + MapPrototype.removeIn = MapPrototype.deleteIn; + + + // #pragma Trie Nodes + + + + function ArrayMapNode(ownerID, entries) { + this.ownerID = ownerID; + this.entries = entries; } - var originIndex = (index >>> level) & MASK; - if (originIndex >= this.array.length) { - return new $VNode([], ownerID); - } - var removingFirst = originIndex === 0; - var newChild; - if (level > 0) { - var oldChild = this.array[originIndex]; - newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index); - if (newChild === oldChild && removingFirst) { + + ArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) { + var entries = this.entries; + for (var ii = 0, len = entries.length; ii < len; ii++) { + if (is(key, entries[ii][0])) { + return entries[ii][1]; + } + } + return notSetValue; + }; + + ArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + var removed = value === NOT_SET; + + var entries = this.entries; + var idx = 0; + for (var len = entries.length; idx < len; idx++) { + if (is(key, entries[idx][0])) { + break; + } + } + var exists = idx < len; + + if (exists ? entries[idx][1] === value : removed) { return this; } + + SetRef(didAlter); + (removed || !exists) && SetRef(didChangeSize); + + if (removed && entries.length === 1) { + return; // undefined + } + + if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) { + return createNodes(ownerID, entries, key, value); + } + + var isEditable = ownerID && ownerID === this.ownerID; + var newEntries = isEditable ? entries : arrCopy(entries); + + if (exists) { + if (removed) { + idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); + } else { + newEntries[idx] = [key, value]; + } + } else { + newEntries.push([key, value]); + } + + if (isEditable) { + this.entries = newEntries; + return this; + } + + return new ArrayMapNode(ownerID, newEntries); + }; + + + + + function BitmapIndexedNode(ownerID, bitmap, nodes) { + this.ownerID = ownerID; + this.bitmap = bitmap; + this.nodes = nodes; } - if (removingFirst && !newChild) { - return this; - } - var editable = editableVNode(this, ownerID); - if (!removingFirst) { - for (var ii = 0; ii < originIndex; ii++) { - editable.array[ii] = undefined; + + BitmapIndexedNode.prototype.get = function(shift, keyHash, key, notSetValue) { + if (keyHash === undefined) { + keyHash = hash(key); } + var bit = (1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK)); + var bitmap = this.bitmap; + return (bitmap & bit) === 0 ? notSetValue : + this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, keyHash, key, notSetValue); + }; + + BitmapIndexedNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (keyHash === undefined) { + keyHash = hash(key); + } + var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + var bit = 1 << keyHashFrag; + var bitmap = this.bitmap; + var exists = (bitmap & bit) !== 0; + + if (!exists && value === NOT_SET) { + return this; + } + + var idx = popCount(bitmap & (bit - 1)); + var nodes = this.nodes; + var node = exists ? nodes[idx] : undefined; + var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter); + + if (newNode === node) { + return this; + } + + if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) { + return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode); + } + + if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) { + return nodes[idx ^ 1]; + } + + if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) { + return newNode; + } + + var isEditable = ownerID && ownerID === this.ownerID; + var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit; + var newNodes = exists ? newNode ? + setIn(nodes, idx, newNode, isEditable) : + spliceOut(nodes, idx, isEditable) : + spliceIn(nodes, idx, newNode, isEditable); + + if (isEditable) { + this.bitmap = newBitmap; + this.nodes = newNodes; + return this; + } + + return new BitmapIndexedNode(ownerID, newBitmap, newNodes); + }; + + + + + function HashArrayMapNode(ownerID, count, nodes) { + this.ownerID = ownerID; + this.count = count; + this.nodes = nodes; } - if (newChild) { - editable.array[originIndex] = newChild; - } - return editable; - }, - removeAfter: function(ownerID, level, index) { - if (index === level ? 1 << level : 0 || this.array.length === 0) { - return this; - } - var sizeIndex = ((index - 1) >>> level) & MASK; - if (sizeIndex >= this.array.length) { - return this; - } - var removingLast = sizeIndex === this.array.length - 1; - var newChild; - if (level > 0) { - var oldChild = this.array[sizeIndex]; - newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index); - if (newChild === oldChild && removingLast) { + + HashArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) { + if (keyHash === undefined) { + keyHash = hash(key); + } + var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + var node = this.nodes[idx]; + return node ? node.get(shift + SHIFT, keyHash, key, notSetValue) : notSetValue; + }; + + HashArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (keyHash === undefined) { + keyHash = hash(key); + } + var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + var removed = value === NOT_SET; + var nodes = this.nodes; + var node = nodes[idx]; + + if (removed && !node) { return this; } + + var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter); + if (newNode === node) { + return this; + } + + var newCount = this.count; + if (!node) { + newCount++; + } else if (!newNode) { + newCount--; + if (newCount < MIN_HASH_ARRAY_MAP_SIZE) { + return packNodes(ownerID, nodes, newCount, idx); + } + } + + var isEditable = ownerID && ownerID === this.ownerID; + var newNodes = setIn(nodes, idx, newNode, isEditable); + + if (isEditable) { + this.count = newCount; + this.nodes = newNodes; + return this; + } + + return new HashArrayMapNode(ownerID, newCount, newNodes); + }; + + + + + function HashCollisionNode(ownerID, keyHash, entries) { + this.ownerID = ownerID; + this.keyHash = keyHash; + this.entries = entries; } - if (removingLast && !newChild) { - return this; - } - var editable = editableVNode(this, ownerID); - if (!removingLast) { - editable.array.pop(); - } - if (newChild) { - editable.array[sizeIndex] = newChild; - } - return editable; - } -}, {}); -function iterateVNode(node, level, offset, max, fn, reverse) { - var ii; - var array = node && node.array; - if (level === 0) { - var from = offset < 0 ? -offset : 0; - var to = max - offset; - if (to > SIZE) { - to = SIZE; - } - for (ii = from; ii < to; ii++) { - if (fn(array && array[reverse ? from + to - 1 - ii : ii]) === false) { - return false; + + HashCollisionNode.prototype.get = function(shift, keyHash, key, notSetValue) { + var entries = this.entries; + for (var ii = 0, len = entries.length; ii < len; ii++) { + if (is(key, entries[ii][0])) { + return entries[ii][1]; + } } + return notSetValue; + }; + + HashCollisionNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (keyHash === undefined) { + keyHash = hash(key); + } + + var removed = value === NOT_SET; + + if (keyHash !== this.keyHash) { + if (removed) { + return this; + } + SetRef(didAlter); + SetRef(didChangeSize); + return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]); + } + + var entries = this.entries; + var idx = 0; + for (var len = entries.length; idx < len; idx++) { + if (is(key, entries[idx][0])) { + break; + } + } + var exists = idx < len; + + if (exists ? entries[idx][1] === value : removed) { + return this; + } + + SetRef(didAlter); + (removed || !exists) && SetRef(didChangeSize); + + if (removed && len === 2) { + return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]); + } + + var isEditable = ownerID && ownerID === this.ownerID; + var newEntries = isEditable ? entries : arrCopy(entries); + + if (exists) { + if (removed) { + idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); + } else { + newEntries[idx] = [key, value]; + } + } else { + newEntries.push([key, value]); + } + + if (isEditable) { + this.entries = newEntries; + return this; + } + + return new HashCollisionNode(ownerID, this.keyHash, newEntries); + }; + + + + + function ValueNode(ownerID, keyHash, entry) { + this.ownerID = ownerID; + this.keyHash = keyHash; + this.entry = entry; } - } else { - var step = 1 << level; - var newLevel = level - SHIFT; - for (ii = 0; ii <= MASK; ii++) { - var levelIndex = reverse ? MASK - ii : ii; - var newOffset = offset + (levelIndex << level); - if (newOffset < max && newOffset + step > 0) { - var nextNode = array && array[levelIndex]; - if (!iterateVNode(nextNode, newLevel, newOffset, max, fn, reverse)) { - return false; + + ValueNode.prototype.get = function(shift, keyHash, key, notSetValue) { + return is(key, this.entry[0]) ? this.entry[1] : notSetValue; + }; + + ValueNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + var removed = value === NOT_SET; + var keyMatch = is(key, this.entry[0]); + if (keyMatch ? value === this.entry[1] : removed) { + return this; + } + + SetRef(didAlter); + + if (removed) { + SetRef(didChangeSize); + return; // undefined + } + + if (keyMatch) { + if (ownerID && ownerID === this.ownerID) { + this.entry[1] = value; + return this; } + return new ValueNode(ownerID, this.keyHash, [key, value]); } + + SetRef(didChangeSize); + return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]); + }; + + + + // #pragma Iterators + + ArrayMapNode.prototype.iterate = + HashCollisionNode.prototype.iterate = function (fn, reverse) { + var entries = this.entries; + for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) { + if (fn(entries[reverse ? maxIndex - ii : ii]) === false) { + return false; + } } } - return true; -} -var ListIterator = function ListIterator(list, type, reverse) { - this._type = type; - this._reverse = !!reverse; - this._maxIndex = list.size - 1; - var tailOffset = getTailOffset(list._capacity); - var rootStack = listIteratorFrame(list._root && list._root.array, list._level, -list._origin, tailOffset - list._origin - 1); - var tailStack = listIteratorFrame(list._tail && list._tail.array, 0, tailOffset - list._origin, list._capacity - list._origin - 1); - this._stack = reverse ? tailStack : rootStack; - this._stack.__prev = reverse ? rootStack : tailStack; -}; -($traceurRuntime.createClass)(ListIterator, {next: function() { - var stack = this._stack; - while (stack) { - var array = stack.array; - var rawIndex = stack.index++; - if (this._reverse) { - rawIndex = MASK - rawIndex; - if (rawIndex > stack.rawMax) { - rawIndex = stack.rawMax; - stack.index = SIZE - rawIndex; - } + + BitmapIndexedNode.prototype.iterate = + HashArrayMapNode.prototype.iterate = function (fn, reverse) { + var nodes = this.nodes; + for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { + var node = nodes[reverse ? maxIndex - ii : ii]; + if (node && node.iterate(fn, reverse) === false) { + return false; } - if (rawIndex >= 0 && rawIndex < SIZE && rawIndex <= stack.rawMax) { - var value = array && array[rawIndex]; - if (stack.level === 0) { - var type = this._type; - var index; - if (type !== 1) { - index = stack.offset + (rawIndex << stack.level); - if (this._reverse) { - index = this._maxIndex - index; - } + } + } + + ValueNode.prototype.iterate = function (fn, reverse) { + return fn(this.entry); + } + + createClass(MapIterator, Iterator); + + function MapIterator(map, type, reverse) { + this._type = type; + this._reverse = reverse; + this._stack = map._root && mapIteratorFrame(map._root); + } + + MapIterator.prototype.next = function() { + var type = this._type; + var stack = this._stack; + while (stack) { + var node = stack.node; + var index = stack.index++; + var maxIndex; + if (node.entry) { + if (index === 0) { + return mapIteratorValue(type, node.entry); } - return iteratorValue(type, index, value); + } else if (node.entries) { + maxIndex = node.entries.length - 1; + if (index <= maxIndex) { + return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]); + } } else { - this._stack = stack = listIteratorFrame(value && value.array, stack.level - SHIFT, stack.offset + (rawIndex << stack.level), stack.max, stack); + maxIndex = node.nodes.length - 1; + if (index <= maxIndex) { + var subNode = node.nodes[this._reverse ? maxIndex - index : index]; + if (subNode) { + if (subNode.entry) { + return mapIteratorValue(type, subNode.entry); + } + stack = this._stack = mapIteratorFrame(subNode, stack); + } + continue; + } } - continue; + stack = this._stack = this._stack.__prev; } - stack = this._stack = this._stack.__prev; - } - return iteratorDone(); - }}, {}, Iterator); -function listIteratorFrame(array, level, offset, max, prevFrame) { - return { - array: array, - level: level, - offset: offset, - max: max, - rawMax: ((max - offset) >> level), - index: 0, - __prev: prevFrame - }; -} -function makeList(origin, capacity, level, root, tail, ownerID, hash) { - var list = Object.create(ListPrototype); - list.size = capacity - origin; - list._origin = origin; - list._capacity = capacity; - list._level = level; - list._root = root; - list._tail = tail; - list.__ownerID = ownerID; - list.__hash = hash; - list.__altered = false; - return list; -} -var EMPTY_LIST; -function emptyList() { - return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT)); -} -function updateList(list, index, value) { - index = wrapIndex(list, index); - if (index >= list.size || index < 0) { - return list.withMutations((function(list) { - index < 0 ? setListBounds(list, index).set(0, value) : setListBounds(list, 0, index + 1).set(index, value); - })); + return iteratorDone(); + }; + + + function mapIteratorValue(type, entry) { + return iteratorValue(type, entry[0], entry[1]); } - index += list._origin; - var newTail = list._tail; - var newRoot = list._root; - var didAlter = MakeRef(DID_ALTER); - if (index >= getTailOffset(list._capacity)) { - newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter); - } else { - newRoot = updateVNode(newRoot, list.__ownerID, list._level, index, value, didAlter); + + function mapIteratorFrame(node, prev) { + return { + node: node, + index: 0, + __prev: prev + }; } - if (!didAlter.value) { - return list; + + function makeMap(size, root, ownerID, hash) { + var map = Object.create(MapPrototype); + map.size = size; + map._root = root; + map.__ownerID = ownerID; + map.__hash = hash; + map.__altered = false; + return map; } - if (list.__ownerID) { - list._root = newRoot; - list._tail = newTail; - list.__hash = undefined; - list.__altered = true; - return list; + + var EMPTY_MAP; + function emptyMap() { + return EMPTY_MAP || (EMPTY_MAP = makeMap(0)); } - return makeList(list._origin, list._capacity, list._level, newRoot, newTail); -} -function updateVNode(node, ownerID, level, index, value, didAlter) { - var idx = (index >>> level) & MASK; - var nodeHas = node && idx < node.array.length; - if (!nodeHas && value === undefined) { - return node; + + function updateMap(map, k, v) { + var newRoot; + var newSize; + if (!map._root) { + if (v === NOT_SET) { + return map; + } + newSize = 1; + newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]); + } else { + var didChangeSize = MakeRef(CHANGE_LENGTH); + var didAlter = MakeRef(DID_ALTER); + newRoot = updateNode(map._root, map.__ownerID, 0, undefined, k, v, didChangeSize, didAlter); + if (!didAlter.value) { + return map; + } + newSize = map.size + (didChangeSize.value ? v === NOT_SET ? -1 : 1 : 0); + } + if (map.__ownerID) { + map.size = newSize; + map._root = newRoot; + map.__hash = undefined; + map.__altered = true; + return map; + } + return newRoot ? makeMap(newSize, newRoot) : emptyMap(); } - var newNode; - if (level > 0) { - var lowerNode = node && node.array[idx]; - var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter); - if (newLowerNode === lowerNode) { - return node; + + function updateNode(node, ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (!node) { + if (value === NOT_SET) { + return node; + } + SetRef(didAlter); + SetRef(didChangeSize); + return new ValueNode(ownerID, keyHash, [key, value]); } - newNode = editableVNode(node, ownerID); - newNode.array[idx] = newLowerNode; - return newNode; + return node.update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter); } - if (nodeHas && node.array[idx] === value) { - return node; + + function isLeafNode(node) { + return node.constructor === ValueNode || node.constructor === HashCollisionNode; } - SetRef(didAlter); - newNode = editableVNode(node, ownerID); - if (value === undefined && idx === newNode.array.length - 1) { - newNode.array.pop(); - } else { - newNode.array[idx] = value; + + function mergeIntoNode(node, ownerID, shift, keyHash, entry) { + if (node.keyHash === keyHash) { + return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]); + } + + var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK; + var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + + var newNode; + var nodes = idx1 === idx2 ? + [mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] : + ((newNode = new ValueNode(ownerID, keyHash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]); + + return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes); } - return newNode; -} -function editableVNode(node, ownerID) { - if (ownerID && node && ownerID === node.ownerID) { + + function createNodes(ownerID, entries, key, value) { + if (!ownerID) { + ownerID = new OwnerID(); + } + var node = new ValueNode(ownerID, hash(key), [key, value]); + for (var ii = 0; ii < entries.length; ii++) { + var entry = entries[ii]; + node = node.update(ownerID, 0, undefined, entry[0], entry[1]); + } return node; } - return new VNode(node ? node.array.slice() : [], ownerID); -} -function listNodeFor(list, rawIndex) { - if (rawIndex >= getTailOffset(list._capacity)) { - return list._tail; + + function packNodes(ownerID, nodes, count, excluding) { + var bitmap = 0; + var packedII = 0; + var packedNodes = new Array(count); + for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) { + var node = nodes[ii]; + if (node !== undefined && ii !== excluding) { + bitmap |= bit; + packedNodes[packedII++] = node; + } + } + return new BitmapIndexedNode(ownerID, bitmap, packedNodes); } - if (rawIndex < 1 << (list._level + SHIFT)) { - var node = list._root; - var level = list._level; - while (node && level > 0) { - node = node.array[(rawIndex >>> level) & MASK]; - level -= SHIFT; + + function expandNodes(ownerID, nodes, bitmap, including, node) { + var count = 0; + var expandedNodes = new Array(SIZE); + for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) { + expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined; } - return node; + expandedNodes[including] = node; + return new HashArrayMapNode(ownerID, count + 1, expandedNodes); } -} -function setListBounds(list, begin, end) { - var owner = list.__ownerID || new OwnerID(); - var oldOrigin = list._origin; - var oldCapacity = list._capacity; - var newOrigin = oldOrigin + begin; - var newCapacity = end === undefined ? oldCapacity : end < 0 ? oldCapacity + end : oldOrigin + end; - if (newOrigin === oldOrigin && newCapacity === oldCapacity) { - return list; + + function mergeIntoMapWith(map, merger, iterables) { + var iters = []; + for (var ii = 0; ii < iterables.length; ii++) { + var value = iterables[ii]; + var iter = KeyedIterable(value); + if (!isIterable(value)) { + iter = iter.map(function(v ) {return fromJS(v)}); + } + iters.push(iter); + } + return mergeIntoCollectionWith(map, merger, iters); } - if (newOrigin >= newCapacity) { - return list.clear(); + + function deepMerger(merger) { + return function(existing, value) + {return existing && existing.mergeDeepWith && isIterable(value) ? + existing.mergeDeepWith(merger, value) : + merger ? merger(existing, value) : value}; } - var newLevel = list._level; - var newRoot = list._root; - var offsetShift = 0; - while (newOrigin + offsetShift < 0) { - newRoot = new VNode(newRoot && newRoot.array.length ? [undefined, newRoot] : [], owner); - newLevel += SHIFT; - offsetShift += 1 << newLevel; + + function mergeIntoCollectionWith(collection, merger, iters) { + iters = iters.filter(function(x ) {return x.size !== 0}); + if (iters.length === 0) { + return collection; + } + if (collection.size === 0 && iters.length === 1) { + return collection.constructor(iters[0]); + } + return collection.withMutations(function(collection ) { + var mergeIntoMap = merger ? + function(value, key) { + collection.update(key, NOT_SET, function(existing ) + {return existing === NOT_SET ? value : merger(existing, value)} + ); + } : + function(value, key) { + collection.set(key, value); + } + for (var ii = 0; ii < iters.length; ii++) { + iters[ii].forEach(mergeIntoMap); + } + }); } - if (offsetShift) { - newOrigin += offsetShift; - oldOrigin += offsetShift; - newCapacity += offsetShift; - oldCapacity += offsetShift; + + function updateInDeepMap(existing, keyPathIter, notSetValue, updater) { + var isNotSet = existing === NOT_SET; + var step = keyPathIter.next(); + if (step.done) { + var existingValue = isNotSet ? notSetValue : existing; + var newValue = updater(existingValue); + return newValue === existingValue ? existing : newValue; + } + invariant( + isNotSet || (existing && existing.set), + 'invalid keyPath' + ); + var key = step.value; + var nextExisting = isNotSet ? NOT_SET : existing.get(key, NOT_SET); + var nextUpdated = updateInDeepMap( + nextExisting, + keyPathIter, + notSetValue, + updater + ); + return nextUpdated === nextExisting ? existing : + nextUpdated === NOT_SET ? existing.remove(key) : + (isNotSet ? emptyMap() : existing).set(key, nextUpdated); } - var oldTailOffset = getTailOffset(oldCapacity); - var newTailOffset = getTailOffset(newCapacity); - while (newTailOffset >= 1 << (newLevel + SHIFT)) { - newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner); - newLevel += SHIFT; + + function popCount(x) { + x = x - ((x >> 1) & 0x55555555); + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0f0f0f0f; + x = x + (x >> 8); + x = x + (x >> 16); + return x & 0x7f; } - var oldTail = list._tail; - var newTail = newTailOffset < oldTailOffset ? listNodeFor(list, newCapacity - 1) : newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail; - if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) { - newRoot = editableVNode(newRoot, owner); - var node = newRoot; - for (var level = newLevel; level > SHIFT; level -= SHIFT) { - var idx = (oldTailOffset >>> level) & MASK; - node = node.array[idx] = editableVNode(node.array[idx], owner); + + function setIn(array, idx, val, canEdit) { + var newArray = canEdit ? array : arrCopy(array); + newArray[idx] = val; + return newArray; + } + + function spliceIn(array, idx, val, canEdit) { + var newLen = array.length + 1; + if (canEdit && idx + 1 === newLen) { + array[idx] = val; + return array; } - node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail; + var newArray = new Array(newLen); + var after = 0; + for (var ii = 0; ii < newLen; ii++) { + if (ii === idx) { + newArray[ii] = val; + after = -1; + } else { + newArray[ii] = array[ii + after]; + } + } + return newArray; } - if (newCapacity < oldCapacity) { - newTail = newTail && newTail.removeAfter(owner, 0, newCapacity); + + function spliceOut(array, idx, canEdit) { + var newLen = array.length - 1; + if (canEdit && idx === newLen) { + array.pop(); + return array; + } + var newArray = new Array(newLen); + var after = 0; + for (var ii = 0; ii < newLen; ii++) { + if (ii === idx) { + after = 1; + } + newArray[ii] = array[ii + after]; + } + return newArray; } - if (newOrigin >= newTailOffset) { - newOrigin -= newTailOffset; - newCapacity -= newTailOffset; - newLevel = SHIFT; - newRoot = null; - newTail = newTail && newTail.removeBefore(owner, 0, newOrigin); - } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) { - offsetShift = 0; - while (newRoot) { - var beginIndex = (newOrigin >>> newLevel) & MASK; - if (beginIndex !== (newTailOffset >>> newLevel) & MASK) { - break; + + var MAX_ARRAY_MAP_SIZE = SIZE / 4; + var MAX_BITMAP_INDEXED_SIZE = SIZE / 2; + var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4; + + createClass(List, IndexedCollection); + + // @pragma Construction + + function List(value) { + var empty = emptyList(); + if (value === null || value === undefined) { + return empty; } - if (beginIndex) { - offsetShift += (1 << newLevel) * beginIndex; + if (isList(value)) { + return value; } - newLevel -= SHIFT; - newRoot = newRoot.array[beginIndex]; + var iter = IndexedIterable(value); + var size = iter.size; + if (size === 0) { + return empty; + } + assertNotInfinite(size); + if (size > 0 && size < SIZE) { + return makeList(0, size, SHIFT, null, new VNode(iter.toArray())); + } + return empty.withMutations(function(list ) { + list.setSize(size); + iter.forEach(function(v, i) {return list.set(i, v)}); + }); } - if (newRoot && newOrigin > oldOrigin) { - newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift); + + List.of = function(/*...values*/) { + return this(arguments); + }; + + List.prototype.toString = function() { + return this.__toString('List [', ']'); + }; + + // @pragma Access + + List.prototype.get = function(index, notSetValue) { + index = wrapIndex(this, index); + if (index < 0 || index >= this.size) { + return notSetValue; + } + index += this._origin; + var node = listNodeFor(this, index); + return node && node.array[index & MASK]; + }; + + // @pragma Modification + + List.prototype.set = function(index, value) { + return updateList(this, index, value); + }; + + List.prototype.remove = function(index) { + return !this.has(index) ? this : + index === 0 ? this.shift() : + index === this.size - 1 ? this.pop() : + this.splice(index, 1); + }; + + List.prototype.clear = function() { + if (this.size === 0) { + return this; + } + if (this.__ownerID) { + this.size = this._origin = this._capacity = 0; + this._level = SHIFT; + this._root = this._tail = null; + this.__hash = undefined; + this.__altered = true; + return this; + } + return emptyList(); + }; + + List.prototype.push = function(/*...values*/) { + var values = arguments; + var oldSize = this.size; + return this.withMutations(function(list ) { + setListBounds(list, 0, oldSize + values.length); + for (var ii = 0; ii < values.length; ii++) { + list.set(oldSize + ii, values[ii]); + } + }); + }; + + List.prototype.pop = function() { + return setListBounds(this, 0, -1); + }; + + List.prototype.unshift = function(/*...values*/) { + var values = arguments; + return this.withMutations(function(list ) { + setListBounds(list, -values.length); + for (var ii = 0; ii < values.length; ii++) { + list.set(ii, values[ii]); + } + }); + }; + + List.prototype.shift = function() { + return setListBounds(this, 1); + }; + + // @pragma Composition + + List.prototype.merge = function(/*...iters*/) { + return mergeIntoListWith(this, undefined, arguments); + }; + + List.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); + return mergeIntoListWith(this, merger, iters); + }; + + List.prototype.mergeDeep = function(/*...iters*/) { + return mergeIntoListWith(this, deepMerger(undefined), arguments); + }; + + List.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1); + return mergeIntoListWith(this, deepMerger(merger), iters); + }; + + List.prototype.setSize = function(size) { + return setListBounds(this, 0, size); + }; + + // @pragma Iteration + + List.prototype.slice = function(begin, end) { + var size = this.size; + if (wholeSlice(begin, end, size)) { + return this; + } + return setListBounds( + this, + resolveBegin(begin, size), + resolveEnd(end, size) + ); + }; + + List.prototype.__iterator = function(type, reverse) { + var index = 0; + var values = iterateList(this, reverse); + return new Iterator(function() { + var value = values(); + return value === DONE ? + iteratorDone() : + iteratorValue(type, index++, value); + }); + }; + + List.prototype.__iterate = function(fn, reverse) { + var index = 0; + var values = iterateList(this, reverse); + var value; + while ((value = values()) !== DONE) { + if (fn(value, index++, this) === false) { + break; + } + } + return index; + }; + + List.prototype.__ensureOwner = function(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + if (!ownerID) { + this.__ownerID = ownerID; + return this; + } + return makeList(this._origin, this._capacity, this._level, this._root, this._tail, ownerID, this.__hash); + }; + + + function isList(maybeList) { + return !!(maybeList && maybeList[IS_LIST_SENTINEL]); + } + + List.isList = isList; + + var IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@'; + + var ListPrototype = List.prototype; + ListPrototype[IS_LIST_SENTINEL] = true; + ListPrototype[DELETE] = ListPrototype.remove; + ListPrototype.setIn = MapPrototype.setIn; + ListPrototype.deleteIn = + ListPrototype.removeIn = MapPrototype.removeIn; + ListPrototype.update = MapPrototype.update; + ListPrototype.updateIn = MapPrototype.updateIn; + ListPrototype.mergeIn = MapPrototype.mergeIn; + ListPrototype.mergeDeepIn = MapPrototype.mergeDeepIn; + ListPrototype.withMutations = MapPrototype.withMutations; + ListPrototype.asMutable = MapPrototype.asMutable; + ListPrototype.asImmutable = MapPrototype.asImmutable; + ListPrototype.wasAltered = MapPrototype.wasAltered; + + + + function VNode(array, ownerID) { + this.array = array; + this.ownerID = ownerID; } - if (newRoot && newTailOffset < oldTailOffset) { - newRoot = newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift); + + // TODO: seems like these methods are very similar + + VNode.prototype.removeBefore = function(ownerID, level, index) { + if (index === level ? 1 << level : 0 || this.array.length === 0) { + return this; + } + var originIndex = (index >>> level) & MASK; + if (originIndex >= this.array.length) { + return new VNode([], ownerID); + } + var removingFirst = originIndex === 0; + var newChild; + if (level > 0) { + var oldChild = this.array[originIndex]; + newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index); + if (newChild === oldChild && removingFirst) { + return this; + } + } + if (removingFirst && !newChild) { + return this; + } + var editable = editableVNode(this, ownerID); + if (!removingFirst) { + for (var ii = 0; ii < originIndex; ii++) { + editable.array[ii] = undefined; + } + } + if (newChild) { + editable.array[originIndex] = newChild; + } + return editable; + }; + + VNode.prototype.removeAfter = function(ownerID, level, index) { + if (index === level ? 1 << level : 0 || this.array.length === 0) { + return this; + } + var sizeIndex = ((index - 1) >>> level) & MASK; + if (sizeIndex >= this.array.length) { + return this; + } + var removingLast = sizeIndex === this.array.length - 1; + var newChild; + if (level > 0) { + var oldChild = this.array[sizeIndex]; + newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index); + if (newChild === oldChild && removingLast) { + return this; + } + } + if (removingLast && !newChild) { + return this; + } + var editable = editableVNode(this, ownerID); + if (!removingLast) { + editable.array.pop(); + } + if (newChild) { + editable.array[sizeIndex] = newChild; + } + return editable; + }; + + + + var DONE = {}; + + function iterateList(list, reverse) { + var left = list._origin; + var right = list._capacity; + var tailPos = getTailOffset(right); + var tail = list._tail; + + return iterateNodeOrLeaf(list._root, list._level, 0); + + function iterateNodeOrLeaf(node, level, offset) { + return level === 0 ? + iterateLeaf(node, offset) : + iterateNode(node, level, offset); } - if (offsetShift) { - newOrigin -= offsetShift; - newCapacity -= offsetShift; + + function iterateLeaf(node, offset) { + var array = offset === tailPos ? tail && tail.array : node && node.array; + var from = offset > left ? 0 : left - offset; + var to = right - offset; + if (to > SIZE) { + to = SIZE; + } + return function() { + if (from === to) { + return DONE; + } + var idx = reverse ? --to : from++; + return array && array[idx]; + }; } + + function iterateNode(node, level, offset) { + var values; + var array = node && node.array; + var from = offset > left ? 0 : (left - offset) >> level; + var to = ((right - offset) >> level) + 1; + if (to > SIZE) { + to = SIZE; + } + return function() { + do { + if (values) { + var value = values(); + if (value !== DONE) { + return value; + } + values = null; + } + if (from === to) { + return DONE; + } + var idx = reverse ? --to : from++; + values = iterateNodeOrLeaf( + array && array[idx], level - SHIFT, offset + (idx << level) + ); + } while (true); + }; + } } - if (list.__ownerID) { - list.size = newCapacity - newOrigin; - list._origin = newOrigin; - list._capacity = newCapacity; - list._level = newLevel; - list._root = newRoot; - list._tail = newTail; - list.__hash = undefined; - list.__altered = true; + + function makeList(origin, capacity, level, root, tail, ownerID, hash) { + var list = Object.create(ListPrototype); + list.size = capacity - origin; + list._origin = origin; + list._capacity = capacity; + list._level = level; + list._root = root; + list._tail = tail; + list.__ownerID = ownerID; + list.__hash = hash; + list.__altered = false; return list; } - return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail); -} -function mergeIntoListWith(list, merger, iterables) { - var iters = []; - var maxSize = 0; - for (var ii = 0; ii < iterables.length; ii++) { - var value = iterables[ii]; - var iter = IndexedIterable(value); - if (iter.size > maxSize) { - maxSize = iter.size; - } - if (!isIterable(value)) { - iter = iter.map((function(v) { - return fromJS(v); - })); - } - iters.push(iter); + + var EMPTY_LIST; + function emptyList() { + return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT)); } - if (maxSize > list.size) { - list = list.setSize(maxSize); - } - return mergeIntoCollectionWith(list, merger, iters); -} -function getTailOffset(size) { - return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT); -} -var OrderedMap = function OrderedMap(value) { - return value === null || value === undefined ? emptyOrderedMap() : isOrderedMap(value) ? value : emptyOrderedMap().merge(KeyedIterable(value)); -}; -($traceurRuntime.createClass)(OrderedMap, { - toString: function() { - return this.__toString('OrderedMap {', '}'); - }, - get: function(k, notSetValue) { - var index = this._map.get(k); - return index !== undefined ? this._list.get(index)[1] : notSetValue; - }, - clear: function() { - if (this.size === 0) { - return this; + + function updateList(list, index, value) { + index = wrapIndex(list, index); + + if (index >= list.size || index < 0) { + return list.withMutations(function(list ) { + index < 0 ? + setListBounds(list, index).set(0, value) : + setListBounds(list, 0, index + 1).set(index, value) + }); } - if (this.__ownerID) { - this.size = 0; - this._map.clear(); - this._list.clear(); - return this; + + index += list._origin; + + var newTail = list._tail; + var newRoot = list._root; + var didAlter = MakeRef(DID_ALTER); + if (index >= getTailOffset(list._capacity)) { + newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter); + } else { + newRoot = updateVNode(newRoot, list.__ownerID, list._level, index, value, didAlter); } - return emptyOrderedMap(); - }, - set: function(k, v) { - return updateOrderedMap(this, k, v); - }, - remove: function(k) { - return updateOrderedMap(this, k, NOT_SET); - }, - wasAltered: function() { - return this._map.wasAltered() || this._list.wasAltered(); - }, - __iterate: function(fn, reverse) { - var $__0 = this; - return this._list.__iterate((function(entry) { - return entry && fn(entry[1], entry[0], $__0); - }), reverse); - }, - __iterator: function(type, reverse) { - return this._list.fromEntrySeq().__iterator(type, reverse); - }, - __ensureOwner: function(ownerID) { - if (ownerID === this.__ownerID) { - return this; + + if (!didAlter.value) { + return list; } - var newMap = this._map.__ensureOwner(ownerID); - var newList = this._list.__ensureOwner(ownerID); - if (!ownerID) { - this.__ownerID = ownerID; - this._map = newMap; - this._list = newList; - return this; + + if (list.__ownerID) { + list._root = newRoot; + list._tail = newTail; + list.__hash = undefined; + list.__altered = true; + return list; } - return makeOrderedMap(newMap, newList, ownerID, this.__hash); + return makeList(list._origin, list._capacity, list._level, newRoot, newTail); } -}, {of: function() { - return this(arguments); - }}, Map); -function isOrderedMap(maybeOrderedMap) { - return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap); -} -OrderedMap.isOrderedMap = isOrderedMap; -OrderedMap.prototype[IS_ORDERED_SENTINEL] = true; -OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove; -function makeOrderedMap(map, list, ownerID, hash) { - var omap = Object.create(OrderedMap.prototype); - omap.size = map ? map.size : 0; - omap._map = map; - omap._list = list; - omap.__ownerID = ownerID; - omap.__hash = hash; - return omap; -} -var EMPTY_ORDERED_MAP; -function emptyOrderedMap() { - return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList())); -} -function updateOrderedMap(omap, k, v) { - var map = omap._map; - var list = omap._list; - var i = map.get(k); - var has = i !== undefined; - var newMap; - var newList; - if (v === NOT_SET) { - if (!has) { - return omap; + + function updateVNode(node, ownerID, level, index, value, didAlter) { + var idx = (index >>> level) & MASK; + var nodeHas = node && idx < node.array.length; + if (!nodeHas && value === undefined) { + return node; } - if (list.size >= SIZE && list.size >= map.size * 2) { - newList = list.filter((function(entry, idx) { - return entry !== undefined && i !== idx; - })); - newMap = newList.toKeyedSeq().map((function(entry) { - return entry[0]; - })).flip().toMap(); - if (omap.__ownerID) { - newMap.__ownerID = newList.__ownerID = omap.__ownerID; + + var newNode; + + if (level > 0) { + var lowerNode = node && node.array[idx]; + var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter); + if (newLowerNode === lowerNode) { + return node; } - } else { - newMap = map.remove(k); - newList = i === list.size - 1 ? list.pop() : list.set(i, undefined); + newNode = editableVNode(node, ownerID); + newNode.array[idx] = newLowerNode; + return newNode; } - } else { - if (has) { - if (v === list.get(i)[1]) { - return omap; - } - newMap = map; - newList = list.set(i, [k, v]); + + if (nodeHas && node.array[idx] === value) { + return node; + } + + SetRef(didAlter); + + newNode = editableVNode(node, ownerID); + if (value === undefined && idx === newNode.array.length - 1) { + newNode.array.pop(); } else { - newMap = map.set(k, list.size); - newList = list.set(list.size, [k, v]); + newNode.array[idx] = value; } + return newNode; } - if (omap.__ownerID) { - omap.size = newMap.size; - omap._map = newMap; - omap._list = newList; - omap.__hash = undefined; - return omap; + + function editableVNode(node, ownerID) { + if (ownerID && node && ownerID === node.ownerID) { + return node; + } + return new VNode(node ? node.array.slice() : [], ownerID); } - return makeOrderedMap(newMap, newList); -} -var Stack = function Stack(value) { - return value === null || value === undefined ? emptyStack() : isStack(value) ? value : emptyStack().unshiftAll(value); -}; -var $Stack = Stack; -($traceurRuntime.createClass)(Stack, { - toString: function() { - return this.__toString('Stack [', ']'); - }, - get: function(index, notSetValue) { - var head = this._head; - while (head && index--) { - head = head.next; + + function listNodeFor(list, rawIndex) { + if (rawIndex >= getTailOffset(list._capacity)) { + return list._tail; } - return head ? head.value : notSetValue; - }, - peek: function() { - return this._head && this._head.value; - }, - push: function() { - if (arguments.length === 0) { - return this; + if (rawIndex < 1 << (list._level + SHIFT)) { + var node = list._root; + var level = list._level; + while (node && level > 0) { + node = node.array[(rawIndex >>> level) & MASK]; + level -= SHIFT; + } + return node; } - var newSize = this.size + arguments.length; - var head = this._head; - for (var ii = arguments.length - 1; ii >= 0; ii--) { - head = { - value: arguments[ii], - next: head - }; + } + + function setListBounds(list, begin, end) { + var owner = list.__ownerID || new OwnerID(); + var oldOrigin = list._origin; + var oldCapacity = list._capacity; + var newOrigin = oldOrigin + begin; + var newCapacity = end === undefined ? oldCapacity : end < 0 ? oldCapacity + end : oldOrigin + end; + if (newOrigin === oldOrigin && newCapacity === oldCapacity) { + return list; } - if (this.__ownerID) { - this.size = newSize; - this._head = head; - this.__hash = undefined; - this.__altered = true; - return this; + + // If it's going to end after it starts, it's empty. + if (newOrigin >= newCapacity) { + return list.clear(); } - return makeStack(newSize, head); - }, - pushAll: function(iter) { - iter = IndexedIterable(iter); - if (iter.size === 0) { - return this; + + var newLevel = list._level; + var newRoot = list._root; + + // New origin might require creating a higher root. + var offsetShift = 0; + while (newOrigin + offsetShift < 0) { + newRoot = new VNode(newRoot && newRoot.array.length ? [undefined, newRoot] : [], owner); + newLevel += SHIFT; + offsetShift += 1 << newLevel; } - var newSize = this.size; - var head = this._head; - iter.reverse().forEach((function(value) { - newSize++; - head = { - value: value, - next: head - }; - })); - if (this.__ownerID) { - this.size = newSize; - this._head = head; - this.__hash = undefined; - this.__altered = true; - return this; + if (offsetShift) { + newOrigin += offsetShift; + oldOrigin += offsetShift; + newCapacity += offsetShift; + oldCapacity += offsetShift; } - return makeStack(newSize, head); - }, - pop: function() { - return this.slice(1); - }, - unshift: function() { - return this.push.apply(this, arguments); - }, - unshiftAll: function(iter) { - return this.pushAll(iter); - }, - shift: function() { - return this.pop.apply(this, arguments); - }, - clear: function() { - if (this.size === 0) { - return this; + + var oldTailOffset = getTailOffset(oldCapacity); + var newTailOffset = getTailOffset(newCapacity); + + // New size might require creating a higher root. + while (newTailOffset >= 1 << (newLevel + SHIFT)) { + newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner); + newLevel += SHIFT; } - if (this.__ownerID) { - this.size = 0; - this._head = undefined; - this.__hash = undefined; - this.__altered = true; - return this; + + // Locate or create the new tail. + var oldTail = list._tail; + var newTail = newTailOffset < oldTailOffset ? + listNodeFor(list, newCapacity - 1) : + newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail; + + // Merge Tail into tree. + if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) { + newRoot = editableVNode(newRoot, owner); + var node = newRoot; + for (var level = newLevel; level > SHIFT; level -= SHIFT) { + var idx = (oldTailOffset >>> level) & MASK; + node = node.array[idx] = editableVNode(node.array[idx], owner); + } + node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail; } - return emptyStack(); - }, - slice: function(begin, end) { - if (wholeSlice(begin, end, this.size)) { - return this; + + // If the size has been reduced, there's a chance the tail needs to be trimmed. + if (newCapacity < oldCapacity) { + newTail = newTail && newTail.removeAfter(owner, 0, newCapacity); } - var resolvedBegin = resolveBegin(begin, this.size); - var resolvedEnd = resolveEnd(end, this.size); - if (resolvedEnd !== this.size) { - return $traceurRuntime.superCall(this, $Stack.prototype, "slice", [begin, end]); + + // If the new origin is within the tail, then we do not need a root. + if (newOrigin >= newTailOffset) { + newOrigin -= newTailOffset; + newCapacity -= newTailOffset; + newLevel = SHIFT; + newRoot = null; + newTail = newTail && newTail.removeBefore(owner, 0, newOrigin); + + // Otherwise, if the root has been trimmed, garbage collect. + } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) { + offsetShift = 0; + + // Identify the new top root node of the subtree of the old root. + while (newRoot) { + var beginIndex = (newOrigin >>> newLevel) & MASK; + if (beginIndex !== (newTailOffset >>> newLevel) & MASK) { + break; + } + if (beginIndex) { + offsetShift += (1 << newLevel) * beginIndex; + } + newLevel -= SHIFT; + newRoot = newRoot.array[beginIndex]; + } + + // Trim the new sides of the new root. + if (newRoot && newOrigin > oldOrigin) { + newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift); + } + if (newRoot && newTailOffset < oldTailOffset) { + newRoot = newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift); + } + if (offsetShift) { + newOrigin -= offsetShift; + newCapacity -= offsetShift; + } } - var newSize = this.size - resolvedBegin; - var head = this._head; - while (resolvedBegin--) { - head = head.next; + + if (list.__ownerID) { + list.size = newCapacity - newOrigin; + list._origin = newOrigin; + list._capacity = newCapacity; + list._level = newLevel; + list._root = newRoot; + list._tail = newTail; + list.__hash = undefined; + list.__altered = true; + return list; } - if (this.__ownerID) { - this.size = newSize; - this._head = head; - this.__hash = undefined; - this.__altered = true; - return this; + return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail); + } + + function mergeIntoListWith(list, merger, iterables) { + var iters = []; + var maxSize = 0; + for (var ii = 0; ii < iterables.length; ii++) { + var value = iterables[ii]; + var iter = IndexedIterable(value); + if (iter.size > maxSize) { + maxSize = iter.size; + } + if (!isIterable(value)) { + iter = iter.map(function(v ) {return fromJS(v)}); + } + iters.push(iter); } - return makeStack(newSize, head); - }, - __ensureOwner: function(ownerID) { - if (ownerID === this.__ownerID) { - return this; + if (maxSize > list.size) { + list = list.setSize(maxSize); } - if (!ownerID) { - this.__ownerID = ownerID; - this.__altered = false; - return this; + return mergeIntoCollectionWith(list, merger, iters); + } + + function getTailOffset(size) { + return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT); + } + + createClass(OrderedMap, Map); + + // @pragma Construction + + function OrderedMap(value) { + return value === null || value === undefined ? emptyOrderedMap() : + isOrderedMap(value) ? value : + emptyOrderedMap().withMutations(function(map ) { + var iter = KeyedIterable(value); + assertNotInfinite(iter.size); + iter.forEach(function(v, k) {return map.set(k, v)}); + }); } - return makeStack(this.size, this._head, ownerID, this.__hash); - }, - __iterate: function(fn, reverse) { - if (reverse) { - return this.toSeq().cacheResult.__iterate(fn, reverse); - } - var iterations = 0; - var node = this._head; - while (node) { - if (fn(node.value, iterations++, this) === false) { - break; + + OrderedMap.of = function(/*...values*/) { + return this(arguments); + }; + + OrderedMap.prototype.toString = function() { + return this.__toString('OrderedMap {', '}'); + }; + + // @pragma Access + + OrderedMap.prototype.get = function(k, notSetValue) { + var index = this._map.get(k); + return index !== undefined ? this._list.get(index)[1] : notSetValue; + }; + + // @pragma Modification + + OrderedMap.prototype.clear = function() { + if (this.size === 0) { + return this; } - node = node.next; - } - return iterations; - }, - __iterator: function(type, reverse) { - if (reverse) { - return this.toSeq().cacheResult().__iterator(type, reverse); - } - var iterations = 0; - var node = this._head; - return new Iterator((function() { - if (node) { - var value = node.value; - node = node.next; - return iteratorValue(type, iterations++, value); + if (this.__ownerID) { + this.size = 0; + this._map.clear(); + this._list.clear(); + return this; } - return iteratorDone(); - })); + return emptyOrderedMap(); + }; + + OrderedMap.prototype.set = function(k, v) { + return updateOrderedMap(this, k, v); + }; + + OrderedMap.prototype.remove = function(k) { + return updateOrderedMap(this, k, NOT_SET); + }; + + OrderedMap.prototype.wasAltered = function() { + return this._map.wasAltered() || this._list.wasAltered(); + }; + + OrderedMap.prototype.__iterate = function(fn, reverse) {var this$0 = this; + return this._list.__iterate( + function(entry ) {return entry && fn(entry[1], entry[0], this$0)}, + reverse + ); + }; + + OrderedMap.prototype.__iterator = function(type, reverse) { + return this._list.fromEntrySeq().__iterator(type, reverse); + }; + + OrderedMap.prototype.__ensureOwner = function(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + var newMap = this._map.__ensureOwner(ownerID); + var newList = this._list.__ensureOwner(ownerID); + if (!ownerID) { + this.__ownerID = ownerID; + this._map = newMap; + this._list = newList; + return this; + } + return makeOrderedMap(newMap, newList, ownerID, this.__hash); + }; + + + function isOrderedMap(maybeOrderedMap) { + return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap); } -}, {of: function() { - return this(arguments); - }}, IndexedCollection); -function isStack(maybeStack) { - return !!(maybeStack && maybeStack[IS_STACK_SENTINEL]); -} -Stack.isStack = isStack; -var IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@'; -var StackPrototype = Stack.prototype; -StackPrototype[IS_STACK_SENTINEL] = true; -StackPrototype.withMutations = MapPrototype.withMutations; -StackPrototype.asMutable = MapPrototype.asMutable; -StackPrototype.asImmutable = MapPrototype.asImmutable; -StackPrototype.wasAltered = MapPrototype.wasAltered; -function makeStack(size, head, ownerID, hash) { - var map = Object.create(StackPrototype); - map.size = size; - map._head = head; - map.__ownerID = ownerID; - map.__hash = hash; - map.__altered = false; - return map; -} -var EMPTY_STACK; -function emptyStack() { - return EMPTY_STACK || (EMPTY_STACK = makeStack(0)); -} -var Set = function Set(value) { - return value === null || value === undefined ? emptySet() : isSet(value) ? value : emptySet().union(SetIterable(value)); -}; -($traceurRuntime.createClass)(Set, { - toString: function() { - return this.__toString('Set {', '}'); - }, - has: function(value) { - return this._map.has(value); - }, - add: function(value) { - return updateSet(this, this._map.set(value, true)); - }, - remove: function(value) { - return updateSet(this, this._map.remove(value)); - }, - clear: function() { - return updateSet(this, this._map.clear()); - }, - union: function() { - var iters = arguments; - if (iters.length === 0) { - return this; - } - return this.withMutations((function(set) { - for (var ii = 0; ii < iters.length; ii++) { - SetIterable(iters[ii]).forEach((function(value) { - return set.add(value); - })); + + OrderedMap.isOrderedMap = isOrderedMap; + + OrderedMap.prototype[IS_ORDERED_SENTINEL] = true; + OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove; + + + + function makeOrderedMap(map, list, ownerID, hash) { + var omap = Object.create(OrderedMap.prototype); + omap.size = map ? map.size : 0; + omap._map = map; + omap._list = list; + omap.__ownerID = ownerID; + omap.__hash = hash; + return omap; + } + + var EMPTY_ORDERED_MAP; + function emptyOrderedMap() { + return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList())); + } + + function updateOrderedMap(omap, k, v) { + var map = omap._map; + var list = omap._list; + var i = map.get(k); + var has = i !== undefined; + var newMap; + var newList; + if (v === NOT_SET) { // removed + if (!has) { + return omap; } - })); - }, - intersect: function() { - for (var iters = [], - $__7 = 0; $__7 < arguments.length; $__7++) - iters[$__7] = arguments[$__7]; - if (iters.length === 0) { - return this; - } - iters = iters.map((function(iter) { - return SetIterable(iter); - })); - var originalSet = this; - return this.withMutations((function(set) { - originalSet.forEach((function(value) { - if (!iters.every((function(iter) { - return iter.contains(value); - }))) { - set.remove(value); + if (list.size >= SIZE && list.size >= map.size * 2) { + newList = list.filter(function(entry, idx) {return entry !== undefined && i !== idx}); + newMap = newList.toKeyedSeq().map(function(entry ) {return entry[0]}).flip().toMap(); + if (omap.__ownerID) { + newMap.__ownerID = newList.__ownerID = omap.__ownerID; } - })); - })); - }, - subtract: function() { - for (var iters = [], - $__8 = 0; $__8 < arguments.length; $__8++) - iters[$__8] = arguments[$__8]; - if (iters.length === 0) { - return this; - } - iters = iters.map((function(iter) { - return SetIterable(iter); - })); - var originalSet = this; - return this.withMutations((function(set) { - originalSet.forEach((function(value) { - if (iters.some((function(iter) { - return iter.contains(value); - }))) { - set.remove(value); + } else { + newMap = map.remove(k); + newList = i === list.size - 1 ? list.pop() : list.set(i, undefined); + } + } else { + if (has) { + if (v === list.get(i)[1]) { + return omap; } - })); - })); - }, - merge: function() { - return this.union.apply(this, arguments); - }, - mergeWith: function(merger) { - for (var iters = [], - $__9 = 1; $__9 < arguments.length; $__9++) - iters[$__9 - 1] = arguments[$__9]; - return this.union.apply(this, iters); - }, - sort: function(comparator) { - return OrderedSet(sortFactory(this, comparator)); - }, - sortBy: function(mapper, comparator) { - return OrderedSet(sortFactory(this, comparator, mapper)); - }, - wasAltered: function() { - return this._map.wasAltered(); - }, - __iterate: function(fn, reverse) { - var $__0 = this; - return this._map.__iterate((function(_, k) { - return fn(k, k, $__0); - }), reverse); - }, - __iterator: function(type, reverse) { - return this._map.map((function(_, k) { - return k; - })).__iterator(type, reverse); - }, - __ensureOwner: function(ownerID) { - if (ownerID === this.__ownerID) { - return this; + newMap = map; + newList = list.set(i, [k, v]); + } else { + newMap = map.set(k, list.size); + newList = list.set(list.size, [k, v]); + } } - var newMap = this._map.__ensureOwner(ownerID); - if (!ownerID) { - this.__ownerID = ownerID; - this._map = newMap; - return this; + if (omap.__ownerID) { + omap.size = newMap.size; + omap._map = newMap; + omap._list = newList; + omap.__hash = undefined; + return omap; } - return this.__make(newMap, ownerID); + return makeOrderedMap(newMap, newList); } -}, { - of: function() { - return this(arguments); - }, - fromKeys: function(value) { - return this(KeyedIterable(value).keySeq()); + + createClass(Stack, IndexedCollection); + + // @pragma Construction + + function Stack(value) { + return value === null || value === undefined ? emptyStack() : + isStack(value) ? value : + emptyStack().unshiftAll(value); + } + + Stack.of = function(/*...values*/) { + return this(arguments); + }; + + Stack.prototype.toString = function() { + return this.__toString('Stack [', ']'); + }; + + // @pragma Access + + Stack.prototype.get = function(index, notSetValue) { + var head = this._head; + while (head && index--) { + head = head.next; + } + return head ? head.value : notSetValue; + }; + + Stack.prototype.peek = function() { + return this._head && this._head.value; + }; + + // @pragma Modification + + Stack.prototype.push = function(/*...values*/) { + if (arguments.length === 0) { + return this; + } + var newSize = this.size + arguments.length; + var head = this._head; + for (var ii = arguments.length - 1; ii >= 0; ii--) { + head = { + value: arguments[ii], + next: head + }; + } + if (this.__ownerID) { + this.size = newSize; + this._head = head; + this.__hash = undefined; + this.__altered = true; + return this; + } + return makeStack(newSize, head); + }; + + Stack.prototype.pushAll = function(iter) { + iter = IndexedIterable(iter); + if (iter.size === 0) { + return this; + } + assertNotInfinite(iter.size); + var newSize = this.size; + var head = this._head; + iter.reverse().forEach(function(value ) { + newSize++; + head = { + value: value, + next: head + }; + }); + if (this.__ownerID) { + this.size = newSize; + this._head = head; + this.__hash = undefined; + this.__altered = true; + return this; + } + return makeStack(newSize, head); + }; + + Stack.prototype.pop = function() { + return this.slice(1); + }; + + Stack.prototype.unshift = function(/*...values*/) { + return this.push.apply(this, arguments); + }; + + Stack.prototype.unshiftAll = function(iter) { + return this.pushAll(iter); + }; + + Stack.prototype.shift = function() { + return this.pop.apply(this, arguments); + }; + + Stack.prototype.clear = function() { + if (this.size === 0) { + return this; + } + if (this.__ownerID) { + this.size = 0; + this._head = undefined; + this.__hash = undefined; + this.__altered = true; + return this; + } + return emptyStack(); + }; + + Stack.prototype.slice = function(begin, end) { + if (wholeSlice(begin, end, this.size)) { + return this; + } + var resolvedBegin = resolveBegin(begin, this.size); + var resolvedEnd = resolveEnd(end, this.size); + if (resolvedEnd !== this.size) { + // super.slice(begin, end); + return IndexedCollection.prototype.slice.call(this, begin, end); + } + var newSize = this.size - resolvedBegin; + var head = this._head; + while (resolvedBegin--) { + head = head.next; + } + if (this.__ownerID) { + this.size = newSize; + this._head = head; + this.__hash = undefined; + this.__altered = true; + return this; + } + return makeStack(newSize, head); + }; + + // @pragma Mutability + + Stack.prototype.__ensureOwner = function(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + if (!ownerID) { + this.__ownerID = ownerID; + this.__altered = false; + return this; + } + return makeStack(this.size, this._head, ownerID, this.__hash); + }; + + // @pragma Iteration + + Stack.prototype.__iterate = function(fn, reverse) { + if (reverse) { + return this.toSeq().cacheResult.__iterate(fn, reverse); + } + var iterations = 0; + var node = this._head; + while (node) { + if (fn(node.value, iterations++, this) === false) { + break; + } + node = node.next; + } + return iterations; + }; + + Stack.prototype.__iterator = function(type, reverse) { + if (reverse) { + return this.toSeq().cacheResult().__iterator(type, reverse); + } + var iterations = 0; + var node = this._head; + return new Iterator(function() { + if (node) { + var value = node.value; + node = node.next; + return iteratorValue(type, iterations++, value); + } + return iteratorDone(); + }); + }; + + + function isStack(maybeStack) { + return !!(maybeStack && maybeStack[IS_STACK_SENTINEL]); } -}, SetCollection); -function isSet(maybeSet) { - return !!(maybeSet && maybeSet[IS_SET_SENTINEL]); -} -Set.isSet = isSet; -var IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@'; -var SetPrototype = Set.prototype; -SetPrototype[IS_SET_SENTINEL] = true; -SetPrototype[DELETE] = SetPrototype.remove; -SetPrototype.mergeDeep = SetPrototype.merge; -SetPrototype.mergeDeepWith = SetPrototype.mergeWith; -SetPrototype.withMutations = MapPrototype.withMutations; -SetPrototype.asMutable = MapPrototype.asMutable; -SetPrototype.asImmutable = MapPrototype.asImmutable; -SetPrototype.__empty = emptySet; -SetPrototype.__make = makeSet; -function updateSet(set, newMap) { - if (set.__ownerID) { - set.size = newMap.size; - set._map = newMap; - return set; + + Stack.isStack = isStack; + + var IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@'; + + var StackPrototype = Stack.prototype; + StackPrototype[IS_STACK_SENTINEL] = true; + StackPrototype.withMutations = MapPrototype.withMutations; + StackPrototype.asMutable = MapPrototype.asMutable; + StackPrototype.asImmutable = MapPrototype.asImmutable; + StackPrototype.wasAltered = MapPrototype.wasAltered; + + + function makeStack(size, head, ownerID, hash) { + var map = Object.create(StackPrototype); + map.size = size; + map._head = head; + map.__ownerID = ownerID; + map.__hash = hash; + map.__altered = false; + return map; } - return newMap === set._map ? set : newMap.size === 0 ? set.__empty() : set.__make(newMap); -} -function makeSet(map, ownerID) { - var set = Object.create(SetPrototype); - set.size = map ? map.size : 0; - set._map = map; - set.__ownerID = ownerID; - return set; -} -var EMPTY_SET; -function emptySet() { - return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap())); -} -var OrderedSet = function OrderedSet(value) { - return value === null || value === undefined ? emptyOrderedSet() : isOrderedSet(value) ? value : emptyOrderedSet().union(SetIterable(value)); -}; -($traceurRuntime.createClass)(OrderedSet, {toString: function() { - return this.__toString('OrderedSet {', '}'); - }}, { - of: function() { - return this(arguments); - }, - fromKeys: function(value) { - return this(KeyedIterable(value).keySeq()); + + var EMPTY_STACK; + function emptyStack() { + return EMPTY_STACK || (EMPTY_STACK = makeStack(0)); } -}, Set); -function isOrderedSet(maybeOrderedSet) { - return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet); -} -OrderedSet.isOrderedSet = isOrderedSet; -var OrderedSetPrototype = OrderedSet.prototype; -OrderedSetPrototype[IS_ORDERED_SENTINEL] = true; -OrderedSetPrototype.__empty = emptyOrderedSet; -OrderedSetPrototype.__make = makeOrderedSet; -function makeOrderedSet(map, ownerID) { - var set = Object.create(OrderedSetPrototype); - set.size = map ? map.size : 0; - set._map = map; - set.__ownerID = ownerID; - return set; -} -var EMPTY_ORDERED_SET; -function emptyOrderedSet() { - return EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap())); -} -var Record = function Record(defaultValues, name) { - var RecordType = function Record(values) { - if (!(this instanceof RecordType)) { - return new RecordType(values); + + createClass(Set, SetCollection); + + // @pragma Construction + + function Set(value) { + return value === null || value === undefined ? emptySet() : + isSet(value) ? value : + emptySet().withMutations(function(set ) { + var iter = SetIterable(value); + assertNotInfinite(iter.size); + iter.forEach(function(v ) {return set.add(v)}); + }); } - this._map = Map(values); - }; - var keys = Object.keys(defaultValues); - var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype); - RecordTypePrototype.constructor = RecordType; - name && (RecordTypePrototype._name = name); - RecordTypePrototype._defaultValues = defaultValues; - RecordTypePrototype._keys = keys; - RecordTypePrototype.size = keys.length; - try { - keys.forEach((function(key) { - Object.defineProperty(RecordType.prototype, key, { - get: function() { - return this.get(key); - }, - set: function(value) { - invariant(this.__ownerID, 'Cannot set on an immutable record.'); - this.set(key, value); + + Set.of = function(/*...values*/) { + return this(arguments); + }; + + Set.fromKeys = function(value) { + return this(KeyedIterable(value).keySeq()); + }; + + Set.prototype.toString = function() { + return this.__toString('Set {', '}'); + }; + + // @pragma Access + + Set.prototype.has = function(value) { + return this._map.has(value); + }; + + // @pragma Modification + + Set.prototype.add = function(value) { + return updateSet(this, this._map.set(value, true)); + }; + + Set.prototype.remove = function(value) { + return updateSet(this, this._map.remove(value)); + }; + + Set.prototype.clear = function() { + return updateSet(this, this._map.clear()); + }; + + // @pragma Composition + + Set.prototype.union = function() {var iters = SLICE$0.call(arguments, 0); + iters = iters.filter(function(x ) {return x.size !== 0}); + if (iters.length === 0) { + return this; + } + if (this.size === 0 && iters.length === 1) { + return this.constructor(iters[0]); + } + return this.withMutations(function(set ) { + for (var ii = 0; ii < iters.length; ii++) { + SetIterable(iters[ii]).forEach(function(value ) {return set.add(value)}); } }); - })); - } catch (error) {} - return RecordType; -}; -($traceurRuntime.createClass)(Record, { - toString: function() { - return this.__toString(recordName(this) + ' {', '}'); - }, - has: function(k) { - return this._defaultValues.hasOwnProperty(k); - }, - get: function(k, notSetValue) { - if (!this.has(k)) { - return notSetValue; + }; + + Set.prototype.intersect = function() {var iters = SLICE$0.call(arguments, 0); + if (iters.length === 0) { + return this; + } + iters = iters.map(function(iter ) {return SetIterable(iter)}); + var originalSet = this; + return this.withMutations(function(set ) { + originalSet.forEach(function(value ) { + if (!iters.every(function(iter ) {return iter.contains(value)})) { + set.remove(value); + } + }); + }); + }; + + Set.prototype.subtract = function() {var iters = SLICE$0.call(arguments, 0); + if (iters.length === 0) { + return this; + } + iters = iters.map(function(iter ) {return SetIterable(iter)}); + var originalSet = this; + return this.withMutations(function(set ) { + originalSet.forEach(function(value ) { + if (iters.some(function(iter ) {return iter.contains(value)})) { + set.remove(value); + } + }); + }); + }; + + Set.prototype.merge = function() { + return this.union.apply(this, arguments); + }; + + Set.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); + return this.union.apply(this, iters); + }; + + Set.prototype.sort = function(comparator) { + // Late binding + return OrderedSet(sortFactory(this, comparator)); + }; + + Set.prototype.sortBy = function(mapper, comparator) { + // Late binding + return OrderedSet(sortFactory(this, comparator, mapper)); + }; + + Set.prototype.wasAltered = function() { + return this._map.wasAltered(); + }; + + Set.prototype.__iterate = function(fn, reverse) {var this$0 = this; + return this._map.__iterate(function(_, k) {return fn(k, k, this$0)}, reverse); + }; + + Set.prototype.__iterator = function(type, reverse) { + return this._map.map(function(_, k) {return k}).__iterator(type, reverse); + }; + + Set.prototype.__ensureOwner = function(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + var newMap = this._map.__ensureOwner(ownerID); + if (!ownerID) { + this.__ownerID = ownerID; + this._map = newMap; + return this; + } + return this.__make(newMap, ownerID); + }; + + + function isSet(maybeSet) { + return !!(maybeSet && maybeSet[IS_SET_SENTINEL]); + } + + Set.isSet = isSet; + + var IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@'; + + var SetPrototype = Set.prototype; + SetPrototype[IS_SET_SENTINEL] = true; + SetPrototype[DELETE] = SetPrototype.remove; + SetPrototype.mergeDeep = SetPrototype.merge; + SetPrototype.mergeDeepWith = SetPrototype.mergeWith; + SetPrototype.withMutations = MapPrototype.withMutations; + SetPrototype.asMutable = MapPrototype.asMutable; + SetPrototype.asImmutable = MapPrototype.asImmutable; + + SetPrototype.__empty = emptySet; + SetPrototype.__make = makeSet; + + function updateSet(set, newMap) { + if (set.__ownerID) { + set.size = newMap.size; + set._map = newMap; + return set; } - var defaultVal = this._defaultValues[k]; - return this._map ? this._map.get(k, defaultVal) : defaultVal; - }, - clear: function() { - if (this.__ownerID) { - this._map && this._map.clear(); - return this; + return newMap === set._map ? set : + newMap.size === 0 ? set.__empty() : + set.__make(newMap); + } + + function makeSet(map, ownerID) { + var set = Object.create(SetPrototype); + set.size = map ? map.size : 0; + set._map = map; + set.__ownerID = ownerID; + return set; + } + + var EMPTY_SET; + function emptySet() { + return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap())); + } + + createClass(OrderedSet, Set); + + // @pragma Construction + + function OrderedSet(value) { + return value === null || value === undefined ? emptyOrderedSet() : + isOrderedSet(value) ? value : + emptyOrderedSet().withMutations(function(set ) { + var iter = SetIterable(value); + assertNotInfinite(iter.size); + iter.forEach(function(v ) {return set.add(v)}); + }); } - var SuperRecord = Object.getPrototypeOf(this).constructor; - return SuperRecord._empty || (SuperRecord._empty = makeRecord(this, emptyMap())); - }, - set: function(k, v) { - if (!this.has(k)) { - throw new Error('Cannot set unknown key "' + k + '" on ' + recordName(this)); - } - var newMap = this._map && this._map.set(k, v); - if (this.__ownerID || newMap === this._map) { - return this; - } - return makeRecord(this, newMap); - }, - remove: function(k) { - if (!this.has(k)) { - return this; - } - var newMap = this._map && this._map.remove(k); - if (this.__ownerID || newMap === this._map) { - return this; - } - return makeRecord(this, newMap); - }, - wasAltered: function() { - return this._map.wasAltered(); - }, - __iterator: function(type, reverse) { - var $__0 = this; - return KeyedIterable(this._defaultValues).map((function(_, k) { - return $__0.get(k); - })).__iterator(type, reverse); - }, - __iterate: function(fn, reverse) { - var $__0 = this; - return KeyedIterable(this._defaultValues).map((function(_, k) { - return $__0.get(k); - })).__iterate(fn, reverse); - }, - __ensureOwner: function(ownerID) { - if (ownerID === this.__ownerID) { - return this; - } - var newMap = this._map && this._map.__ensureOwner(ownerID); - if (!ownerID) { - this.__ownerID = ownerID; - this._map = newMap; - return this; - } - return makeRecord(this, newMap, ownerID); + + OrderedSet.of = function(/*...values*/) { + return this(arguments); + }; + + OrderedSet.fromKeys = function(value) { + return this(KeyedIterable(value).keySeq()); + }; + + OrderedSet.prototype.toString = function() { + return this.__toString('OrderedSet {', '}'); + }; + + + function isOrderedSet(maybeOrderedSet) { + return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet); } -}, {}, KeyedCollection); -var RecordPrototype = Record.prototype; -RecordPrototype[DELETE] = RecordPrototype.remove; -RecordPrototype.merge = MapPrototype.merge; -RecordPrototype.mergeWith = MapPrototype.mergeWith; -RecordPrototype.mergeDeep = MapPrototype.mergeDeep; -RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith; -RecordPrototype.update = MapPrototype.update; -RecordPrototype.updateIn = MapPrototype.updateIn; -RecordPrototype.withMutations = MapPrototype.withMutations; -RecordPrototype.asMutable = MapPrototype.asMutable; -RecordPrototype.asImmutable = MapPrototype.asImmutable; -function makeRecord(likeRecord, map, ownerID) { - var record = Object.create(Object.getPrototypeOf(likeRecord)); - record._map = map; - record.__ownerID = ownerID; - return record; -} -function recordName(record) { - return record._name || record.constructor.name; -} -var Range = function Range(start, end, step) { - if (!(this instanceof $Range)) { - return new $Range(start, end, step); + + OrderedSet.isOrderedSet = isOrderedSet; + + var OrderedSetPrototype = OrderedSet.prototype; + OrderedSetPrototype[IS_ORDERED_SENTINEL] = true; + + OrderedSetPrototype.__empty = emptyOrderedSet; + OrderedSetPrototype.__make = makeOrderedSet; + + function makeOrderedSet(map, ownerID) { + var set = Object.create(OrderedSetPrototype); + set.size = map ? map.size : 0; + set._map = map; + set.__ownerID = ownerID; + return set; } - invariant(step !== 0, 'Cannot step a Range by 0'); - start = start || 0; - if (end === undefined) { - end = Infinity; + + var EMPTY_ORDERED_SET; + function emptyOrderedSet() { + return EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap())); } - if (start === end && __EMPTY_RANGE) { - return __EMPTY_RANGE; + + createClass(Record, KeyedCollection); + + function Record(defaultValues, name) { + var RecordType = function Record(values) { + if (!(this instanceof RecordType)) { + return new RecordType(values); + } + this._map = Map(values); + }; + + var keys = Object.keys(defaultValues); + + var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype); + RecordTypePrototype.constructor = RecordType; + name && (RecordTypePrototype._name = name); + RecordTypePrototype._defaultValues = defaultValues; + RecordTypePrototype._keys = keys; + RecordTypePrototype.size = keys.length; + + try { + keys.forEach(function(key ) { + Object.defineProperty(RecordType.prototype, key, { + get: function() { + return this.get(key); + }, + set: function(value) { + invariant(this.__ownerID, 'Cannot set on an immutable record.'); + this.set(key, value); + } + }); + }); + } catch (error) { + // Object.defineProperty failed. Probably IE8. + } + + return RecordType; + } + + Record.prototype.toString = function() { + return this.__toString(recordName(this) + ' {', '}'); + }; + + // @pragma Access + + Record.prototype.has = function(k) { + return this._defaultValues.hasOwnProperty(k); + }; + + Record.prototype.get = function(k, notSetValue) { + if (!this.has(k)) { + return notSetValue; + } + var defaultVal = this._defaultValues[k]; + return this._map ? this._map.get(k, defaultVal) : defaultVal; + }; + + // @pragma Modification + + Record.prototype.clear = function() { + if (this.__ownerID) { + this._map && this._map.clear(); + return this; + } + var SuperRecord = Object.getPrototypeOf(this).constructor; + return SuperRecord._empty || (SuperRecord._empty = makeRecord(this, emptyMap())); + }; + + Record.prototype.set = function(k, v) { + if (!this.has(k)) { + throw new Error('Cannot set unknown key "' + k + '" on ' + recordName(this)); + } + var newMap = this._map && this._map.set(k, v); + if (this.__ownerID || newMap === this._map) { + return this; + } + return makeRecord(this, newMap); + }; + + Record.prototype.remove = function(k) { + if (!this.has(k)) { + return this; + } + var newMap = this._map && this._map.remove(k); + if (this.__ownerID || newMap === this._map) { + return this; + } + return makeRecord(this, newMap); + }; + + Record.prototype.wasAltered = function() { + return this._map.wasAltered(); + }; + + Record.prototype.__iterator = function(type, reverse) {var this$0 = this; + return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterator(type, reverse); + }; + + Record.prototype.__iterate = function(fn, reverse) {var this$0 = this; + return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterate(fn, reverse); + }; + + Record.prototype.__ensureOwner = function(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + var newMap = this._map && this._map.__ensureOwner(ownerID); + if (!ownerID) { + this.__ownerID = ownerID; + this._map = newMap; + return this; + } + return makeRecord(this, newMap, ownerID); + }; + + + var RecordPrototype = Record.prototype; + RecordPrototype[DELETE] = RecordPrototype.remove; + RecordPrototype.deleteIn = + RecordPrototype.removeIn = MapPrototype.removeIn; + RecordPrototype.merge = MapPrototype.merge; + RecordPrototype.mergeWith = MapPrototype.mergeWith; + RecordPrototype.mergeIn = MapPrototype.mergeIn; + RecordPrototype.mergeDeep = MapPrototype.mergeDeep; + RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith; + RecordPrototype.mergeDeepIn = MapPrototype.mergeDeepIn; + RecordPrototype.setIn = MapPrototype.setIn; + RecordPrototype.update = MapPrototype.update; + RecordPrototype.updateIn = MapPrototype.updateIn; + RecordPrototype.withMutations = MapPrototype.withMutations; + RecordPrototype.asMutable = MapPrototype.asMutable; + RecordPrototype.asImmutable = MapPrototype.asImmutable; + + + function makeRecord(likeRecord, map, ownerID) { + var record = Object.create(Object.getPrototypeOf(likeRecord)); + record._map = map; + record.__ownerID = ownerID; + return record; } - step = step === undefined ? 1 : Math.abs(step); - if (end < start) { - step = -step; + + function recordName(record) { + return record._name || record.constructor.name; } - this._start = start; - this._end = end; - this._step = step; - this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1); -}; -var $Range = Range; -($traceurRuntime.createClass)(Range, { - toString: function() { - if (this.size === 0) { - return 'Range []'; + + function deepEqual(a, b) { + if (a === b) { + return true; } - return 'Range [ ' + this._start + '...' + this._end + (this._step > 1 ? ' by ' + this._step : '') + ' ]'; - }, - get: function(index, notSetValue) { - return this.has(index) ? this._start + wrapIndex(this, index) * this._step : notSetValue; - }, - contains: function(searchValue) { - var possibleIndex = (searchValue - this._start) / this._step; - return possibleIndex >= 0 && possibleIndex < this.size && possibleIndex === Math.floor(possibleIndex); - }, - slice: function(begin, end) { - if (wholeSlice(begin, end, this.size)) { - return this; + + if ( + !isIterable(b) || + a.size !== undefined && b.size !== undefined && a.size !== b.size || + a.__hash !== undefined && b.__hash !== undefined && a.__hash !== b.__hash || + isKeyed(a) !== isKeyed(b) || + isIndexed(a) !== isIndexed(b) || + isOrdered(a) !== isOrdered(b) + ) { + return false; } - begin = resolveBegin(begin, this.size); - end = resolveEnd(end, this.size); - if (end <= begin) { - return __EMPTY_RANGE; + + if (a.size === 0 && b.size === 0) { + return true; } - return new $Range(this.get(begin, this._end), this.get(end, this._end), this._step); - }, - indexOf: function(searchValue) { - var offsetValue = searchValue - this._start; - if (offsetValue % this._step === 0) { - var index = offsetValue / this._step; - if (index >= 0 && index < this.size) { - return index; + + var notAssociative = !isAssociative(a); + + if (isOrdered(a)) { + var entries = a.entries(); + return b.every(function(v, k) { + var entry = entries.next().value; + return entry && is(entry[1], v) && (notAssociative || is(entry[0], k)); + }) && entries.next().done; + } + + var flipped = false; + + if (a.size === undefined) { + if (b.size === undefined) { + a.cacheResult(); + } else { + flipped = true; + var _ = a; + a = b; + b = _; } } - return -1; - }, - lastIndexOf: function(searchValue) { - return this.indexOf(searchValue); - }, - take: function(amount) { - return this.slice(0, Math.max(0, amount)); - }, - skip: function(amount) { - return this.slice(Math.max(0, amount)); - }, - __iterate: function(fn, reverse) { - var maxIndex = this.size - 1; - var step = this._step; - var value = reverse ? this._start + maxIndex * step : this._start; - for (var ii = 0; ii <= maxIndex; ii++) { - if (fn(value, ii, this) === false) { - return ii + 1; + + var allEqual = true; + var bSize = b.__iterate(function(v, k) { + if (notAssociative ? !a.has(v) : + flipped ? !is(v, a.get(k, NOT_SET)) : !is(a.get(k, NOT_SET), v)) { + allEqual = false; + return false; } - value += reverse ? -step : step; + }); + + return allEqual && a.size === bSize; + } + + createClass(Range, IndexedSeq); + + function Range(start, end, step) { + if (!(this instanceof Range)) { + return new Range(start, end, step); + } + invariant(step !== 0, 'Cannot step a Range by 0'); + start = start || 0; + if (end === undefined) { + end = Infinity; + } + step = step === undefined ? 1 : Math.abs(step); + if (end < start) { + step = -step; + } + this._start = start; + this._end = end; + this._step = step; + this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1); + if (this.size === 0) { + if (EMPTY_RANGE) { + return EMPTY_RANGE; + } + EMPTY_RANGE = this; + } } - return ii; - }, - __iterator: function(type, reverse) { - var maxIndex = this.size - 1; - var step = this._step; - var value = reverse ? this._start + maxIndex * step : this._start; - var ii = 0; - return new Iterator((function() { - var v = value; - value += reverse ? -step : step; - return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v); - })); - }, - __deepEquals: function(other) { - return other instanceof $Range ? this._start === other._start && this._end === other._end && this._step === other._step : deepEqual(this, other); + + Range.prototype.toString = function() { + if (this.size === 0) { + return 'Range []'; + } + return 'Range [ ' + + this._start + '...' + this._end + + (this._step > 1 ? ' by ' + this._step : '') + + ' ]'; + }; + + Range.prototype.get = function(index, notSetValue) { + return this.has(index) ? + this._start + wrapIndex(this, index) * this._step : + notSetValue; + }; + + Range.prototype.contains = function(searchValue) { + var possibleIndex = (searchValue - this._start) / this._step; + return possibleIndex >= 0 && + possibleIndex < this.size && + possibleIndex === Math.floor(possibleIndex); + }; + + Range.prototype.slice = function(begin, end) { + if (wholeSlice(begin, end, this.size)) { + return this; + } + begin = resolveBegin(begin, this.size); + end = resolveEnd(end, this.size); + if (end <= begin) { + return new Range(0, 0); + } + return new Range(this.get(begin, this._end), this.get(end, this._end), this._step); + }; + + Range.prototype.indexOf = function(searchValue) { + var offsetValue = searchValue - this._start; + if (offsetValue % this._step === 0) { + var index = offsetValue / this._step; + if (index >= 0 && index < this.size) { + return index + } + } + return -1; + }; + + Range.prototype.lastIndexOf = function(searchValue) { + return this.indexOf(searchValue); + }; + + Range.prototype.__iterate = function(fn, reverse) { + var maxIndex = this.size - 1; + var step = this._step; + var value = reverse ? this._start + maxIndex * step : this._start; + for (var ii = 0; ii <= maxIndex; ii++) { + if (fn(value, ii, this) === false) { + return ii + 1; + } + value += reverse ? -step : step; + } + return ii; + }; + + Range.prototype.__iterator = function(type, reverse) { + var maxIndex = this.size - 1; + var step = this._step; + var value = reverse ? this._start + maxIndex * step : this._start; + var ii = 0; + return new Iterator(function() { + var v = value; + value += reverse ? -step : step; + return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v); + }); + }; + + Range.prototype.equals = function(other) { + return other instanceof Range ? + this._start === other._start && + this._end === other._end && + this._step === other._step : + deepEqual(this, other); + }; + + + var EMPTY_RANGE; + + createClass(Repeat, IndexedSeq); + + function Repeat(value, times) { + if (!(this instanceof Repeat)) { + return new Repeat(value, times); + } + this._value = value; + this.size = times === undefined ? Infinity : Math.max(0, times); + if (this.size === 0) { + if (EMPTY_REPEAT) { + return EMPTY_REPEAT; + } + EMPTY_REPEAT = this; + } + } + + Repeat.prototype.toString = function() { + if (this.size === 0) { + return 'Repeat []'; + } + return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]'; + }; + + Repeat.prototype.get = function(index, notSetValue) { + return this.has(index) ? this._value : notSetValue; + }; + + Repeat.prototype.contains = function(searchValue) { + return is(this._value, searchValue); + }; + + Repeat.prototype.slice = function(begin, end) { + var size = this.size; + return wholeSlice(begin, end, size) ? this : + new Repeat(this._value, resolveEnd(end, size) - resolveBegin(begin, size)); + }; + + Repeat.prototype.reverse = function() { + return this; + }; + + Repeat.prototype.indexOf = function(searchValue) { + if (is(this._value, searchValue)) { + return 0; + } + return -1; + }; + + Repeat.prototype.lastIndexOf = function(searchValue) { + if (is(this._value, searchValue)) { + return this.size; + } + return -1; + }; + + Repeat.prototype.__iterate = function(fn, reverse) { + for (var ii = 0; ii < this.size; ii++) { + if (fn(this._value, ii, this) === false) { + return ii + 1; + } + } + return ii; + }; + + Repeat.prototype.__iterator = function(type, reverse) {var this$0 = this; + var ii = 0; + return new Iterator(function() + {return ii < this$0.size ? iteratorValue(type, ii++, this$0._value) : iteratorDone()} + ); + }; + + Repeat.prototype.equals = function(other) { + return other instanceof Repeat ? + is(this._value, other._value) : + deepEqual(other); + }; + + + var EMPTY_REPEAT; + + /** + * Contributes additional methods to a constructor + */ + function mixin(ctor, methods) { + var keyCopier = function(key ) { ctor.prototype[key] = methods[key]; }; + Object.keys(methods).forEach(keyCopier); + Object.getOwnPropertySymbols && + Object.getOwnPropertySymbols(methods).forEach(keyCopier); + return ctor; } -}, {}, IndexedSeq); -var RangePrototype = Range.prototype; -RangePrototype.__toJS = RangePrototype.toArray; -RangePrototype.first = ListPrototype.first; -RangePrototype.last = ListPrototype.last; -var __EMPTY_RANGE = Range(0, 0); -var Repeat = function Repeat(value, times) { - if (times <= 0 && EMPTY_REPEAT) { - return EMPTY_REPEAT; + + Iterable.Iterator = Iterator; + + mixin(Iterable, { + + // ### Conversion to other types + + toArray: function() { + assertNotInfinite(this.size); + var array = new Array(this.size || 0); + this.valueSeq().__iterate(function(v, i) { array[i] = v; }); + return array; + }, + + toIndexedSeq: function() { + return new ToIndexedSequence(this); + }, + + toJS: function() { + return this.toSeq().map( + function(value ) {return value && typeof value.toJS === 'function' ? value.toJS() : value} + ).__toJS(); + }, + + toJSON: function() { + return this.toSeq().map( + function(value ) {return value && typeof value.toJSON === 'function' ? value.toJSON() : value} + ).__toJS(); + }, + + toKeyedSeq: function() { + return new ToKeyedSequence(this, true); + }, + + toMap: function() { + // Use Late Binding here to solve the circular dependency. + return Map(this.toKeyedSeq()); + }, + + toObject: function() { + assertNotInfinite(this.size); + var object = {}; + this.__iterate(function(v, k) { object[k] = v; }); + return object; + }, + + toOrderedMap: function() { + // Use Late Binding here to solve the circular dependency. + return OrderedMap(this.toKeyedSeq()); + }, + + toOrderedSet: function() { + // Use Late Binding here to solve the circular dependency. + return OrderedSet(isKeyed(this) ? this.valueSeq() : this); + }, + + toSet: function() { + // Use Late Binding here to solve the circular dependency. + return Set(isKeyed(this) ? this.valueSeq() : this); + }, + + toSetSeq: function() { + return new ToSetSequence(this); + }, + + toSeq: function() { + return isIndexed(this) ? this.toIndexedSeq() : + isKeyed(this) ? this.toKeyedSeq() : + this.toSetSeq(); + }, + + toStack: function() { + // Use Late Binding here to solve the circular dependency. + return Stack(isKeyed(this) ? this.valueSeq() : this); + }, + + toList: function() { + // Use Late Binding here to solve the circular dependency. + return List(isKeyed(this) ? this.valueSeq() : this); + }, + + + // ### Common JavaScript methods and properties + + toString: function() { + return '[Iterable]'; + }, + + __toString: function(head, tail) { + if (this.size === 0) { + return head + tail; + } + return head + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + tail; + }, + + + // ### ES6 Collection methods (ES6 Array and Map) + + concat: function() {var values = SLICE$0.call(arguments, 0); + return reify(this, concatFactory(this, values)); + }, + + contains: function(searchValue) { + return this.some(function(value ) {return is(value, searchValue)}); + }, + + entries: function() { + return this.__iterator(ITERATE_ENTRIES); + }, + + every: function(predicate, context) { + assertNotInfinite(this.size); + var returnValue = true; + this.__iterate(function(v, k, c) { + if (!predicate.call(context, v, k, c)) { + returnValue = false; + return false; + } + }); + return returnValue; + }, + + filter: function(predicate, context) { + return reify(this, filterFactory(this, predicate, context, true)); + }, + + find: function(predicate, context, notSetValue) { + var entry = this.findEntry(predicate, context); + return entry ? entry[1] : notSetValue; + }, + + findEntry: function(predicate, context) { + var found; + this.__iterate(function(v, k, c) { + if (predicate.call(context, v, k, c)) { + found = [k, v]; + return false; + } + }); + return found; + }, + + findLastEntry: function(predicate, context) { + return this.toSeq().reverse().findEntry(predicate, context); + }, + + forEach: function(sideEffect, context) { + assertNotInfinite(this.size); + return this.__iterate(context ? sideEffect.bind(context) : sideEffect); + }, + + join: function(separator) { + assertNotInfinite(this.size); + separator = separator !== undefined ? '' + separator : ','; + var joined = ''; + var isFirst = true; + this.__iterate(function(v ) { + isFirst ? (isFirst = false) : (joined += separator); + joined += v !== null && v !== undefined ? v : ''; + }); + return joined; + }, + + keys: function() { + return this.__iterator(ITERATE_KEYS); + }, + + map: function(mapper, context) { + return reify(this, mapFactory(this, mapper, context)); + }, + + reduce: function(reducer, initialReduction, context) { + assertNotInfinite(this.size); + var reduction; + var useFirst; + if (arguments.length < 2) { + useFirst = true; + } else { + reduction = initialReduction; + } + this.__iterate(function(v, k, c) { + if (useFirst) { + useFirst = false; + reduction = v; + } else { + reduction = reducer.call(context, reduction, v, k, c); + } + }); + return reduction; + }, + + reduceRight: function(reducer, initialReduction, context) { + var reversed = this.toKeyedSeq().reverse(); + return reversed.reduce.apply(reversed, arguments); + }, + + reverse: function() { + return reify(this, reverseFactory(this, true)); + }, + + slice: function(begin, end) { + return reify(this, sliceFactory(this, begin, end, true)); + }, + + some: function(predicate, context) { + return !this.every(not(predicate), context); + }, + + sort: function(comparator) { + return reify(this, sortFactory(this, comparator)); + }, + + values: function() { + return this.__iterator(ITERATE_VALUES); + }, + + + // ### More sequential methods + + butLast: function() { + return this.slice(0, -1); + }, + + isEmpty: function() { + return this.size !== undefined ? this.size === 0 : !this.some(function() {return true}); + }, + + count: function(predicate, context) { + return ensureSize( + predicate ? this.toSeq().filter(predicate, context) : this + ); + }, + + countBy: function(grouper, context) { + return countByFactory(this, grouper, context); + }, + + equals: function(other) { + return deepEqual(this, other); + }, + + entrySeq: function() { + var iterable = this; + if (iterable._cache) { + // We cache as an entries array, so we can just return the cache! + return new ArraySeq(iterable._cache); + } + var entriesSequence = iterable.toSeq().map(entryMapper).toIndexedSeq(); + entriesSequence.fromEntrySeq = function() {return iterable.toSeq()}; + return entriesSequence; + }, + + filterNot: function(predicate, context) { + return this.filter(not(predicate), context); + }, + + findLast: function(predicate, context, notSetValue) { + return this.toKeyedSeq().reverse().find(predicate, context, notSetValue); + }, + + first: function() { + return this.find(returnTrue); + }, + + flatMap: function(mapper, context) { + return reify(this, flatMapFactory(this, mapper, context)); + }, + + flatten: function(depth) { + return reify(this, flattenFactory(this, depth, true)); + }, + + fromEntrySeq: function() { + return new FromEntriesSequence(this); + }, + + get: function(searchKey, notSetValue) { + return this.find(function(_, key) {return is(key, searchKey)}, undefined, notSetValue); + }, + + getIn: function(searchKeyPath, notSetValue) { + var nested = this; + // Note: in an ES6 environment, we would prefer: + // for (var key of searchKeyPath) { + var iter = forceIterator(searchKeyPath); + var step; + while (!(step = iter.next()).done) { + var key = step.value; + nested = nested && nested.get ? nested.get(key, NOT_SET) : NOT_SET; + if (nested === NOT_SET) { + return notSetValue; + } + } + return nested; + }, + + groupBy: function(grouper, context) { + return groupByFactory(this, grouper, context); + }, + + has: function(searchKey) { + return this.get(searchKey, NOT_SET) !== NOT_SET; + }, + + hasIn: function(searchKeyPath) { + return this.getIn(searchKeyPath, NOT_SET) !== NOT_SET; + }, + + isSubset: function(iter) { + iter = typeof iter.contains === 'function' ? iter : Iterable(iter); + return this.every(function(value ) {return iter.contains(value)}); + }, + + isSuperset: function(iter) { + return iter.isSubset(this); + }, + + keySeq: function() { + return this.toSeq().map(keyMapper).toIndexedSeq(); + }, + + last: function() { + return this.toSeq().reverse().first(); + }, + + max: function(comparator) { + return maxFactory(this, comparator); + }, + + maxBy: function(mapper, comparator) { + return maxFactory(this, comparator, mapper); + }, + + min: function(comparator) { + return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator); + }, + + minBy: function(mapper, comparator) { + return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator, mapper); + }, + + rest: function() { + return this.slice(1); + }, + + skip: function(amount) { + return this.slice(Math.max(0, amount)); + }, + + skipLast: function(amount) { + return reify(this, this.toSeq().reverse().skip(amount).reverse()); + }, + + skipWhile: function(predicate, context) { + return reify(this, skipWhileFactory(this, predicate, context, true)); + }, + + skipUntil: function(predicate, context) { + return this.skipWhile(not(predicate), context); + }, + + sortBy: function(mapper, comparator) { + return reify(this, sortFactory(this, comparator, mapper)); + }, + + take: function(amount) { + return this.slice(0, Math.max(0, amount)); + }, + + takeLast: function(amount) { + return reify(this, this.toSeq().reverse().take(amount).reverse()); + }, + + takeWhile: function(predicate, context) { + return reify(this, takeWhileFactory(this, predicate, context)); + }, + + takeUntil: function(predicate, context) { + return this.takeWhile(not(predicate), context); + }, + + valueSeq: function() { + return this.toIndexedSeq(); + }, + + + // ### Hashable Object + + hashCode: function() { + return this.__hash || (this.__hash = hashIterable(this)); + }, + + + // ### Internal + + // abstract __iterate(fn, reverse) + + // abstract __iterator(type, reverse) + }); + + // var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; + // var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; + // var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@'; + // var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; + + var IterablePrototype = Iterable.prototype; + IterablePrototype[IS_ITERABLE_SENTINEL] = true; + IterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.values; + IterablePrototype.__toJS = IterablePrototype.toArray; + IterablePrototype.__toStringMapper = quoteString; + IterablePrototype.inspect = + IterablePrototype.toSource = function() { return this.toString(); }; + IterablePrototype.chain = IterablePrototype.flatMap; + + // Temporary warning about using length + (function () { + try { + Object.defineProperty(IterablePrototype, 'length', { + get: function () { + if (!Iterable.noLengthWarning) { + var stack; + try { + throw new Error(); + } catch (error) { + stack = error.stack; + } + if (stack.indexOf('_wrapObject') === -1) { + console && console.warn && console.warn( + 'iterable.length has been deprecated, '+ + 'use iterable.size or iterable.count(). '+ + 'This warning will become a silent error in a future version. ' + + stack + ); + return this.size; + } + } + } + }); + } catch (e) {} + })(); + + + + mixin(KeyedIterable, { + + // ### More sequential methods + + flip: function() { + return reify(this, flipFactory(this)); + }, + + findKey: function(predicate, context) { + var entry = this.findEntry(predicate, context); + return entry && entry[0]; + }, + + findLastKey: function(predicate, context) { + return this.toSeq().reverse().findKey(predicate, context); + }, + + keyOf: function(searchValue) { + return this.findKey(function(value ) {return is(value, searchValue)}); + }, + + lastKeyOf: function(searchValue) { + return this.findLastKey(function(value ) {return is(value, searchValue)}); + }, + + mapEntries: function(mapper, context) {var this$0 = this; + var iterations = 0; + return reify(this, + this.toSeq().map( + function(v, k) {return mapper.call(context, [k, v], iterations++, this$0)} + ).fromEntrySeq() + ); + }, + + mapKeys: function(mapper, context) {var this$0 = this; + return reify(this, + this.toSeq().flip().map( + function(k, v) {return mapper.call(context, k, v, this$0)} + ).flip() + ); + }, + + }); + + var KeyedIterablePrototype = KeyedIterable.prototype; + KeyedIterablePrototype[IS_KEYED_SENTINEL] = true; + KeyedIterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.entries; + KeyedIterablePrototype.__toJS = IterablePrototype.toObject; + KeyedIterablePrototype.__toStringMapper = function(v, k) {return k + ': ' + quoteString(v)}; + + + + mixin(IndexedIterable, { + + // ### Conversion to other types + + toKeyedSeq: function() { + return new ToKeyedSequence(this, false); + }, + + + // ### ES6 Collection methods (ES6 Array and Map) + + filter: function(predicate, context) { + return reify(this, filterFactory(this, predicate, context, false)); + }, + + findIndex: function(predicate, context) { + var entry = this.findEntry(predicate, context); + return entry ? entry[0] : -1; + }, + + indexOf: function(searchValue) { + var key = this.toKeyedSeq().keyOf(searchValue); + return key === undefined ? -1 : key; + }, + + lastIndexOf: function(searchValue) { + return this.toSeq().reverse().indexOf(searchValue); + }, + + reverse: function() { + return reify(this, reverseFactory(this, false)); + }, + + slice: function(begin, end) { + return reify(this, sliceFactory(this, begin, end, false)); + }, + + splice: function(index, removeNum /*, ...values*/) { + var numArgs = arguments.length; + removeNum = Math.max(removeNum | 0, 0); + if (numArgs === 0 || (numArgs === 2 && !removeNum)) { + return this; + } + index = resolveBegin(index, this.size); + var spliced = this.slice(0, index); + return reify( + this, + numArgs === 1 ? + spliced : + spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum)) + ); + }, + + + // ### More collection methods + + findLastIndex: function(predicate, context) { + var key = this.toKeyedSeq().findLastKey(predicate, context); + return key === undefined ? -1 : key; + }, + + first: function() { + return this.get(0); + }, + + flatten: function(depth) { + return reify(this, flattenFactory(this, depth, false)); + }, + + get: function(index, notSetValue) { + index = wrapIndex(this, index); + return (index < 0 || (this.size === Infinity || + (this.size !== undefined && index > this.size))) ? + notSetValue : + this.find(function(_, key) {return key === index}, undefined, notSetValue); + }, + + has: function(index) { + index = wrapIndex(this, index); + return index >= 0 && (this.size !== undefined ? + this.size === Infinity || index < this.size : + this.indexOf(index) !== -1 + ); + }, + + interpose: function(separator) { + return reify(this, interposeFactory(this, separator)); + }, + + interleave: function(/*...iterables*/) { + var iterables = [this].concat(arrCopy(arguments)); + var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, iterables); + var interleaved = zipped.flatten(true); + if (zipped.size) { + interleaved.size = zipped.size * iterables.length; + } + return reify(this, interleaved); + }, + + last: function() { + return this.get(-1); + }, + + skipWhile: function(predicate, context) { + return reify(this, skipWhileFactory(this, predicate, context, false)); + }, + + zip: function(/*, ...iterables */) { + var iterables = [this].concat(arrCopy(arguments)); + return reify(this, zipWithFactory(this, defaultZipper, iterables)); + }, + + zipWith: function(zipper/*, ...iterables */) { + var iterables = arrCopy(arguments); + iterables[0] = this; + return reify(this, zipWithFactory(this, zipper, iterables)); + }, + + }); + + IndexedIterable.prototype[IS_INDEXED_SENTINEL] = true; + IndexedIterable.prototype[IS_ORDERED_SENTINEL] = true; + + + + mixin(SetIterable, { + + // ### ES6 Collection methods (ES6 Array and Map) + + get: function(value, notSetValue) { + return this.has(value) ? value : notSetValue; + }, + + contains: function(value) { + return this.has(value); + }, + + + // ### More sequential methods + + keySeq: function() { + return this.valueSeq(); + }, + + }); + + SetIterable.prototype.has = IterablePrototype.contains; + + + // Mixin subclasses + + mixin(KeyedSeq, KeyedIterable.prototype); + mixin(IndexedSeq, IndexedIterable.prototype); + mixin(SetSeq, SetIterable.prototype); + + mixin(KeyedCollection, KeyedIterable.prototype); + mixin(IndexedCollection, IndexedIterable.prototype); + mixin(SetCollection, SetIterable.prototype); + + + // #pragma Helper functions + + function keyMapper(v, k) { + return k; } - if (!(this instanceof $Repeat)) { - return new $Repeat(value, times); + + function entryMapper(v, k) { + return [k, v]; } - this._value = value; - this.size = times === undefined ? Infinity : Math.max(0, times); - if (this.size === 0) { - EMPTY_REPEAT = this; + + function not(predicate) { + return function() { + return !predicate.apply(this, arguments); + } } -}; -var $Repeat = Repeat; -($traceurRuntime.createClass)(Repeat, { - toString: function() { - if (this.size === 0) { - return 'Repeat []'; + + function neg(predicate) { + return function() { + return -predicate.apply(this, arguments); } - return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]'; - }, - get: function(index, notSetValue) { - return this.has(index) ? this._value : notSetValue; - }, - contains: function(searchValue) { - return is(this._value, searchValue); - }, - slice: function(begin, end) { - var size = this.size; - return wholeSlice(begin, end, size) ? this : new $Repeat(this._value, resolveEnd(end, size) - resolveBegin(begin, size)); - }, - reverse: function() { - return this; - }, - indexOf: function(searchValue) { - if (is(this._value, searchValue)) { + } + + function quoteString(value) { + return typeof value === 'string' ? JSON.stringify(value) : value; + } + + function defaultZipper() { + return arrCopy(arguments); + } + + function defaultNegComparator(a, b) { + return a < b ? 1 : a > b ? -1 : 0; + } + + function hashIterable(iterable) { + if (iterable.size === Infinity) { return 0; } - return -1; - }, - lastIndexOf: function(searchValue) { - if (is(this._value, searchValue)) { - return this.size; - } - return -1; - }, - __iterate: function(fn, reverse) { - for (var ii = 0; ii < this.size; ii++) { - if (fn(this._value, ii, this) === false) { - return ii + 1; - } - } - return ii; - }, - __iterator: function(type, reverse) { - var $__0 = this; - var ii = 0; - return new Iterator((function() { - return ii < $__0.size ? iteratorValue(type, ii++, $__0._value) : iteratorDone(); - })); - }, - __deepEquals: function(other) { - return other instanceof $Repeat ? is(this._value, other._value) : deepEqual(other); + var ordered = isOrdered(iterable); + var keyed = isKeyed(iterable); + var h = ordered ? 1 : 0; + var size = iterable.__iterate( + keyed ? + ordered ? + function(v, k) { h = 31 * h + hashMerge(hash(v), hash(k)) | 0; } : + function(v, k) { h = h + hashMerge(hash(v), hash(k)) | 0; } : + ordered ? + function(v ) { h = 31 * h + hash(v) | 0; } : + function(v ) { h = h + hash(v) | 0; } + ); + return murmurHashOfSize(size, h); } -}, {}, IndexedSeq); -var RepeatPrototype = Repeat.prototype; -RepeatPrototype.last = RepeatPrototype.first; -RepeatPrototype.has = RangePrototype.has; -RepeatPrototype.take = RangePrototype.take; -RepeatPrototype.skip = RangePrototype.skip; -RepeatPrototype.__toJS = RangePrototype.__toJS; -var EMPTY_REPEAT; -var Immutable = { - Iterable: Iterable, - Seq: Seq, - Collection: Collection, - Map: Map, - OrderedMap: OrderedMap, - List: List, - Stack: Stack, - Set: Set, - OrderedSet: OrderedSet, - Record: Record, - Range: Range, - Repeat: Repeat, - is: is, - fromJS: fromJS -}; + function murmurHashOfSize(size, h) { + h = Math__imul(h, 0xCC9E2D51); + h = Math__imul(h << 15 | h >>> -15, 0x1B873593); + h = Math__imul(h << 13 | h >>> -13, 5); + h = (h + 0xE6546B64 | 0) ^ size; + h = Math__imul(h ^ h >>> 16, 0x85EBCA6B); + h = Math__imul(h ^ h >>> 13, 0xC2B2AE35); + h = smi(h ^ h >>> 16); + return h; + } + + function hashMerge(a, b) { + return a ^ b + 0x9E3779B9 + (a << 6) + (a >> 2) | 0; // int + } + + var Immutable = { + + Iterable: Iterable, + + Seq: Seq, + Collection: Collection, + Map: Map, + OrderedMap: OrderedMap, + List: List, + Stack: Stack, + Set: Set, + OrderedSet: OrderedSet, + + Record: Record, + Range: Range, + Repeat: Repeat, + + is: is, + fromJS: fromJS, + + }; + return Immutable; -} -typeof exports === 'object' ? module.exports = universalModule() : - typeof define === 'function' && define.amd ? define(universalModule) : - Immutable = universalModule(); +})); },{}],55:[function(require,module,exports){ var baseFlatten = require('../internals/baseFlatten'), map = require('../collections/map'); function flatten(array, isShallow, callback, thisArg) { if (typeof isShallow != 'boolean' && isShallow != null) { thisArg = callback; @@ -6663,13 +7708,13 @@ },{}],102:[function(require,module,exports){ 'use strict'; function Node(node) { this.node = node; } -Node.prototype.getAncestor = function (nodeFilter) { +Node.prototype.getAncestor = function (rootElement, nodeFilter) { var isTopContainerElement = function (element) { - return element && element.attributes && element.attributes.getNamedItem('contenteditable'); + return rootElement === element; }; if (isTopContainerElement(this.node)) { return; } var currentNode = this.node.parentNode; @@ -6693,55 +7738,81 @@ },{}],103:[function(require,module,exports){ var elementHelper = require('../element'); 'use strict'; module.exports = function (scribe) { function Selection() { - this.selection = window.getSelection(); + var rootDoc = document; + var currentElement = scribe.el.parentNode; + while (currentElement && currentElement.nodeType !== Node.DOCUMENT_FRAGMENT_NODE && currentElement.nodeType !== Node.DOCUMENT_NODE) { + currentElement = currentElement.parentNode; + } + if (currentElement && currentElement.nodeType === Node.DOCUMENT_FRAGMENT_NODE && currentElement.getSelection) { + rootDoc = currentElement; + } + this.selection = rootDoc.getSelection(); if (this.selection.rangeCount) { - this.range = this.selection.getRangeAt(0); + this.range = document.createRange(); + var reverseRange = document.createRange(); + this.range.setStart(this.selection.anchorNode, this.selection.anchorOffset); + reverseRange.setStart(this.selection.focusNode, this.selection.focusOffset); + if (this.range.compareBoundaryPoints(Range.START_TO_START, reverseRange) <= 0) { + this.range.setEnd(this.selection.focusNode, this.selection.focusOffset); + } else { + this.range = reverseRange; + this.range.setEnd(this.selection.anchorNode, this.selection.anchorOffset); + } } } Selection.prototype.getContaining = function (nodeFilter) { var range = this.range; if (!range) { return; } var node = new scribe.api.Node(this.range.commonAncestorContainer); - var isTopContainerElement = node.node && node.node.attributes && node.node.attributes.getNamedItem('contenteditable'); - return !isTopContainerElement && nodeFilter(node.node) ? node.node : node.getAncestor(nodeFilter); + var isTopContainerElement = node.node && scribe.el === node.node; + return !isTopContainerElement && nodeFilter(node.node) ? node.node : node.getAncestor(scribe.el, nodeFilter); }; Selection.prototype.placeMarkers = function () { var range = this.range; if (!range) { return; } - var startMarker = document.createElement('em'); - startMarker.classList.add('scribe-marker'); - var endMarker = document.createElement('em'); - endMarker.classList.add('scribe-marker'); - var rangeEnd = this.range.cloneRange(); - rangeEnd.collapse(false); - rangeEnd.insertNode(endMarker); - if (endMarker.nextSibling && endMarker.nextSibling.nodeType === Node.TEXT_NODE && endMarker.nextSibling.data === '') { - endMarker.parentNode.removeChild(endMarker.nextSibling); + if (!scribe.el.offsetParent) { + return; } - if (endMarker.previousSibling && endMarker.previousSibling.nodeType === Node.TEXT_NODE && endMarker.previousSibling.data === '') { - endMarker.parentNode.removeChild(endMarker.previousSibling); - } - if (!this.selection.isCollapsed) { - var rangeStart = this.range.cloneRange(); - rangeStart.collapse(true); - rangeStart.insertNode(startMarker); - if (startMarker.nextSibling && startMarker.nextSibling.nodeType === Node.TEXT_NODE && startMarker.nextSibling.data === '') { - startMarker.parentNode.removeChild(startMarker.nextSibling); + var scribeNodeRange = document.createRange(); + scribeNodeRange.selectNodeContents(scribe.el); + var selectionStartWithinScribeElementStart = this.range.compareBoundaryPoints(Range.START_TO_START, scribeNodeRange) >= 0; + var selectionEndWithinScribeElementEnd = this.range.compareBoundaryPoints(Range.END_TO_END, scribeNodeRange) <= 0; + if (selectionStartWithinScribeElementStart && selectionEndWithinScribeElementEnd) { + var startMarker = document.createElement('em'); + startMarker.classList.add('scribe-marker'); + var endMarker = document.createElement('em'); + endMarker.classList.add('scribe-marker'); + var rangeEnd = this.range.cloneRange(); + rangeEnd.collapse(false); + rangeEnd.insertNode(endMarker); + if (endMarker.nextSibling && endMarker.nextSibling.nodeType === Node.TEXT_NODE && endMarker.nextSibling.data === '') { + endMarker.parentNode.removeChild(endMarker.nextSibling); } - if (startMarker.previousSibling && startMarker.previousSibling.nodeType === Node.TEXT_NODE && startMarker.previousSibling.data === '') { - startMarker.parentNode.removeChild(startMarker.previousSibling); + if (endMarker.previousSibling && endMarker.previousSibling.nodeType === Node.TEXT_NODE && endMarker.previousSibling.data === '') { + endMarker.parentNode.removeChild(endMarker.previousSibling); } + if (!this.range.collapsed) { + var rangeStart = this.range.cloneRange(); + rangeStart.collapse(true); + rangeStart.insertNode(startMarker); + if (startMarker.nextSibling && startMarker.nextSibling.nodeType === Node.TEXT_NODE && startMarker.nextSibling.data === '') { + startMarker.parentNode.removeChild(startMarker.nextSibling); + } + if (startMarker.previousSibling && startMarker.previousSibling.nodeType === Node.TEXT_NODE && startMarker.previousSibling.data === '') { + startMarker.parentNode.removeChild(startMarker.previousSibling); + } + } + this.selection.removeAllRanges(); + this.selection.addRange(this.range); } - this.selection.removeAllRanges(); - this.selection.addRange(this.range); }; Selection.prototype.getMarkers = function () { return scribe.el.querySelectorAll('em.scribe-marker'); }; Selection.prototype.removeMarkers = function () { @@ -6768,11 +7839,11 @@ this.selection.removeAllRanges(); this.selection.addRange(newRange); }; Selection.prototype.isCaretOnNewLine = function () { function isEmptyInlineElement(node) { - var treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT); + var treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT, null, false); var currentNode = treeWalker.root; while (currentNode) { var numberOfChildren = currentNode.childNodes.length; if (numberOfChildren > 1 || numberOfChildren === 1 && currentNode.textContent.trim() !== '') return false; @@ -6798,18 +7869,18 @@ },{"../element":106}],104:[function(require,module,exports){ 'use strict'; module.exports = function (api, scribe) { function SimpleCommand(commandName, nodeName) { scribe.api.Command.call(this, commandName); - this.nodeName = nodeName; + this._nodeName = nodeName; } SimpleCommand.prototype = Object.create(api.Command.prototype); SimpleCommand.prototype.constructor = SimpleCommand; SimpleCommand.prototype.queryState = function () { var selection = new scribe.api.Selection(); return scribe.api.Command.prototype.queryState.call(this) && !!selection.getContaining(function (node) { - return node.nodeName === this.nodeName; + return node.nodeName === this._nodeName; }.bind(this)); }; return SimpleCommand; }; },{}],105:[function(require,module,exports){ @@ -6854,25 +7925,45 @@ module.exports = observeDomChanges; },{"./element":106,"./node":108,"lodash-amd/modern/arrays/flatten":55,"lodash-amd/modern/collections/toArray":60}],106:[function(require,module,exports){ var contains = require('lodash-amd/modern/collections/contains'); 'use strict'; var blockElementNames = [ - 'P', - 'LI', - 'DIV', + 'ADDRESS', + 'ARTICLE', + 'ASIDE', + 'AUDIO', 'BLOCKQUOTE', - 'UL', - 'OL', + 'CANVAS', + 'DD', + 'DIV', + 'FIELDSET', + 'FIGCAPTION', + 'FIGURE', + 'FOOTER', + 'FORM', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', + 'HEADER', + 'HGROUP', + 'HR', + 'LI', + 'NOSCRIPT', + 'OL', + 'OUTPUT', + 'P', + 'PRE', + 'SECTION', 'TABLE', + 'TD', 'TH', - 'TD' + 'TFOOT', + 'UL', + 'VIDEO' ]; function isBlockElement(node) { return contains(blockElementNames, node.nodeName); } function isSelectionMarkerNode(node) { @@ -6892,36 +7983,40 @@ isSelectionMarkerNode: isSelectionMarkerNode, isCaretPositionNode: isCaretPositionNode, unwrap: unwrap }; },{"lodash-amd/modern/collections/contains":58}],107:[function(require,module,exports){ -var pull = require('lodash-amd/modern/arrays/pull'); +var pull = require('lodash-amd/modern/arrays/pull'), Immutable = require('immutable/dist/immutable'); 'use strict'; function EventEmitter() { this._listeners = {}; } EventEmitter.prototype.on = function (eventName, fn) { - var listeners = this._listeners[eventName] || []; - listeners.push(fn); - this._listeners[eventName] = listeners; + var listeners = this._listeners[eventName] || Immutable.Set(); + this._listeners[eventName] = listeners.add(fn); }; EventEmitter.prototype.off = function (eventName, fn) { - var listeners = this._listeners[eventName] || []; + var listeners = this._listeners[eventName] || Immutable.Set(); if (fn) { - pull(listeners, fn); + listeners = listeners.delete(fn); } else { - delete this._listeners[eventName]; + listeners = listeners.clear(); } }; EventEmitter.prototype.trigger = function (eventName, args) { - var listeners = this._listeners[eventName] || []; - listeners.forEach(function (listener) { - listener.apply(null, args); - }); + var events = eventName.split(':'); + while (!!events.length) { + var currentEvent = events.join(':'); + var listeners = this._listeners[currentEvent] || Immutable.Set(); + listeners.forEach(function (listener) { + listener.apply(null, args); + }); + events.splice(events.length - 1, 1); + } }; module.exports = EventEmitter; -},{"lodash-amd/modern/arrays/pull":57}],108:[function(require,module,exports){ +},{"immutable/dist/immutable":54,"lodash-amd/modern/arrays/pull":57}],108:[function(require,module,exports){ 'use strict'; function isEmptyTextNode(node) { return node.nodeType === Node.TEXT_NODE && node.textContent === ''; } function insertAfter(newNode, referenceNode) { @@ -7064,16 +8159,18 @@ }; redoCommand.queryEnabled = function () { return scribe.undoManager.position < scribe.undoManager.stack.length - 1; }; scribe.commands.redo = redoCommand; - scribe.el.addEventListener('keydown', function (event) { - if (event.shiftKey && (event.metaKey || event.ctrlKey) && event.keyCode === 90) { - event.preventDefault(); - redoCommand.execute(); - } - }); + if (scribe.options.undo.enabled) { + scribe.el.addEventListener('keydown', function (event) { + if (event.shiftKey && (event.metaKey || event.ctrlKey) && event.keyCode === 90) { + event.preventDefault(); + redoCommand.execute(); + } + }); + } }; }; },{}],114:[function(require,module,exports){ 'use strict'; module.exports = function () { @@ -7103,16 +8200,18 @@ }; undoCommand.queryEnabled = function () { return scribe.undoManager.position > 1; }; scribe.commands.undo = undoCommand; - scribe.el.addEventListener('keydown', function (event) { - if (!event.shiftKey && (event.metaKey || event.ctrlKey) && event.keyCode === 90) { - event.preventDefault(); - undoCommand.execute(); - } - }); + if (scribe.options.undo.enabled) { + scribe.el.addEventListener('keydown', function (event) { + if (!event.shiftKey && (event.metaKey || event.ctrlKey) && event.keyCode === 90) { + event.preventDefault(); + undoCommand.execute(); + } + }); + } }; }; },{}],117:[function(require,module,exports){ var contains = require('lodash-amd/modern/collections/contains'), observeDomChanges = require('../../dom-observer'); 'use strict'; @@ -7137,11 +8236,11 @@ selection.selection.removeAllRanges(); selection.selection.addRange(range); } } function getFirstDeepestChild(node) { - var treeWalker = document.createTreeWalker(node); + var treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_ALL, null, false); var previousNode = treeWalker.currentNode; if (treeWalker.firstChild()) { if (treeWalker.currentNode.nodeName === 'BR') { return previousNode; } else { @@ -7162,11 +8261,13 @@ } scribe.setHTML(scribe._htmlFormatterFactory.format(scribe.getHTML())); selection.selectMarkers(); }.bind(scribe); if (isEditorActive) { - scribe.undoManager.undo(); + if (scribe.undoManager) { + scribe.undoManager.undo(); + } scribe.transactionManager.run(runFormatters); } else { runFormatters(); } } @@ -7283,11 +8384,11 @@ }); }); parentNode._isWrapped = true; } function traverse(scribe, parentNode) { - var treeWalker = document.createTreeWalker(parentNode, NodeFilter.SHOW_ELEMENT); + var treeWalker = document.createTreeWalker(parentNode, NodeFilter.SHOW_ELEMENT, null, false); var node = treeWalker.firstChild(); while (node) { if (node.nodeName === 'BLOCKQUOTE' && !node._isWrapped) { wrapChildNodes(scribe, node); traverse(scribe, parentNode); @@ -7386,11 +8487,11 @@ }; }; },{"lodash-amd/modern/utilities/escape":95}],122:[function(require,module,exports){ 'use strict'; function hasContent(rootNode) { - var treeWalker = document.createTreeWalker(rootNode); + var treeWalker = document.createTreeWalker(rootNode, NodeFilter.SHOW_ALL, null, false); while (treeWalker.nextNode()) { if (treeWalker.currentNode) { if (~['br'].indexOf(treeWalker.currentNode.nodeName.toLowerCase()) || treeWalker.currentNode.length > 0) { return true; } @@ -7472,11 +8573,11 @@ return function (scribe) { var createLinkCommand = new scribe.api.CommandPatch('createLink'); scribe.commandPatches.createLink = createLinkCommand; createLinkCommand.execute = function (value) { var selection = new scribe.api.Selection(); - if (selection.selection.isCollapsed) { + if (selection.range.collapsed) { var aElement = document.createElement('a'); aElement.setAttribute('href', value); aElement.textContent = value; selection.range.insertNode(aElement); var newRange = document.createRange(); @@ -7531,11 +8632,11 @@ insertHTMLCommandPatch.execute = function (value) { scribe.transactionManager.run(function () { scribe.api.CommandPatch.prototype.execute.call(this, value); sanitize(scribe.el); function sanitize(parentNode) { - var treeWalker = document.createTreeWalker(parentNode, NodeFilter.SHOW_ELEMENT); + var treeWalker = document.createTreeWalker(parentNode, NodeFilter.SHOW_ELEMENT, null, false); var node = treeWalker.firstChild(); if (!node) { return; } do { @@ -7674,11 +8775,13 @@ var selection = new scribe.api.Selection(); var containerPElement = selection.getContaining(function (node) { return node.nodeName === 'P'; }); if (containerPElement) { - scribe.undoManager.undo(); + if (scribe.undoManager) { + scribe.undoManager.undo(); + } scribe.transactionManager.run(function () { selection.placeMarkers(); var pElementChildNodes = Array.prototype.slice.call(containerPElement.childNodes); pElementChildNodes.forEach(function (pElementChildNode) { if (pElementChildNode.nodeName === 'SPAN') { @@ -7715,23 +8818,35 @@ EventEmitter.call(this); this.el = el; this.commands = {}; this.options = defaults(options || {}, { allowBlockElements: true, - debug: false + debug: false, + undo: { enabled: true }, + defaultCommandPatches: [ + 'bold', + 'indent', + 'insertHTML', + 'insertList', + 'outdent', + 'createLink' + ] }); this.commandPatches = {}; this._plainTextFormatterFactory = new FormatterFactory(); this._htmlFormatterFactory = new HTMLFormatterFactory(); this.api = new Api(this); this.node = nodeHelpers; this.element = elementHelpers; this.Immutable = Immutable; var TransactionManager = buildTransactionManager(this); this.transactionManager = new TransactionManager(); - var UndoManager = buildUndoManager(this); - this.undoManager = new UndoManager(); + this.undoManager = false; + if (this.options.undo.enabled) { + var UndoManager = buildUndoManager(this); + this.undoManager = new UndoManager(); + } this.el.setAttribute('contenteditable', true); this.el.addEventListener('input', function () { this.transactionManager.run(); }.bind(this), false); if (this.allowsBlockElements()) { @@ -7739,31 +8854,19 @@ this.use(enforcePElements()); this.use(ensureSelectableContainers()); } else { this.use(inlineElementsMode()); } - this.use(escapeHtmlCharactersFormatter()); - this.use(replaceNbspCharsFormatter()); - var mandatoryPatches = [ - patches.commands.bold, - patches.commands.indent, - patches.commands.insertHTML, - patches.commands.insertList, - patches.commands.outdent, - patches.commands.createLink, - patches.events - ]; - var mandatoryCommands = [ - commands.indent, - commands.insertList, - commands.outdent, - commands.redo, - commands.subscript, - commands.superscript, - commands.undo - ]; - var allPlugins = [].concat(mandatoryPatches, mandatoryCommands); + var defaultFormatters = Immutable.List.of(escapeHtmlCharactersFormatter, replaceNbspCharsFormatter); + var defaultPatches = Immutable.List.of(patches.events); + var defaultCommandPatches = Immutable.List(this.options.defaultCommandPatches).map(function (patch) { + return patches.commands[patch]; + }); + var defaultCommands = Immutable.List.of('indent', 'insertList', 'outdent', 'redo', 'subscript', 'superscript', 'undo').map(function (command) { + return commands[command]; + }); + var allPlugins = Immutable.List().concat(defaultFormatters, defaultPatches, defaultCommandPatches, defaultCommands); allPlugins.forEach(function (plugin) { this.use(plugin()); }.bind(this)); this.use(events()); } @@ -7774,11 +8877,13 @@ }; Scribe.prototype.setHTML = function (html, skipFormatters) { if (skipFormatters) { this._skipFormatters = true; } - this.el.innerHTML = html; + if (this.el.innerHTML !== html) { + this.el.innerHTML = html; + } }; Scribe.prototype.getHTML = function () { return this.el.innerHTML; }; Scribe.prototype.getContent = function () { @@ -7786,19 +8891,23 @@ }; Scribe.prototype.getTextContent = function () { return this.el.textContent; }; Scribe.prototype.pushHistory = function () { - var previousUndoItem = this.undoManager.stack[this.undoManager.position]; - var previousContent = previousUndoItem && previousUndoItem.replace(/<em class="scribe-marker">/g, '').replace(/<\/em>/g, ''); - if (!previousUndoItem || previousUndoItem && this.getHTML() !== previousContent) { - var selection = new this.api.Selection(); - selection.placeMarkers(); - var html = this.getHTML(); - selection.removeMarkers(); - this.undoManager.push(html); - return true; + if (this.options.undo.enabled) { + var previousUndoItem = this.undoManager.stack[this.undoManager.position]; + var previousContent = previousUndoItem && previousUndoItem.replace(/<em class="scribe-marker">/g, '').replace(/<\/em>/g, ''); + if (!previousUndoItem || previousUndoItem && this.getHTML() !== previousContent) { + var selection = new this.api.Selection(); + selection.placeMarkers(); + var html = this.getHTML(); + selection.removeMarkers(); + this.undoManager.push(html); + return true; + } else { + return false; + } } else { return false; } }; Scribe.prototype.getCommand = function (commandName) { @@ -7827,15 +8936,15 @@ this.getCommand('insertHTML').execute(this._htmlFormatterFactory.format(html)); }; Scribe.prototype.isDebugModeEnabled = function () { return this.options.debug; }; -Scribe.prototype.registerHTMLFormatter = function (phase, fn) { - this._htmlFormatterFactory.formatters[phase] = this._htmlFormatterFactory.formatters[phase].push(fn); +Scribe.prototype.registerHTMLFormatter = function (phase, formatter) { + this._htmlFormatterFactory.formatters[phase] = this._htmlFormatterFactory.formatters[phase].push(formatter); }; -Scribe.prototype.registerPlainTextFormatter = function (fn) { - this._plainTextFormatterFactory.formatters = this._plainTextFormatterFactory.formatters.push(fn); +Scribe.prototype.registerPlainTextFormatter = function (formatter) { + this._plainTextFormatterFactory.formatters = this._plainTextFormatterFactory.formatters.push(formatter); }; function FormatterFactory() { this.formatters = Immutable.List(); } FormatterFactory.prototype.format = function (html) { @@ -8103,21 +9212,10 @@ } return obj } /** - * Returns the absolute page-offset of the given element. - */ - function pos(el) { - var o = { x:el.offsetLeft, y:el.offsetTop } - while((el = el.offsetParent)) - o.x+=el.offsetLeft, o.y+=el.offsetTop - - return o - } - - /** * Returns the line color from the given string or array. */ function getColor(color, idx) { return typeof color == 'string' ? color : color[idx % color.length] } @@ -8163,11 +9261,10 @@ this.stop() var self = this , o = self.opts , el = self.el = css(createEl(0, {className: o.className}), {position: o.position, width: 0, zIndex: o.zIndex}) - , mid = o.radius+o.length+o.width css(el, { left: o.left, top: o.top }) @@ -8545,10 +9642,11 @@ this.mediator.trigger('block:render', block); this.triggerBlockCountUpdate(); this.mediator.trigger('block:limitReached', this.blockLimitReached()); + EventBus.trigger(data ? "block:create:existing" : "block:create:new", block); utils.log("Block created of type " + type); }, removeBlock: function(blockID) { var block = this.findBlockById(blockID), @@ -9146,11 +10244,11 @@ var input_html = $("<div>", { 'class': 'st-block__inputs' }); this.$inner.append(input_html); this.$inputs = input_html; } - if (this.hasTextBlock) { this._initTextBlocks(); } + if (this.hasTextBlock()) { this._initTextBlocks(); } this.availableMixins.forEach(function(mixin) { if (this[mixin]) { this.withMixin(BlockMixins[utils.classify(mixin)]); } @@ -9914,12 +11012,28 @@ editorHTML: '<div class="st-required st-text-block" contenteditable="true"></div>', icon_name: 'text', + markdownSupport: true, + + _serializeData: function() { + var data = Block.prototype._serializeData.apply(this); + + if (Object.keys(data).length && this.markdownSupport) { + data.isHtml = true; + } + + return data; + }, + loadData: function(data){ - this.getTextBlock().html(stToHTML(data.text, this.type)); + if (this.markdownSupport && !data.isHtml) { + this.getTextBlock().html(stToHTML(data.text, this.type)); + } else { + this.getTextBlock().html(data.text); + } }, }); },{"../block":146,"../to-html":182}],160:[function(require,module,exports){ (function (global){ @@ -11650,10 +12764,10 @@ // MD -> HTML type = utils.classify(type); var html = markdown, - shouldWrap = false; + shouldWrap = type === "Text"; if(_.isUndefined(shouldWrap)) { shouldWrap = false; } if (shouldWrap) { html = "<p>" + html; \ No newline at end of file