| 'use strict'; | 
| var bind = require('../internals/function-bind-context'); | 
| var call = require('../internals/function-call'); | 
| var anObject = require('../internals/an-object'); | 
| var tryToString = require('../internals/try-to-string'); | 
| var isArrayIteratorMethod = require('../internals/is-array-iterator-method'); | 
| var lengthOfArrayLike = require('../internals/length-of-array-like'); | 
| var isPrototypeOf = require('../internals/object-is-prototype-of'); | 
| var getIterator = require('../internals/get-iterator'); | 
| var getIteratorMethod = require('../internals/get-iterator-method'); | 
| var iteratorClose = require('../internals/iterator-close'); | 
|   | 
| var $TypeError = TypeError; | 
|   | 
| var Result = function (stopped, result) { | 
|   this.stopped = stopped; | 
|   this.result = result; | 
| }; | 
|   | 
| var ResultPrototype = Result.prototype; | 
|   | 
| module.exports = function (iterable, unboundFunction, options) { | 
|   var that = options && options.that; | 
|   var AS_ENTRIES = !!(options && options.AS_ENTRIES); | 
|   var IS_RECORD = !!(options && options.IS_RECORD); | 
|   var IS_ITERATOR = !!(options && options.IS_ITERATOR); | 
|   var INTERRUPTED = !!(options && options.INTERRUPTED); | 
|   var fn = bind(unboundFunction, that); | 
|   var iterator, iterFn, index, length, result, next, step; | 
|   | 
|   var stop = function (condition) { | 
|     if (iterator) iteratorClose(iterator, 'normal', condition); | 
|     return new Result(true, condition); | 
|   }; | 
|   | 
|   var callFn = function (value) { | 
|     if (AS_ENTRIES) { | 
|       anObject(value); | 
|       return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]); | 
|     } return INTERRUPTED ? fn(value, stop) : fn(value); | 
|   }; | 
|   | 
|   if (IS_RECORD) { | 
|     iterator = iterable.iterator; | 
|   } else if (IS_ITERATOR) { | 
|     iterator = iterable; | 
|   } else { | 
|     iterFn = getIteratorMethod(iterable); | 
|     if (!iterFn) throw new $TypeError(tryToString(iterable) + ' is not iterable'); | 
|     // optimisation for array iterators | 
|     if (isArrayIteratorMethod(iterFn)) { | 
|       for (index = 0, length = lengthOfArrayLike(iterable); length > index; index++) { | 
|         result = callFn(iterable[index]); | 
|         if (result && isPrototypeOf(ResultPrototype, result)) return result; | 
|       } return new Result(false); | 
|     } | 
|     iterator = getIterator(iterable, iterFn); | 
|   } | 
|   | 
|   next = IS_RECORD ? iterable.next : iterator.next; | 
|   while (!(step = call(next, iterator)).done) { | 
|     try { | 
|       result = callFn(step.value); | 
|     } catch (error) { | 
|       iteratorClose(iterator, 'throw', error); | 
|     } | 
|     if (typeof result == 'object' && result && isPrototypeOf(ResultPrototype, result)) return result; | 
|   } return new Result(false); | 
| }; |