'use strict'; var isArguments = require('es5-ext/function/is-arguments') , callable = require('es5-ext/object/valid-callable') , isString = require('es5-ext/string/is-string') , get = require('./get') , isArray = Array.isArray, call = Function.prototype.call , some = Array.prototype.some; module.exports = function (iterable, cb/*, thisArg*/) { var mode, thisArg = arguments[2], result, doBreak, broken, i, l, char, code; if (isArray(iterable) || isArguments(iterable)) mode = 'array'; else if (isString(iterable)) mode = 'string'; else iterable = get(iterable); callable(cb); doBreak = function () { broken = true; }; if (mode === 'array') { some.call(iterable, function (value) { call.call(cb, thisArg, value, doBreak); if (broken) return true; }); return; } if (mode === 'string') { l = iterable.length; for (i = 0; i < l; ++i) { char = iterable[i]; if ((i + 1) < l) { code = char.charCodeAt(0); if ((code >= 0xD800) && (code <= 0xDBFF)) char += iterable[++i]; } call.call(cb, thisArg, char, doBreak); if (broken) break; } return; } result = iterable.next(); while (!result.done) { call.call(cb, thisArg, result.value, doBreak); if (broken) return; result = iterable.next(); } };