basant307/AI_Governance_Project
048
1var mapping = require('./_mapping'),2 fallbackHolder = require('./placeholder');3 4/** Built-in value reference. */5var push = Array.prototype.push;6 7/**8 * Creates a function, with an arity of `n`, that invokes `func` with the9 * arguments it receives.10 *11 * @private12 * @param {Function} func The function to wrap.13 * @param {number} n The arity of the new function.14 * @returns {Function} Returns the new function.15 */16function baseArity(func, n) {17 return n == 218 ? function(a, b) { return func.apply(undefined, arguments); }19 : function(a) { return func.apply(undefined, arguments); };20}21 22/**23 * Creates a function that invokes `func`, with up to `n` arguments, ignoring24 * any additional arguments.25 *26 * @private27 * @param {Function} func The function to cap arguments for.28 * @param {number} n The arity cap.29 * @returns {Function} Returns the new function.30 */31function baseAry(func, n) {32 return n == 233 ? function(a, b) { return func(a, b); }34 : function(a) { return func(a); };35}36 37/**38 * Creates a clone of `array`.39 *40 * @private41 * @param {Array} array The array to clone.42 * @returns {Array} Returns the cloned array.43 */44function cloneArray(array) {45 var length = array ? array.length : 0,46 result = Array(length);47 48 while (length--) {49 result[length] = array[length];50 }51 return result;52}53 54/**55 * Creates a function that clones a given object using the assignment `func`.56 *57 * @private58 * @param {Function} func The assignment function.59 * @returns {Function} Returns the new cloner function.60 */61function createCloner(func) {62 return function(object) {63 return func({}, object);64 };65}66 67/**68 * A specialized version of `_.spread` which flattens the spread array into69 * the arguments of the invoked `func`.70 *71 * @private72 * @param {Function} func The function to spread arguments over.73 * @param {number} start The start position of the spread.74 * @returns {Function} Returns the new function.75 */76function flatSpread(func, start) {77 return function() {78 var length = arguments.length,79 lastIndex = length - 1,80 args = Array(length);81 82 while (length--) {83 args[length] = arguments[length];84 }85 var array = args[start],86 otherArgs = args.slice(0, start);87 88 if (array) {89 push.apply(otherArgs, array);90 }91 if (start != lastIndex) {92 push.apply(otherArgs, args.slice(start + 1));93 }94 return func.apply(this, otherArgs);95 };96}97 98/**99 * Creates a function that wraps `func` and uses `cloner` to clone the first100 * argument it receives.101 *102 * @private103 * @param {Function} func The function to wrap.104 * @param {Function} cloner The function to clone arguments.105 * @returns {Function} Returns the new immutable function.106 */107function wrapImmutable(func, cloner) {108 return function() {109 var length = arguments.length;110 if (!length) {111 return;112 }113 var args = Array(length);114 while (length--) {115 args[length] = arguments[length];116 }117 var result = args[0] = cloner.apply(undefined, args);118 func.apply(undefined, args);119 return result;120 };121}122 123/**124 * The base implementation of `convert` which accepts a `util` object of methods125 * required to perform conversions.126 *127 * @param {Object} util The util object.128 * @param {string} name The name of the function to convert.129 * @param {Function} func The function to convert.130 * @param {Object} [options] The options object.131 * @param {boolean} [options.cap=true] Specify capping iteratee arguments.132 * @param {boolean} [options.curry=true] Specify currying.133 * @param {boolean} [options.fixed=true] Specify fixed arity.134 * @param {boolean} [options.immutable=true] Specify immutable operations.135 * @param {boolean} [options.rearg=true] Specify rearranging arguments.136 * @returns {Function|Object} Returns the converted function or object.137 */138function baseConvert(util, name, func, options) {139 var isLib = typeof name == 'function',140 isObj = name === Object(name);141 142 if (isObj) {143 options = func;144 func = name;145 name = undefined;146 }147 if (func == null) {148 throw new TypeError;149 }150 options || (options = {});151 152 var config = {153 'cap': 'cap' in options ? options.cap : true,154 'curry': 'curry' in options ? options.curry : true,155 'fixed': 'fixed' in options ? options.fixed : true,156 'immutable': 'immutable' in options ? options.immutable : true,157 'rearg': 'rearg' in options ? options.rearg : true158 };159 160 var defaultHolder = isLib ? func : fallbackHolder,161 forceCurry = ('curry' in options) && options.curry,162 forceFixed = ('fixed' in options) && options.fixed,163 forceRearg = ('rearg' in options) && options.rearg,164 pristine = isLib ? func.runInContext() : undefined;165 166 var helpers = isLib ? func : {167 'ary': util.ary,168 'assign': util.assign,169 'clone': util.clone,170 'curry': util.curry,171 'forEach': util.forEach,172 'isArray': util.isArray,173 'isError': util.isError,174 'isFunction': util.isFunction,175 'isWeakMap': util.isWeakMap,176 'iteratee': util.iteratee,177 'keys': util.keys,178 'rearg': util.rearg,179 'toInteger': util.toInteger,180 'toPath': util.toPath181 };182 183 var ary = helpers.ary,184 assign = helpers.assign,185 clone = helpers.clone,186 curry = helpers.curry,187 each = helpers.forEach,188 isArray = helpers.isArray,189 isError = helpers.isError,190 isFunction = helpers.isFunction,191 isWeakMap = helpers.isWeakMap,192 keys = helpers.keys,193 rearg = helpers.rearg,194 toInteger = helpers.toInteger,195 toPath = helpers.toPath;196 197 var aryMethodKeys = keys(mapping.aryMethod);198 199 var wrappers = {200 'castArray': function(castArray) {201 return function() {202 var value = arguments[0];203 return isArray(value)204 ? castArray(cloneArray(value))205 : castArray.apply(undefined, arguments);206 };207 },208 'iteratee': function(iteratee) {209 return function() {210 var func = arguments[0],211 arity = arguments[1],212 result = iteratee(func, arity),213 length = result.length;214 215 if (config.cap && typeof arity == 'number') {216 arity = arity > 2 ? (arity - 2) : 1;217 return (length && length <= arity) ? result : baseAry(result, arity);218 }219 return result;220 };221 },222 'mixin': function(mixin) {223 return function(source) {224 var func = this;225 if (!isFunction(func)) {226 return mixin(func, Object(source));227 }228 var pairs = [];229 each(keys(source), function(key) {230 if (isFunction(source[key])) {231 pairs.push([key, func.prototype[key]]);232 }233 });234 235 mixin(func, Object(source));236 237 each(pairs, function(pair) {238 var value = pair[1];239 if (isFunction(value)) {240 func.prototype[pair[0]] = value;241 } else {242 delete func.prototype[pair[0]];243 }244 });245 return func;246 };247 },248 'nthArg': function(nthArg) {249 return function(n) {250 var arity = n < 0 ? 1 : (toInteger(n) + 1);251 return curry(nthArg(n), arity);252 };253 },254 'rearg': function(rearg) {255 return function(func, indexes) {256 var arity = indexes ? indexes.length : 0;257 return curry(rearg(func, indexes), arity);258 };259 },260 'runInContext': function(runInContext) {261 return function(context) {262 return baseConvert(util, runInContext(context), options);263 };264 }265 };266 267 /*--------------------------------------------------------------------------*/268 269 /**270 * Casts `func` to a function with an arity capped iteratee if needed.271 *272 * @private273 * @param {string} name The name of the function to inspect.274 * @param {Function} func The function to inspect.275 * @returns {Function} Returns the cast function.276 */277 function castCap(name, func) {278 if (config.cap) {279 var indexes = mapping.iterateeRearg[name];280 if (indexes) {281 return iterateeRearg(func, indexes);282 }283 var n = !isLib && mapping.iterateeAry[name];284 if (n) {285 return iterateeAry(func, n);286 }287 }288 return func;289 }290 291 /**292 * Casts `func` to a curried function if needed.293 *294 * @private295 * @param {string} name The name of the function to inspect.296 * @param {Function} func The function to inspect.297 * @param {number} n The arity of `func`.298 * @returns {Function} Returns the cast function.299 */300 function castCurry(name, func, n) {301 return (forceCurry || (config.curry && n > 1))302 ? curry(func, n)303 : func;304 }305 306 /**307 * Casts `func` to a fixed arity function if needed.308 *309 * @private310 * @param {string} name The name of the function to inspect.311 * @param {Function} func The function to inspect.312 * @param {number} n The arity cap.313 * @returns {Function} Returns the cast function.314 */315 function castFixed(name, func, n) {316 if (config.fixed && (forceFixed || !mapping.skipFixed[name])) {317 var data = mapping.methodSpread[name],318 start = data && data.start;319 320 return start === undefined ? ary(func, n) : flatSpread(func, start);321 }322 return func;323 }324 325 /**326 * Casts `func` to an rearged function if needed.327 *328 * @private329 * @param {string} name The name of the function to inspect.330 * @param {Function} func The function to inspect.331 * @param {number} n The arity of `func`.332 * @returns {Function} Returns the cast function.333 */334 function castRearg(name, func, n) {335 return (config.rearg && n > 1 && (forceRearg || !mapping.skipRearg[name]))336 ? rearg(func, mapping.methodRearg[name] || mapping.aryRearg[n])337 : func;338 }339 340 /**341 * Creates a clone of `object` by `path`.342 *343 * @private344 * @param {Object} object The object to clone.345 * @param {Array|string} path The path to clone by.346 * @returns {Object} Returns the cloned object.347 */348 function cloneByPath(object, path) {349 path = toPath(path);350 351 var index = -1,352 length = path.length,353 lastIndex = length - 1,354 result = clone(Object(object)),355 nested = result;356 357 while (nested != null && ++index < length) {358 var key = path[index],359 value = nested[key];360 361 if (value != null &&362 !(isFunction(value) || isError(value) || isWeakMap(value))) {363 nested[key] = clone(index == lastIndex ? value : Object(value));364 }365 nested = nested[key];366 }367 return result;368 }369 370 /**371 * Converts `lodash` to an immutable auto-curried iteratee-first data-last372 * version with conversion `options` applied.373 *374 * @param {Object} [options] The options object. See `baseConvert` for more details.375 * @returns {Function} Returns the converted `lodash`.376 */377 function convertLib(options) {378 return _.runInContext.convert(options)(undefined);379 }380 381 /**382 * Create a converter function for `func` of `name`.383 *384 * @param {string} name The name of the function to convert.385 * @param {Function} func The function to convert.386 * @returns {Function} Returns the new converter function.387 */388 function createConverter(name, func) {389 var realName = mapping.aliasToReal[name] || name,390 methodName = mapping.remap[realName] || realName,391 oldOptions = options;392 393 return function(options) {394 var newUtil = isLib ? pristine : helpers,395 newFunc = isLib ? pristine[methodName] : func,396 newOptions = assign(assign({}, oldOptions), options);397 398 return baseConvert(newUtil, realName, newFunc, newOptions);399 };400 }401 402 /**403 * Creates a function that wraps `func` to invoke its iteratee, with up to `n`404 * arguments, ignoring any additional arguments.405 *406 * @private407 * @param {Function} func The function to cap iteratee arguments for.408 * @param {number} n The arity cap.409 * @returns {Function} Returns the new function.410 */411 function iterateeAry(func, n) {412 return overArg(func, function(func) {413 return typeof func == 'function' ? baseAry(func, n) : func;414 });415 }416 417 /**418 * Creates a function that wraps `func` to invoke its iteratee with arguments419 * arranged according to the specified `indexes` where the argument value at420 * the first index is provided as the first argument, the argument value at421 * the second index is provided as the second argument, and so on.422 *423 * @private424 * @param {Function} func The function to rearrange iteratee arguments for.425 * @param {number[]} indexes The arranged argument indexes.426 * @returns {Function} Returns the new function.427 */428 function iterateeRearg(func, indexes) {429 return overArg(func, function(func) {430 var n = indexes.length;431 return baseArity(rearg(baseAry(func, n), indexes), n);432 });433 }434 435 /**436 * Creates a function that invokes `func` with its first argument transformed.437 *438 * @private439 * @param {Function} func The function to wrap.440 * @param {Function} transform The argument transform.441 * @returns {Function} Returns the new function.442 */443 function overArg(func, transform) {444 return function() {445 var length = arguments.length;446 if (!length) {447 return func();448 }449 var args = Array(length);450 while (length--) {451 args[length] = arguments[length];452 }453 var index = config.rearg ? 0 : (length - 1);454 args[index] = transform(args[index]);455 return func.apply(undefined, args);456 };457 }458 459 /**460 * Creates a function that wraps `func` and applys the conversions461 * rules by `name`.462 *463 * @private464 * @param {string} name The name of the function to wrap.465 * @param {Function} func The function to wrap.466 * @returns {Function} Returns the converted function.467 */468 function wrap(name, func, placeholder) {469 var result,470 realName = mapping.aliasToReal[name] || name,471 wrapped = func,472 wrapper = wrappers[realName];473 474 if (wrapper) {475 wrapped = wrapper(func);476 }477 else if (config.immutable) {478 if (mapping.mutate.array[realName]) {479 wrapped = wrapImmutable(func, cloneArray);480 }481 else if (mapping.mutate.object[realName]) {482 wrapped = wrapImmutable(func, createCloner(func));483 }484 else if (mapping.mutate.set[realName]) {485 wrapped = wrapImmutable(func, cloneByPath);486 }487 }488 each(aryMethodKeys, function(aryKey) {489 each(mapping.aryMethod[aryKey], function(otherName) {490 if (realName == otherName) {491 var data = mapping.methodSpread[realName],492 afterRearg = data && data.afterRearg;493 494 result = afterRearg495 ? castFixed(realName, castRearg(realName, wrapped, aryKey), aryKey)496 : castRearg(realName, castFixed(realName, wrapped, aryKey), aryKey);497 498 result = castCap(realName, result);499 result = castCurry(realName, result, aryKey);500 return false;501 }502 });503 return !result;504 });505 506 result || (result = wrapped);507 if (result == func) {508 result = forceCurry ? curry(result, 1) : function() {509 return func.apply(this, arguments);510 };511 }512 result.convert = createConverter(realName, func);513 result.placeholder = func.placeholder = placeholder;514 515 return result;516 }517 518 /*--------------------------------------------------------------------------*/519 520 if (!isObj) {521 return wrap(name, func, defaultHolder);522 }523 var _ = func;524 525 // Convert methods by ary cap.526 var pairs = [];527 each(aryMethodKeys, function(aryKey) {528 each(mapping.aryMethod[aryKey], function(key) {529 var func = _[mapping.remap[key] || key];530 if (func) {531 pairs.push([key, wrap(key, func, _)]);532 }533 });534 });535 536 // Convert remaining methods.537 each(keys(_), function(key) {538 var func = _[key];539 if (typeof func == 'function') {540 var length = pairs.length;541 while (length--) {542 if (pairs[length][0] == key) {543 return;544 }545 }546 func.convert = createConverter(key, func);547 pairs.push([key, func]);548 }549 });550 551 // Assign to `_` leaving `_.prototype` unchanged to allow chaining.552 each(pairs, function(pair) {553 _[pair[0]] = pair[1];554 });555 556 _.convert = convertLib;557 _.placeholder = _;558 559 // Assign aliases.560 each(keys(_), function(key) {561 each(mapping.realToAlias[key] || [], function(alias) {562 _[alias] = _[key];563 });564 });565 566 return _;567}568 569module.exports = baseConvert;570 