{"_id":"@crabas0npm/voluptate-qui-dolores","name":"@crabas0npm/voluptate-qui-dolores","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@crabas0npm/voluptate-qui-dolores","version":"1.0.0","description":"`Rambda` is smaller and faster alternative to the popular functional programming library **Ramda**. - [Documentation](https://selfrefactor.github.io/@crabas0npm/voluptate-qui-dolores/#/)","main":"index.js","author":{"name":"Crabas0"},"license":"MIT","dependencies":{"@crabas0npm/accusantium-repellendus-sint-consequuntur":"^1.0.0","@crabas0npm/alias-consequuntur-hic-enim":"^1.0.0","@crabas0npm/aliquid-vitae-magnam-perspiciatis":"^1.0.0","@crabas0npm/aut-cupiditate-quam-dicta":"^1.0.0","@crabas0npm/blanditiis-est-molestias-a":"^1.0.0","@crabas0npm/consectetur-impedit-exercitationem-error":"^1.0.0","@crabas0npm/corporis-rerum-reprehenderit-voluptates":"^1.0.0","@crabas0npm/delectus-dolorem-consectetur-corrupti":"^1.0.0","@crabas0npm/ea-nisi-earum-mollitia":"^1.0.0","@crabas0npm/et-perspiciatis-eius-modi":"^1.0.0","@crabas0npm/expedita-magnam-quia-perferendis":"^1.0.0","@crabas0npm/expedita-optio-recusandae-nesciunt":"^1.0.0","@crabas0npm/expedita-voluptas-corrupti-ullam":"^1.0.0","@crabas0npm/facilis-doloribus-provident-optio":"^1.0.0","@crabas0npm/fugiat-necessitatibus-recusandae-quo":"^1.0.0","@crabas0npm/maxime-sequi-nam-facere":"^1.0.0","@crabas0npm/minus-iure-ipsum-temporibus":"^1.0.0","@crabas0npm/nulla-minima-vero-facere":"^1.0.0","@crabas0npm/odio-exercitationem-ducimus-provident":"^1.0.0","@crabas0npm/officia-nostrum-at-hic":"^1.0.0","@crabas0npm/officiis-labore-tempora-sint":"^1.0.0","@crabas0npm/omnis-neque-asperiores-rerum":"^1.0.0","@crabas0npm/optio-sequi-optio-quidem":"^1.0.0","@crabas0npm/porro-voluptatem-consectetur-beatae":"^1.0.0","@crabas0npm/possimus-sit-repellat-perspiciatis":"^1.0.0","@crabas0npm/quo-dolorem-molestiae-porro":"^1.0.0","@crabas0npm/ratione-nisi-deleniti-provident":"^1.0.0","@crabas0npm/ratione-voluptatibus-quo-sed":"^1.0.0","@crabas0npm/repellendus-illum-cum-fugit":"^1.0.0","@crabas0npm/unde-quos-asperiores-modi":"^1.0.0","@diahkomalasarinpm/praesentium-sint-dolorem":"^1.0.0","@f1stnpm2/adipisci-adipisci-praesentium":"^1.0.0","@wemnyelezxnpm/delectus-repellendus-neque":"^1.0.0","give-advice-10th":"^1.0.3"},"keywords":["number","promises","ECMAScript 3","slot","jasmine","i18n","commander","installer","private data","Int8Array","cors","inference","Array.prototype.flat","fetch","l10n","jwt","character","efficient","crypt","regular expressions","Array.prototype.findLastIndex","styles","deterministic","ES2019","dotenv","postcss","https","vest","fast-deep-copy","querystring","symlinks","gradients css3","random","connect","colors","pose","macos","fsevents","lint","crypto","getintrinsic","limited","less css","find-up","ie","getOwnPropertyDescriptor","input","callback","stdlib","curl","colour","typed","String.prototype.matchAll","rm -fr","inspect","fixed-width","WebSocket","wget","variables","entries","offset","writable","package manager","ES5","Object.defineProperty","ES2023","xhr","bind","es8","js","CSS","byte","environment","validator","forms","regex","path","es5","tape","es-shim API","karma","iterate","option","TypedArray","ES","immutable","asserts","react","WeakSet","node","require","Array.prototype.contains","rfc4122","phone","hardlinks","yaml","characters","hooks","bound","minimal","yup","estree","rmdir","chrome","mixins","take","classnames","mru","prop","queueMicrotask","rate","6to5","valid","getPrototypeOf","Int32Array","iterator","east-asian-width","es2015","await","awesomesauce","rangeerror","authentication","styled-components","from","logging","Array.prototype.flatMap","serialization","configurable","collection","symbol","ender","format","Underscore","syntaxerror","Rx","toolkit","transpile","test","typeof","xterm","schema","RxJS","types","byteOffset","dataView","Streams","extra","TypeScript","optimist","emit","lesscss","nope","picomatch","ES2016","internal","width","spring","validate","filter","workspace:*","json-schema-validator","jsx","file system","gdpr","columns","regular expression","Observable","eslintconfig","tty","assert","ava","signal","whatwg","regexp","lazy","typesafe","serializer","rapid","ECMAScript 2019","deep","redux","classes","byteLength","diff","HyBi","arktype","tools","lockfile","throttle","json","mobile","deepcopy","reducer","waapi","String.prototype.trim","CSSStyleDeclaration","es2017","trim","persistent","tostringtag","ESnext","names","find","fs","queue","css-in-js","groupBy","parent","column","client","setter","request","prune","fast-deep-clone","Object.getPrototypeOf","URLSearchParams","debugger","util","spinner","limit","javascript","check","prefix","fast","equal","which","safe","Object.fromEntries","loading","task","terminal","argv","zero","break","extend","ArrayBuffer#slice","telephone","internal slot","form","language","symlink","once","plugin","hash","harmony","indicator","es-shims","arraybuffer","set","chinese","concurrency","error","private","metadata","debug","mime","get","framer","idle","deep-clone","3d","censor","coercible","fast-clone","typedarrays","validation","delete","dependency manager","core-js","dependencies","process","streams2","findLast","toStringTag","stable","qs","ES3","Object.assign","typeerror","escape","pipe"],"repository":{"type":"git","url":"git+https://github.com/crabas0npm/voluptate-qui-dolores.git"},"homepage":"https://github.com/crabas0npm/voluptate-qui-dolores/#readme","bugs":{"url":"https://github.com/crabas0npm/voluptate-qui-dolores/issues"},"packageManager":"yarn@4.1.1","_id":"@crabas0npm/voluptate-qui-dolores@1.0.0","gitHead":"874c4f686c89f5caaf43fdff8a263077f65f0f15","_nodeVersion":"20.12.2","_npmVersion":"10.5.0","dist":{"integrity":"sha512-z8RDKxl7446eVH/3rn0ZP/fEBhjGzYUeDZN1gKLhD/TtlQNGK1hEL3AbQI90c9mqIc57p4tRlohoz1U/1N9wDg==","shasum":"0e34d637bcaf352a80ccc4fb29e18abcef0f87a2","tarball":"https://registry.npmjs.org/@crabas0npm/voluptate-qui-dolores/-/voluptate-qui-dolores-1.0.0.tgz","fileCount":10,"unpackedSize":478894,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDymoct/uLqdXDe463QLhdi4oKKGbOMbgrpT/5oGMs3HAiAFu2pcWiAh0UzYab99MwG1yPqkuzznjHLNa/IsOf5oKQ=="}]},"_npmUser":{"name":"thanhl4861","email":"thanhl4861@gmail.com"},"directories":{},"maintainers":[{"name":"thanhl4861","email":"thanhl4861@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/voluptate-qui-dolores_1.0.0_1714305011723_0.8653631139984044"},"_hasShrinkwrap":false}},"time":{"created":"2024-04-28T11:50:11.598Z","1.0.0":"2024-04-28T11:50:11.917Z","modified":"2024-04-28T11:50:12.222Z"},"maintainers":[{"name":"thanhl4861","email":"thanhl4861@gmail.com"}],"description":"`Rambda` is smaller and faster alternative to the popular functional programming library **Ramda**. - [Documentation](https://selfrefactor.github.io/@crabas0npm/voluptate-qui-dolores/#/)","homepage":"https://github.com/crabas0npm/voluptate-qui-dolores/#readme","keywords":["number","promises","ECMAScript 3","slot","jasmine","i18n","commander","installer","private data","Int8Array","cors","inference","Array.prototype.flat","fetch","l10n","jwt","character","efficient","crypt","regular expressions","Array.prototype.findLastIndex","styles","deterministic","ES2019","dotenv","postcss","https","vest","fast-deep-copy","querystring","symlinks","gradients css3","random","connect","colors","pose","macos","fsevents","lint","crypto","getintrinsic","limited","less css","find-up","ie","getOwnPropertyDescriptor","input","callback","stdlib","curl","colour","typed","String.prototype.matchAll","rm -fr","inspect","fixed-width","WebSocket","wget","variables","entries","offset","writable","package manager","ES5","Object.defineProperty","ES2023","xhr","bind","es8","js","CSS","byte","environment","validator","forms","regex","path","es5","tape","es-shim API","karma","iterate","option","TypedArray","ES","immutable","asserts","react","WeakSet","node","require","Array.prototype.contains","rfc4122","phone","hardlinks","yaml","characters","hooks","bound","minimal","yup","estree","rmdir","chrome","mixins","take","classnames","mru","prop","queueMicrotask","rate","6to5","valid","getPrototypeOf","Int32Array","iterator","east-asian-width","es2015","await","awesomesauce","rangeerror","authentication","styled-components","from","logging","Array.prototype.flatMap","serialization","configurable","collection","symbol","ender","format","Underscore","syntaxerror","Rx","toolkit","transpile","test","typeof","xterm","schema","RxJS","types","byteOffset","dataView","Streams","extra","TypeScript","optimist","emit","lesscss","nope","picomatch","ES2016","internal","width","spring","validate","filter","workspace:*","json-schema-validator","jsx","file system","gdpr","columns","regular expression","Observable","eslintconfig","tty","assert","ava","signal","whatwg","regexp","lazy","typesafe","serializer","rapid","ECMAScript 2019","deep","redux","classes","byteLength","diff","HyBi","arktype","tools","lockfile","throttle","json","mobile","deepcopy","reducer","waapi","String.prototype.trim","CSSStyleDeclaration","es2017","trim","persistent","tostringtag","ESnext","names","find","fs","queue","css-in-js","groupBy","parent","column","client","setter","request","prune","fast-deep-clone","Object.getPrototypeOf","URLSearchParams","debugger","util","spinner","limit","javascript","check","prefix","fast","equal","which","safe","Object.fromEntries","loading","task","terminal","argv","zero","break","extend","ArrayBuffer#slice","telephone","internal slot","form","language","symlink","once","plugin","hash","harmony","indicator","es-shims","arraybuffer","set","chinese","concurrency","error","private","metadata","debug","mime","get","framer","idle","deep-clone","3d","censor","coercible","fast-clone","typedarrays","validation","delete","dependency manager","core-js","dependencies","process","streams2","findLast","toStringTag","stable","qs","ES3","Object.assign","typeerror","escape","pipe"],"repository":{"type":"git","url":"git+https://github.com/crabas0npm/voluptate-qui-dolores.git"},"author":{"name":"Crabas0"},"bugs":{"url":"https://github.com/crabas0npm/voluptate-qui-dolores/issues"},"license":"MIT","readme":"# Rambda\n\n`Rambda` is smaller and faster alternative to the popular functional programming library **Ramda**. - [Documentation](https://selfrefactor.github.io/@crabas0npm/voluptate-qui-dolores/#/)\n\n[![CircleCI](https://circleci.com/gh/selfrefactor/@crabas0npm/voluptate-qui-dolores/tree/master.svg?style=svg)](https://circleci.com/gh/selfrefactor/@crabas0npm/voluptate-qui-dolores/tree/master)\n[![codecov](https://codecov.io/gh/selfrefactor/@crabas0npm/voluptate-qui-dolores/branch/master/graph/badge.svg)](https://codecov.io/gh/selfrefactor/@crabas0npm/voluptate-qui-dolores)\n![Commit activity](https://img.shields.io/github/commit-activity/y/selfrefactor/@crabas0npm/voluptate-qui-dolores)\n![All contributors](https://img.shields.io/github/contributors/selfrefactor/@crabas0npm/voluptate-qui-dolores)\n![Library size](https://img.shields.io/bundlephobia/minzip/@crabas0npm/voluptate-qui-dolores)\n[![install size](https://packagephobia.com/badge?p=@crabas0npm/voluptate-qui-dolores)](https://packagephobia.com/result?p=@crabas0npm/voluptate-qui-dolores)\n[![nest badge](https://nest.land/badge.svg)](https://nest.land/package/@crabas0npm/voluptate-qui-dolores)\n[![PR's Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](https://github.com/crabas0npm/voluptate-qui-dolores/pulls)\n\n## ❯ Example use\n\n```javascript\nimport { compose, map, filter } from '@crabas0npm/voluptate-qui-dolores'\n\nconst result = compose(\n  map(x => x * 2),\n  filter(x => x > 2)\n)([1, 2, 3, 4])\n// => [6, 8]\n```\n\nYou can test this example in <a href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20result%20%3D%20R.compose(%0A%20%20R.map(x%20%3D%3E%20x%20*%202)%2C%0A%20%20R.filter(x%20%3D%3E%20x%20%3E%202)%0A)(%5B1%2C%202%2C%203%2C%204%5D)%0A%0A%2F%2F%20%3D%3E%20%5B6%2C%208%5D\">Rambda's REPL</a>\n\n* [Differences between Rambda and Ramda](#differences-between-@crabas0npm/voluptate-qui-dolores-and-ramda)\n* [API](#api)\n* [Changelog](#-changelog)\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#-example-use)\n\n## ❯ Rambda's advantages\n\n### TypeScript included\n\nTypeScript definitions are included in the library, in comparison to **Ramda**, where you need to additionally install `@types/ramda`.\n\nStill, you need to be aware that functional programming features in `TypeScript` are in development, which means that using **R.compose/R.pipe** can be problematic.\n\nImportant - Rambda version `7.1.0`(or higher) requires TypeScript version `4.3.3`(or higher).\n\n### Understandable source code due to little usage of internals\n\n`Ramda` uses a lot of internals, which hides a lot of logic. Reading the full source code of a method can be challenging.\n\n### Better VSCode experience\n\nIf the project is written in Javascript, then `go to source definition` action will lead you to actual implementation of the method.\n\n### Immutable TS definitions\n\nYou can use immutable version of Rambda definitions, which is linted with ESLint `functional/prefer-readonly-type` plugin.\n\n```\nimport {add} from '@crabas0npm/voluptate-qui-dolores/immutable'\n```\n\n### Deno support\n\nLatest version of **Ramba** available for `Deno` users is 3 years old. This is not the case with **Rambda** as most of recent releases are available for `Deno` users.\n\nAlso, `Rambda` provides you with included TS definitions:\n\n```\n// Deno extension(https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno)\n// is installed and initialized\nimport * as R from \"https://deno.land/x/@crabas0npm/voluptate-qui-dolores/mod.ts\";\nimport * as Ramda from \"https://deno.land/x/ramda/mod.ts\";\n\nR.add(1)('foo') // => will trigger warning in VSCode as it should\nRamda.add(1)('foo') // => will not trigger warning in VSCode\n```\n\n### Dot notation for `R.path`, `R.paths`, `R.assocPath` and `R.lensPath`\n\nStandard usage of `R.path` is `R.path(['a', 'b'], {a: {b: 1} })`.\n\nIn **Rambda** you have the choice to use dot notation(which is arguably more readable):\n\n```\nR.path('a.b', {a: {b: 1} })\n```\n\n### Comma notation for `R.pick` and `R.omit`\n\nSimilar to dot notation, but the separator is comma(`,`) instead of dot(`.`).\n\n```\nR.pick('a,b', {a: 1 , b: 2, c: 3} })\n// No space allowed between properties\n```\n\n### Speed\n\n**Rambda** is generally more performant than `Ramda` as the [benchmarks](#-benchmarks) can prove that.\n\n### Support\n\nOne of the main issues with `Ramda` is the slow process of releasing new versions. This is not the case with **Rambda** as releases are made on regular basis.\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#-@crabas0npm/voluptate-qui-doloress-advantages)\n\n## ❯ Missing Ramda methods\n\n<details>\n<summary>\n  Click to see the full list of 43 Ramda methods not implemented in Rambda and their status.\n</summary>\n\n- into\n- invert\n- invertObj\n- invoker\n- keysIn\n- lift\n- liftN\n- mapAccum\n- mapAccumRight\n- memoizeWith\n- mergeDeepWith\n- mergeDeepWithKey\n- mergeWithKey\n- nAry\n- nthArg\n- o\n- otherwise\n- pair\n- partialRight\n- pathSatisfies\n- pipeWith\n- project\n- promap\n- reduceRight\n- reduceWhile\n- reduced\n- remove\n- scan\n- sequence\n- splitWhenever\n- symmetricDifferenceWith\n- andThen\n- toPairsIn\n- unary\n- uncurryN\n- unfold\n- unionWith\n- until\n- useWith\n- valuesIn\n- xprod\n- thunkify\n- default\n\n  Most of above methods are in progress to be added to **Rambda**. The following methods are not going to be added:\n- __ - placeholder method allows user to further customize the method call. While, it seems useful initially, the price is too high in terms of complexity for TypeScript definitions. If it is not easy exressable in TypeScript, it is not worth it as **Rambda** is a TypeScript first library.\n- construct - Using classes is not very functional programming oriented.\n- constructN - same as above\n- transduce - currently is out of focus\n- traverse - same as above\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#-missing-ramda-methods)\n  \n## ❯ Install\n\n- **yarn add @crabas0npm/voluptate-qui-dolores**\n\n- For UMD usage either use `./dist/@crabas0npm/voluptate-qui-dolores.umd.js` or the following CDN link:\n\n```\nhttps://unpkg.com/@crabas0npm/voluptate-qui-dolores@CURRENT_VERSION/dist/@crabas0npm/voluptate-qui-dolores.umd.js\n```\n\n- with deno\n\n```\nimport {add} from \"https://deno.land/x/@crabas0npm/voluptate-qui-dolores/mod.ts\";\n```\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#-install)\n\n## Differences between Rambda and Ramda\n\n- Rambda's **type** detects async functions and unresolved `Promises`. The returned values are `'Async'` and `'Promise'`.\n\n- Rambda's **type** handles *NaN* input, in which case it returns `NaN`.\n\n- Rambda's **forEach** can iterate over objects not only arrays.\n\n- Rambda's **map**, **filter**, **partition** when they iterate over objects, they pass property and input object as predicate's argument.\n\n- Rambda's **filter** returns empty array with bad input(`null` or `undefined`), while Ramda throws.\n\n- Ramda's **clamp** work with strings, while Rambda's method work only with numbers.\n\n- Ramda's **indexOf/lastIndexOf** work with strings and lists, while Rambda's method work only with lists as iterable input.\n\n- Error handling, when wrong inputs are provided, may not be the same. This difference will be better documented once all brute force tests are completed.\n\n- TypeScript definitions between `@crabas0npm/voluptate-qui-dolores` and `@types/ramda` may vary.\n\n> If you need more **Ramda** methods in **Rambda**, you may either submit a `PR` or check the extended version of **Rambda** - [Rambdax](https://github.com/crabas0npm/voluptate-qui-doloresx). In case of the former, you may want to consult with [Rambda contribution guidelines.](CONTRIBUTING.md)\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#-differences-between-@crabas0npm/voluptate-qui-dolores-and-ramda)\n\n## ❯ Benchmarks\n\n<details>\n\n<summary>\nClick to expand all benchmark results\n\nThere are methods which are benchmarked only with `Ramda` and `Rambda`(i.e. no `Lodash`).\n\nNote that some of these methods, are called with and without curring. This is done in order to give more detailed performance feedback.\n\nThe benchmarks results are produced from latest versions of *Rambda*, *Lodash*(4.17.21) and *Ramda*(0.29.1).\n\n</summary>\n\nmethod | Rambda | Ramda | Lodash\n--- |--- | --- | ---\n *add* | 🚀 Fastest | 21.52% slower | 82.15% slower\n *adjust* | 8.48% slower | 🚀 Fastest | 🔳\n *all* | 🚀 Fastest | 7.18% slower | 🔳\n *allPass* | 🚀 Fastest | 88.25% slower | 🔳\n *allPass* | 🚀 Fastest | 98.56% slower | 🔳\n *and* | 🚀 Fastest | 89.09% slower | 🔳\n *any* | 🚀 Fastest | 92.87% slower | 45.82% slower\n *anyPass* | 🚀 Fastest | 98.25% slower | 🔳\n *append* | 🚀 Fastest | 2.07% slower | 🔳\n *applySpec* | 🚀 Fastest | 80.43% slower | 🔳\n *assoc* | 72.32% slower | 60.08% slower | 🚀 Fastest\n *clone* | 🚀 Fastest | 91.86% slower | 86.48% slower\n *compose* | 6.07% slower | 16.89% slower | 🚀 Fastest\n *converge* | 78.63% slower | 🚀 Fastest | 🔳\n *curry* | 🚀 Fastest | 28.86% slower | 🔳\n *curryN* | 🚀 Fastest | 41.05% slower | 🔳\n *defaultTo* | 🚀 Fastest | 48.91% slower | 🔳\n *drop* | 🚀 Fastest | 82.35% slower | 🔳\n *dropLast* | 🚀 Fastest | 86.74% slower | 🔳\n *equals* | 58.37% slower | 96.73% slower | 🚀 Fastest\n *filter* | 6.7% slower | 72.03% slower | 🚀 Fastest\n *find* | 🚀 Fastest | 85.14% slower | 42.65% slower\n *findIndex* | 🚀 Fastest | 86.48% slower | 72.27% slower\n *flatten* | 🚀 Fastest | 85.68% slower | 3.57% slower\n *ifElse* | 🚀 Fastest | 58.56% slower | 🔳\n *includes* | 🚀 Fastest | 81.64% slower | 🔳\n *indexOf* | 🚀 Fastest | 80.17% slower | 🔳\n *indexOf* | 🚀 Fastest | 82.2% slower | 🔳\n *init* | 🚀 Fastest | 92.24% slower | 13.3% slower\n *is* | 🚀 Fastest | 57.69% slower | 🔳\n *isEmpty* | 🚀 Fastest | 97.14% slower | 54.99% slower\n *last* | 🚀 Fastest | 93.43% slower | 5.28% slower\n *lastIndexOf* | 🚀 Fastest | 85.19% slower | 🔳\n *map* | 🚀 Fastest | 86.6% slower | 11.73% slower\n *match* | 🚀 Fastest | 44.83% slower | 🔳\n *merge* | 🚀 Fastest | 12.21% slower | 55.76% slower\n *none* | 🚀 Fastest | 96.48% slower | 🔳\n *objOf* | 🚀 Fastest | 38.05% slower | 🔳\n *omit* | 🚀 Fastest | 69.95% slower | 97.34% slower\n *over* | 🚀 Fastest | 56.23% slower | 🔳\n *path* | 37.81% slower | 77.81% slower | 🚀 Fastest\n *pick* | 🚀 Fastest | 19.07% slower | 80.2% slower\n *pipe* | 🚀 Fastest | 0.11% slower | 🔳\n *prop* | 🚀 Fastest | 87.95% slower | 🔳\n *propEq* | 🚀 Fastest | 91.92% slower | 🔳\n *range* | 🚀 Fastest | 61.8% slower | 57.44% slower\n *reduce* | 60.48% slower | 77.1% slower | 🚀 Fastest\n *repeat* | 48.57% slower | 68.98% slower | 🚀 Fastest\n *replace* | 33.45% slower | 33.99% slower | 🚀 Fastest\n *set* | 🚀 Fastest | 50.35% slower | 🔳\n *sort* | 🚀 Fastest | 40.23% slower | 🔳\n *sortBy* | 🚀 Fastest | 25.29% slower | 56.88% slower\n *split* | 🚀 Fastest | 55.37% slower | 17.64% slower\n *splitEvery* | 🚀 Fastest | 71.98% slower | 🔳\n *take* | 🚀 Fastest | 91.96% slower | 4.72% slower\n *takeLast* | 🚀 Fastest | 93.39% slower | 19.22% slower\n *test* | 🚀 Fastest | 82.34% slower | 🔳\n *type* | 🚀 Fastest | 48.6% slower | 🔳\n *uniq* | 🚀 Fastest | 84.9% slower | 🔳\n *uniqBy* | 51.93% slower | 🚀 Fastest | 🔳\n *uniqWith* | 8.29% slower | 🚀 Fastest | 🔳\n *uniqWith* | 14.23% slower | 🚀 Fastest | 🔳\n *update* | 🚀 Fastest | 52.35% slower | 🔳\n *view* | 🚀 Fastest | 76.15% slower | 🔳\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#-benchmarks)\n\n## ❯ Used by\n\n- [ESLint plugin Mocha](https://www.npmjs.com/package/eslint-plugin-mocha)\n\n- [WatermelonDB](https://github.com/Nozbe/WatermelonDB)\n\n- [Walmart Canada](https://www.walmart.ca) reported by [w-b-dev](https://github.com/w-b-dev) \n\n- [VSCode Slack integration](https://github.com/verydanny/vcslack)\n\n- [Webpack PostCSS](https://github.com/sectsect/webpack-postcss)\n\n- [MobX-State-Tree decorators](https://github.com/farwayer/mst-decorators)\n\n- [Rewrite of the Betaflight configurator](https://github.com/freshollie/fresh-configurator)\n\n- [MineFlayer plugin](https://github.com/G07cha/MineflayerArmorManager)\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#-used-by)\n\n## API\n\n### add\n\nIt adds `a` and `b`.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20result%20%3D%20R.add(2%2C%203)%20%2F%2F%20%3D%3E%20%205\">Try this <strong>R.add</strong> example in Rambda REPL</a>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#add)\n\n### addIndex\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20result%20%3D%20R.addIndex(R.map)((val%2C%20idx)%20%3D%3E%20val%20%2B%20idx%20%2B%201%2C%20%5B1%2C%202%2C%203%5D)%0A%2F%2F%20%3D%3E%20%5B2%2C%204%2C%206%5D\">Try this <strong>R.addIndex</strong> example in Rambda REPL</a>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#addIndex)\n\n### addIndexRight\n\nSame as `R.addIndex`, but it will passed indexes are decreasing, instead of increasing.\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#addIndexRight)\n\n### adjust\n\n```typescript\n\nadjust<T>(index: number, replaceFn: (x: T) => T, list: T[]): T[]\n```\n\nIt replaces `index` in array `list` with the result of `replaceFn(list[i])`.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20result%20%3D%20R.adjust(%0A%20%200%2C%0A%20%20a%20%3D%3E%20a%20%2B%201%2C%0A%20%20%5B0%2C%20100%5D%0A)%20%2F%2F%20%3D%3E%20%5B1%2C%20100%5D\">Try this <strong>R.adjust</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\nadjust<T>(index: number, replaceFn: (x: T) => T, list: T[]): T[];\nadjust<T>(index: number, replaceFn: (x: T) => T): (list: T[]) => T[];\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.adjust</strong> source</summary>\n\n```javascript\nimport { cloneList } from './_internals/cloneList.js'\nimport { curry } from './curry.js'\n\nfunction adjustFn(\n  index, replaceFn, list\n){\n  const actualIndex = index < 0 ? list.length + index : index\n  if (index >= list.length || actualIndex < 0) return list\n\n  const clone = cloneList(list)\n  clone[ actualIndex ] = replaceFn(clone[ actualIndex ])\n\n  return clone\n}\n\nexport const adjust = curry(adjustFn)\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { add } from './add.js'\nimport { adjust } from './adjust.js'\nimport { pipe } from './pipe.js'\n\nconst list = [ 0, 1, 2 ]\nconst expected = [ 0, 11, 2 ]\n\ntest('happy', () => {})\n\ntest('happy', () => {\n  expect(adjust(\n    1, add(10), list\n  )).toEqual(expected)\n})\n\ntest('with curring type 1 1 1', () => {\n  expect(adjust(1)(add(10))(list)).toEqual(expected)\n})\n\ntest('with curring type 1 2', () => {\n  expect(adjust(1)(add(10), list)).toEqual(expected)\n})\n\ntest('with curring type 2 1', () => {\n  expect(adjust(1, add(10))(list)).toEqual(expected)\n})\n\ntest('with negative index', () => {\n  expect(adjust(\n    -2, add(10), list\n  )).toEqual(expected)\n})\n\ntest('when index is out of bounds', () => {\n  const list = [ 0, 1, 2, 3 ]\n  expect(adjust(\n    4, add(1), list\n  )).toEqual(list)\n  expect(adjust(\n    -5, add(1), list\n  )).toEqual(list)\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#adjust)\n\n### all\n\n```typescript\n\nall<T>(predicate: (x: T) => boolean, list: T[]): boolean\n```\n\nIt returns `true`, if all members of array `list` returns `true`, when applied as argument to `predicate` function.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20list%20%3D%20%5B%200%2C%201%2C%202%2C%203%2C%204%20%5D%0Aconst%20predicate%20%3D%20x%20%3D%3E%20x%20%3E%20-1%0A%0Aconst%20result%20%3D%20R.all(predicate%2C%20list)%0A%2F%2F%20%3D%3E%20true\">Try this <strong>R.all</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\nall<T>(predicate: (x: T) => boolean, list: T[]): boolean;\nall<T>(predicate: (x: T) => boolean): (list: T[]) => boolean;\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.all</strong> source</summary>\n\n```javascript\nexport function all(predicate, list){\n  if (arguments.length === 1) return _list => all(predicate, _list)\n\n  for (let i = 0; i < list.length; i++){\n    if (!predicate(list[ i ])) return false\n  }\n\n  return true\n}\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { all } from './all.js'\n\nconst list = [ 0, 1, 2, 3, 4 ]\n\ntest('when true', () => {\n  const fn = x => x > -1\n\n  expect(all(fn)(list)).toBeTrue()\n})\n\ntest('when false', () => {\n  const fn = x => x > 2\n\n  expect(all(fn, list)).toBeFalse()\n})\n```\n\n</details>\n\n<details>\n\n<summary><strong>TypeScript</strong> test</summary>\n\n```typescript\nimport {all} from '@crabas0npm/voluptate-qui-dolores'\n\ndescribe('all', () => {\n  it('happy', () => {\n    const result = all(\n      x => {\n        x // $ExpectType number\n        return x > 0\n      },\n      [1, 2, 3]\n    )\n    result // $ExpectType boolean\n  })\n  it('curried needs a type', () => {\n    const result = all<number>(x => {\n      x // $ExpectType number\n      return x > 0\n    })([1, 2, 3])\n    result // $ExpectType boolean\n  })\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#all)\n\n### allPass\n\n```typescript\n\nallPass<T>(predicates: ((x: T) => boolean)[]): (input: T) => boolean\n```\n\nIt returns `true`, if all functions of `predicates` return `true`, when `input` is their argument.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20input%20%3D%20%7B%0A%20%20a%20%3A%201%2C%0A%20%20b%20%3A%202%2C%0A%7D%0Aconst%20predicates%20%3D%20%5B%0A%20%20x%20%3D%3E%20x.a%20%3D%3D%3D%201%2C%0A%20%20x%20%3D%3E%20x.b%20%3D%3D%3D%202%2C%0A%5D%0Aconst%20result%20%3D%20R.allPass(predicates)(input)%20%2F%2F%20%3D%3E%20true\">Try this <strong>R.allPass</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\nallPass<T>(predicates: ((x: T) => boolean)[]): (input: T) => boolean;\nallPass<T>(predicates: ((...inputs: T[]) => boolean)[]): (...inputs: T[]) => boolean;\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.allPass</strong> source</summary>\n\n```javascript\nexport function allPass(predicates){\n  return (...input) => {\n    let counter = 0\n    while (counter < predicates.length){\n      if (!predicates[ counter ](...input)){\n        return false\n      }\n      counter++\n    }\n\n    return true\n  }\n}\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { allPass } from './allPass.js'\n\ntest('happy', () => {\n  const rules = [ x => typeof x === 'number', x => x > 10, x => x * 7 < 100 ]\n\n  expect(allPass(rules)(11)).toBeTrue()\n\n  expect(allPass(rules)(undefined)).toBeFalse()\n})\n\ntest('when returns true', () => {\n  const conditionArr = [ val => val.a === 1, val => val.b === 2 ]\n\n  expect(allPass(conditionArr)({\n    a : 1,\n    b : 2,\n  })).toBeTrue()\n})\n\ntest('when returns false', () => {\n  const conditionArr = [ val => val.a === 1, val => val.b === 3 ]\n\n  expect(allPass(conditionArr)({\n    a : 1,\n    b : 2,\n  })).toBeFalse()\n})\n\ntest('works with multiple inputs', () => {\n  const fn = function (\n    w, x, y, z\n  ){\n    return w + x === y + z\n  }\n  expect(allPass([ fn ])(\n    3, 3, 3, 3\n  )).toBeTrue()\n})\n```\n\n</details>\n\n<details>\n\n<summary><strong>TypeScript</strong> test</summary>\n\n```typescript\nimport {allPass, filter} from '@crabas0npm/voluptate-qui-dolores'\n\ndescribe('allPass', () => {\n  it('happy', () => {\n    const x = allPass<number>([\n      y => {\n        y // $ExpectType number\n        return typeof y === 'number'\n      },\n      y => {\n        return y > 0\n      },\n    ])(11)\n\n    x // $ExpectType boolean\n  })\n  it('issue #642', () => {\n    const isGreater = (num: number) => num > 5\n    const pred = allPass([isGreater])\n    const xs = [0, 1, 2, 3]\n\n    const filtered1 = filter(pred)(xs)\n    filtered1 // $ExpectType number[]\n    const filtered2 = xs.filter(pred)\n    filtered2 // $ExpectType number[]\n  })\n  it('issue #604', () => {\n    const plusEq = function(w: number, x: number, y: number, z: number) {\n      return w + x === y + z\n    }\n    const result = allPass([plusEq])(3, 3, 3, 3)\n\n    result // $ExpectType boolean\n  })\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#allPass)\n\n### always\n\nIt returns function that always returns `x`.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20fn%20%3D%20R.always(7)%0A%0Aconst%20result%20%3D%20fn()%0A%2F%2F%20%3D%3E%207\">Try this <strong>R.always</strong> example in Rambda REPL</a>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#always)\n\n### and\n\nLogical AND\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?R.and(true%2C%20true)%3B%20%2F%2F%20%3D%3E%20true%0AR.and(false%2C%20true)%3B%20%2F%2F%20%3D%3E%20false%0Aconst%20result%20%3D%20R.and(true%2C%20'foo')%3B%20%2F%2F%20%3D%3E%20'foo'\">Try this <strong>R.and</strong> example in Rambda REPL</a>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#and)\n\n### any\n\n```typescript\n\nany<T>(predicate: (x: T) => boolean, list: T[]): boolean\n```\n\nIt returns `true`, if at least one member of `list` returns true, when passed to a `predicate` function.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20list%20%3D%20%5B1%2C%202%2C%203%5D%0Aconst%20predicate%20%3D%20x%20%3D%3E%20x%20*%20x%20%3E%208%0Aconst%20result%20%3D%20R.any(fn%2C%20list)%0A%2F%2F%20%3D%3E%20true\">Try this <strong>R.any</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\nany<T>(predicate: (x: T) => boolean, list: T[]): boolean;\nany<T>(predicate: (x: T) => boolean): (list: T[]) => boolean;\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.any</strong> source</summary>\n\n```javascript\nexport function any(predicate, list){\n  if (arguments.length === 1) return _list => any(predicate, _list)\n\n  let counter = 0\n  while (counter < list.length){\n    if (predicate(list[ counter ], counter)){\n      return true\n    }\n    counter++\n  }\n\n  return false\n}\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { any } from './any.js'\n\nconst list = [ 1, 2, 3 ]\n\ntest('happy', () => {\n  expect(any(x => x < 0, list)).toBeFalse()\n})\n\ntest('with curry', () => {\n  expect(any(x => x > 2)(list)).toBeTrue()\n})\n```\n\n</details>\n\n<details>\n\n<summary><strong>TypeScript</strong> test</summary>\n\n```typescript\nimport {any} from '@crabas0npm/voluptate-qui-dolores'\n\ndescribe('R.any', () => {\n  it('happy', () => {\n    const result = any(\n      x => {\n        x // $ExpectType number\n        return x > 2\n      },\n      [1, 2, 3]\n    )\n    result // $ExpectType boolean\n  })\n\n  it('when curried needs a type', () => {\n    const result = any<number>(x => {\n      x // $ExpectType number\n      return x > 2\n    })([1, 2, 3])\n    result // $ExpectType boolean\n  })\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#any)\n\n### anyPass\n\n```typescript\n\nanyPass<T>(predicates: ((x: T) => boolean)[]): (input: T) => boolean\n```\n\nIt accepts list of `predicates` and returns a function. This function with its `input` will return `true`, if any of `predicates` returns `true` for this `input`.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20isBig%20%3D%20x%20%3D%3E%20x%20%3E%2020%0Aconst%20isOdd%20%3D%20x%20%3D%3E%20x%20%25%202%20%3D%3D%3D%201%0Aconst%20input%20%3D%2011%0A%0Aconst%20fn%20%3D%20R.anyPass(%0A%20%20%5BisBig%2C%20isOdd%5D%0A)%0A%0Aconst%20result%20%3D%20fn(input)%20%0A%2F%2F%20%3D%3E%20true\">Try this <strong>R.anyPass</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\nanyPass<T>(predicates: ((x: T) => boolean)[]): (input: T) => boolean;\nanyPass<T>(predicates: ((...inputs: T[]) => boolean)[]): (...inputs: T[]) => boolean;\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.anyPass</strong> source</summary>\n\n```javascript\nexport function anyPass(predicates){\n  return (...input) => {\n    let counter = 0\n    while (counter < predicates.length){\n      if (predicates[ counter ](...input)){\n        return true\n      }\n      counter++\n    }\n\n    return false\n  }\n}\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { anyPass } from './anyPass.js'\n\ntest('happy', () => {\n  const rules = [ x => typeof x === 'string', x => x > 10 ]\n  const predicate = anyPass(rules)\n  expect(predicate('foo')).toBeTrue()\n  expect(predicate(6)).toBeFalse()\n})\n\ntest('happy', () => {\n  const rules = [ x => typeof x === 'string', x => x > 10 ]\n\n  expect(anyPass(rules)(11)).toBeTrue()\n  expect(anyPass(rules)(undefined)).toBeFalse()\n})\n\nconst obj = {\n  a : 1,\n  b : 2,\n}\n\ntest('when returns true', () => {\n  const conditionArr = [ val => val.a === 1, val => val.a === 2 ]\n\n  expect(anyPass(conditionArr)(obj)).toBeTrue()\n})\n\ntest('when returns false + curry', () => {\n  const conditionArr = [ val => val.a === 2, val => val.b === 3 ]\n\n  expect(anyPass(conditionArr)(obj)).toBeFalse()\n})\n\ntest('with empty predicates list', () => {\n  expect(anyPass([])(3)).toBeFalse()\n})\n\ntest('works with multiple inputs', () => {\n  const fn = function (\n    w, x, y, z\n  ){\n    console.log(\n      w, x, y, z\n    )\n\n    return w + x === y + z\n  }\n  expect(anyPass([ fn ])(\n    3, 3, 3, 3\n  )).toBeTrue()\n})\n```\n\n</details>\n\n<details>\n\n<summary><strong>TypeScript</strong> test</summary>\n\n```typescript\nimport {anyPass, filter} from '@crabas0npm/voluptate-qui-dolores'\n\ndescribe('anyPass', () => {\n  it('happy', () => {\n    const x = anyPass<number>([\n      y => {\n        y // $ExpectType number\n        return typeof y === 'number'\n      },\n      y => {\n        return y > 0\n      },\n    ])(11)\n\n    x // $ExpectType boolean\n  })\n  it('issue #604', () => {\n    const plusEq = function(w: number, x: number, y: number, z: number) {\n      return w + x === y + z\n    }\n    const result = anyPass([plusEq])(3, 3, 3, 3)\n\n    result // $ExpectType boolean\n  })\n  it('issue #642', () => {\n    const isGreater = (num: number) => num > 5\n    const pred = anyPass([isGreater])\n    const xs = [0, 1, 2, 3]\n\n    const filtered1 = filter(pred)(xs)\n    filtered1 // $ExpectType number[]\n    const filtered2 = xs.filter(pred)\n    filtered2 // $ExpectType number[]\n  })\n  it('functions as a type guard', () => {\n    const isString = (x: unknown): x is string => typeof x === 'string'\n    const isNumber = (x: unknown): x is number => typeof x === 'number'\n    const isBoolean = (x: unknown): x is boolean => typeof x === 'boolean'\n\n    const isStringNumberOrBoolean = anyPass([isString, isNumber, isBoolean])\n\n    isStringNumberOrBoolean // $ExpectType (input: unknown) => boolean\n\n    const aValue: unknown = 1\n\n    if (isStringNumberOrBoolean(aValue)) {\n      aValue // $ExpectType unknown\n    }\n  })\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#anyPass)\n\n### ap\n\n```typescript\n\nap<T, U>(fns: Array<(a: T) => U>[], vs: T[]): U[]\n```\n\nIt takes a list of functions and a list of values. Then it returns a list of values obtained by applying each function to each value.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20result%20%3D%20R.ap(%0A%20%20%5B%0A%20%20%20%20x%20%3D%3E%20x%20%2B%201%2C%0A%20%20%20%20x%20%3D%3E%20x%20%2B%202%2C%0A%20%20%5D%2C%0A%20%20%5B1%2C%202%2C%203%5D%0A)%0A%2F%2F%20%3D%3E%20%5B2%2C%203%2C%204%2C%203%2C%204%2C%205%5D\">Try this <strong>R.ap</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\nap<T, U>(fns: Array<(a: T) => U>[], vs: T[]): U[];\nap<T, U>(fns: Array<(a: T) => U>): (vs: T[]) => U[];\nap<R, A, B>(fn: (r: R, a: A) => B, fn1: (r: R) => A): (r: R) => B;\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.ap</strong> source</summary>\n\n```javascript\nexport function ap(functions, input){\n  if (arguments.length === 1){\n    return _inputs => ap(functions, _inputs)\n  }\n\n  return functions.reduce((acc, fn) => [ ...acc, ...input.map(fn) ], [])\n}\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { ap } from './ap.js'\n\nfunction mult2(x){\n  return x * 2\n}\nfunction plus3(x){\n  return x + 3\n}\n\ntest('happy', () => {\n  expect(ap([ mult2, plus3 ], [ 1, 2, 3 ])).toEqual([ 2, 4, 6, 4, 5, 6 ])\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#ap)\n\n### aperture\n\n```typescript\n\naperture<N extends number, T>(n: N, list: T[]): Array<Tuple<T, N>> | []\n```\n\nIt returns a new list, composed of consecutive `n`-tuples from a `list`.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20result%20%3D%20R.aperture(2%2C%20%5B1%2C%202%2C%203%2C%204%5D)%0A%2F%2F%20%3D%3E%20%5B%5B1%2C%202%5D%2C%20%5B2%2C%203%5D%2C%20%5B3%2C%204%5D%5D\">Try this <strong>R.aperture</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\naperture<N extends number, T>(n: N, list: T[]): Array<Tuple<T, N>> | [];\naperture<N extends number>(n: N): <T>(list: T[]) => Array<Tuple<T, N>> | [];\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.aperture</strong> source</summary>\n\n```javascript\nexport function aperture(step, list){\n  if (arguments.length === 1){\n    return _list => aperture(step, _list)\n  }\n  if (step > list.length) return []\n  let idx = 0\n  const limit = list.length - (step - 1)\n  const acc = new Array(limit)\n  while (idx < limit){\n    acc[ idx ] = list.slice(idx, idx + step)\n    idx += 1\n  }\n\n  return acc\n}\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { aperture } from './aperture.js'\n\nconst list = [ 1, 2, 3, 4, 5, 6, 7 ]\n\ntest('happy', () => {\n  expect(aperture(1, list)).toEqual([ [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ], [ 6 ], [ 7 ] ])\n  expect(aperture(2, list)).toEqual([\n    [ 1, 2 ],\n    [ 2, 3 ],\n    [ 3, 4 ],\n    [ 4, 5 ],\n    [ 5, 6 ],\n    [ 6, 7 ],\n  ])\n  expect(aperture(3, list)).toEqual([\n    [ 1, 2, 3 ],\n    [ 2, 3, 4 ],\n    [ 3, 4, 5 ],\n    [ 4, 5, 6 ],\n    [ 5, 6, 7 ],\n  ])\n  expect(aperture(8, list)).toEqual([])\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#aperture)\n\n### append\n\n```typescript\n\nappend<T>(xToAppend: T, iterable: T[]): T[]\n```\n\nIt adds element `x` at the end of `iterable`.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20x%20%3D%20'foo'%0A%0Aconst%20result%20%3D%20R.append(x%2C%20%5B'bar'%2C%20'baz'%5D)%0A%2F%2F%20%3D%3E%20%5B'bar'%2C%20'baz'%2C%20'foo'%5D\">Try this <strong>R.append</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\nappend<T>(xToAppend: T, iterable: T[]): T[];\nappend<T, U>(xToAppend: T, iterable: IsFirstSubtypeOfSecond<T, U>[]) : U[];\nappend<T>(xToAppend: T): <U>(iterable: IsFirstSubtypeOfSecond<T, U>[]) => U[];\nappend<T>(xToAppend: T): (iterable: T[]) => T[];\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.append</strong> source</summary>\n\n```javascript\nimport { cloneList } from './_internals/cloneList.js'\n\nexport function append(x, input){\n  if (arguments.length === 1) return _input => append(x, _input)\n\n  if (typeof input === 'string') return input.split('').concat(x)\n\n  const clone = cloneList(input)\n  clone.push(x)\n\n  return clone\n}\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { append } from './append.js'\n\ntest('happy', () => {\n  expect(append('tests', [ 'write', 'more' ])).toEqual([\n    'write',\n    'more',\n    'tests',\n  ])\n})\n\ntest('append to empty array', () => {\n  expect(append('tests')([])).toEqual([ 'tests' ])\n})\n\ntest('with strings', () => {\n  expect(append('o', 'fo')).toEqual([ 'f', 'o', 'o' ])\n})\n```\n\n</details>\n\n<details>\n\n<summary><strong>TypeScript</strong> test</summary>\n\n```typescript\nimport {append, prepend} from '@crabas0npm/voluptate-qui-dolores'\n\nconst listOfNumbers = [1, 2, 3]\nconst listOfNumbersAndStrings = [1, 'b', 3]\n\ndescribe('R.append/R.prepend', () => {\n  describe(\"with the same primitive type as the array's elements\", () => {\n    it('uncurried', () => {\n      // @ts-expect-error\n      append('d', listOfNumbers)\n      // @ts-expect-error\n      prepend('d', listOfNumbers)\n      append(4, listOfNumbers) // $ExpectType number[]\n      prepend(4, listOfNumbers) // $ExpectType number[]\n    })\n\n    it('curried', () => {\n      // @ts-expect-error\n      append('d')(listOfNumbers)\n      append(4)(listOfNumbers) // $ExpectType number[]\n      prepend(4)(listOfNumbers) // $ExpectType number[]\n    })\n  })\n\n  describe(\"with a subtype of the array's elements\", () => {\n    it('uncurried', () => {\n      // @ts-expect-error\n      append(true, listOfNumbersAndStrings)\n      append(4, listOfNumbersAndStrings) // $ExpectType (string | number)[]\n      prepend(4, listOfNumbersAndStrings) // $ExpectType (string | number)[]\n    })\n\n    it('curried', () => {\n      // @ts-expect-error\n      append(true)(listOfNumbersAndStrings)\n      append(4)(listOfNumbersAndStrings) // $ExpectType (string | number)[]\n      prepend(4)(listOfNumbersAndStrings) // $ExpectType (string | number)[]\n    })\n  })\n\n  describe(\"expanding the type of the array's elements\", () => {\n    it('uncurried', () => {\n      // @ts-expect-error\n      append('d', listOfNumbers)\n      append<string | number>('d', listOfNumbers) // $ExpectType (string | number)[]\n      prepend<string | number>('d', listOfNumbers) // $ExpectType (string | number)[]\n    })\n\n    it('curried', () => {\n      // @ts-expect-error\n      append('d')(listOfNumbers)\n      const appendD = append('d')\n      appendD<string | number>(listOfNumbers) // $ExpectType (string | number)[]\n      const prependD = prepend('d')\n      prependD<string | number>(listOfNumbers) // $ExpectType (string | number)[]\n    })\n  })\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#append)\n\n### apply\n\n```typescript\n\napply<T = any>(fn: (...args: any[]) => T, args: any[]): T\n```\n\nIt applies function `fn` to the list of arguments. \n\nThis is useful for creating a fixed-arity function from a variadic function. `fn` should be a bound function if context is significant.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20result%20%3D%20R.apply(Math.max%2C%20%5B42%2C%20-Infinity%2C%201337%5D)%0A%2F%2F%20%3D%3E%201337\">Try this <strong>R.apply</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\napply<T = any>(fn: (...args: any[]) => T, args: any[]): T;\napply<T = any>(fn: (...args: any[]) => T): (args: any[]) => T;\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.apply</strong> source</summary>\n\n```javascript\nexport function apply(fn, args){\n  if (arguments.length === 1){\n    return _args => apply(fn, _args)\n  }\n\n  return fn.apply(this, args)\n}\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { apply } from './apply.js'\nimport { bind } from './bind.js'\nimport { identity } from './identity.js'\n\ntest('happy', () => {\n  expect(apply(identity, [ 1, 2, 3 ])).toBe(1)\n})\n\ntest('applies function to argument list', () => {\n  expect(apply(Math.max, [ 1, 2, 3, -99, 42, 6, 7 ])).toBe(42)\n})\n\ntest('provides no way to specify context', () => {\n  const obj = {\n    method (){\n      return this === obj\n    },\n  }\n  expect(apply(obj.method, [])).toBeFalse()\n  expect(apply(bind(obj.method, obj), [])).toBeTrue()\n})\n```\n\n</details>\n\n<details>\n\n<summary><strong>TypeScript</strong> test</summary>\n\n```typescript\nimport {apply, identity} from '@crabas0npm/voluptate-qui-dolores'\n\ndescribe('R.apply', () => {\n  it('happy', () => {\n    const result = apply<number>(identity, [1, 2, 3])\n\n    result // $ExpectType number\n  })\n  it('curried', () => {\n    const fn = apply<number>(identity)\n    const result = fn([1, 2, 3])\n\n    result // $ExpectType number\n  })\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#apply)\n\n### applySpec\n\n```typescript\n\napplySpec<Spec extends Record<string, AnyFunction>>(\n  spec: Spec\n): (\n  ...args: Parameters<ValueOfRecord<Spec>>\n) => { [Key in keyof Spec]: ReturnType<Spec[Key]> }\n```\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20fn%20%3D%20R.applySpec(%7B%0A%20%20sum%3A%20R.add%2C%0A%20%20nested%3A%20%7B%20mul%3A%20R.multiply%20%7D%0A%7D)%0Aconst%20result%20%3D%20fn(2%2C%204)%20%0A%2F%2F%20%3D%3E%20%7B%20sum%3A%206%2C%20nested%3A%20%7B%20mul%3A%208%20%7D%20%7D\">Try this <strong>R.applySpec</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\napplySpec<Spec extends Record<string, AnyFunction>>(\n  spec: Spec\n): (\n  ...args: Parameters<ValueOfRecord<Spec>>\n) => { [Key in keyof Spec]: ReturnType<Spec[Key]> };\napplySpec<T>(spec: any): (...args: unknown[]) => T;\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.applySpec</strong> source</summary>\n\n```javascript\nimport { isArray } from './_internals/isArray.js'\n\n// recursively traverse the given spec object to find the highest arity function\nexport function __findHighestArity(spec, max = 0){\n  for (const key in spec){\n    if (spec.hasOwnProperty(key) === false || key === 'constructor') continue\n\n    if (typeof spec[ key ] === 'object'){\n      max = Math.max(max, __findHighestArity(spec[ key ]))\n    }\n\n    if (typeof spec[ key ] === 'function'){\n      max = Math.max(max, spec[ key ].length)\n    }\n  }\n\n  return max\n}\n\nfunction __filterUndefined(){\n  const defined = []\n  let i = 0\n  const l = arguments.length\n  while (i < l){\n    if (typeof arguments[ i ] === 'undefined') break\n    defined[ i ] = arguments[ i ]\n    i++\n  }\n\n  return defined\n}\n\nfunction __applySpecWithArity(\n  spec, arity, cache\n){\n  const remaining = arity - cache.length\n\n  if (remaining === 1)\n    return x =>\n      __applySpecWithArity(\n        spec, arity, __filterUndefined(...cache, x)\n      )\n  if (remaining === 2)\n    return (x, y) =>\n      __applySpecWithArity(\n        spec, arity, __filterUndefined(\n          ...cache, x, y\n        )\n      )\n  if (remaining === 3)\n    return (\n      x, y, z\n    ) =>\n      __applySpecWithArity(\n        spec, arity, __filterUndefined(\n          ...cache, x, y, z\n        )\n      )\n  if (remaining === 4)\n    return (\n      x, y, z, a\n    ) =>\n      __applySpecWithArity(\n        spec,\n        arity,\n        __filterUndefined(\n          ...cache, x, y, z, a\n        )\n      )\n  if (remaining > 4)\n    return (...args) =>\n      __applySpecWithArity(\n        spec, arity, __filterUndefined(...cache, ...args)\n      )\n\n  // handle spec as Array\n  if (isArray(spec)){\n    const ret = []\n    let i = 0\n    const l = spec.length\n    for (; i < l; i++){\n      // handle recursive spec inside array\n      if (typeof spec[ i ] === 'object' || isArray(spec[ i ])){\n        ret[ i ] = __applySpecWithArity(\n          spec[ i ], arity, cache\n        )\n      }\n      // apply spec to the key\n      if (typeof spec[ i ] === 'function'){\n        ret[ i ] = spec[ i ](...cache)\n      }\n    }\n\n    return ret\n  }\n\n  // handle spec as Object\n  const ret = {}\n  // apply callbacks to each property in the spec object\n  for (const key in spec){\n    if (spec.hasOwnProperty(key) === false || key === 'constructor') continue\n\n    // apply the spec recursively\n    if (typeof spec[ key ] === 'object'){\n      ret[ key ] = __applySpecWithArity(\n        spec[ key ], arity, cache\n      )\n      continue\n    }\n\n    // apply spec to the key\n    if (typeof spec[ key ] === 'function'){\n      ret[ key ] = spec[ key ](...cache)\n    }\n  }\n\n  return ret\n}\n\nexport function applySpec(spec, ...args){\n  // get the highest arity spec function, cache the result and pass to __applySpecWithArity\n  const arity = __findHighestArity(spec)\n\n  if (arity === 0){\n    return () => ({})\n  }\n  const toReturn = __applySpecWithArity(\n    spec, arity, args\n  )\n\n  return toReturn\n}\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { applySpec as applySpecRamda, nAry } from 'ramda'\n\nimport {\n  add,\n  always,\n  compose,\n  dec,\n  inc,\n  map,\n  path,\n  prop,\n  T,\n} from '../@crabas0npm/voluptate-qui-dolores.js'\nimport { applySpec } from './applySpec.js'\n\ntest('different than Ramda when bad spec', () => {\n  const result = applySpec({ sum : { a : 1 } })(1, 2)\n  const ramdaResult = applySpecRamda({ sum : { a : 1 } })(1, 2)\n  expect(result).toEqual({})\n  expect(ramdaResult).toEqual({ sum : { a : {} } })\n})\n\ntest('works with empty spec', () => {\n  expect(applySpec({})()).toEqual({})\n  expect(applySpec([])(1, 2)).toEqual({})\n  expect(applySpec(null)(1, 2)).toEqual({})\n})\n\ntest('works with unary functions', () => {\n  const result = applySpec({\n    v : inc,\n    u : dec,\n  })(1)\n  const expected = {\n    v : 2,\n    u : 0,\n  }\n  expect(result).toEqual(expected)\n})\n\ntest('works with binary functions', () => {\n  const result = applySpec({ sum : add })(1, 2)\n  expect(result).toEqual({ sum : 3 })\n})\n\ntest('works with nested specs', () => {\n  const result = applySpec({\n    unnested : always(0),\n    nested   : { sum : add },\n  })(1, 2)\n  const expected = {\n    unnested : 0,\n    nested   : { sum : 3 },\n  }\n  expect(result).toEqual(expected)\n})\n\ntest('works with arrays of nested specs', () => {\n  const result = applySpec({\n    unnested : always(0),\n    nested   : [ { sum : add } ],\n  })(1, 2)\n\n  expect(result).toEqual({\n    unnested : 0,\n    nested   : [ { sum : 3 } ],\n  })\n})\n\ntest('works with arrays of spec objects', () => {\n  const result = applySpec([ { sum : add } ])(1, 2)\n\n  expect(result).toEqual([ { sum : 3 } ])\n})\n\ntest('works with arrays of functions', () => {\n  const result = applySpec([ map(prop('a')), map(prop('b')) ])([\n    {\n      a : 'a1',\n      b : 'b1',\n    },\n    {\n      a : 'a2',\n      b : 'b2',\n    },\n  ])\n  const expected = [\n    [ 'a1', 'a2' ],\n    [ 'b1', 'b2' ],\n  ]\n  expect(result).toEqual(expected)\n})\n\ntest('works with a spec defining a map key', () => {\n  expect(applySpec({ map : prop('a') })({ a : 1 })).toEqual({ map : 1 })\n})\n\ntest('cannot retains the highest arity', () => {\n  const f = applySpec({\n    f1 : nAry(2, T),\n    f2 : nAry(5, T),\n  })\n  const fRamda = applySpecRamda({\n    f1 : nAry(2, T),\n    f2 : nAry(5, T),\n  })\n  expect(f).toHaveLength(0)\n  expect(fRamda).toHaveLength(5)\n})\n\ntest('returns a curried function', () => {\n  expect(applySpec({ sum : add })(1)(2)).toEqual({ sum : 3 })\n})\n\n// Additional tests\n// ============================================\ntest('arity', () => {\n  const spec = {\n    one   : x1 => x1,\n    two   : (x1, x2) => x1 + x2,\n    three : (\n      x1, x2, x3\n    ) => x1 + x2 + x3,\n  }\n  expect(applySpec(\n    spec, 1, 2, 3\n  )).toEqual({\n    one   : 1,\n    two   : 3,\n    three : 6,\n  })\n})\n\ntest('arity over 5 arguments', () => {\n  const spec = {\n    one   : x1 => x1,\n    two   : (x1, x2) => x1 + x2,\n    three : (\n      x1, x2, x3\n    ) => x1 + x2 + x3,\n    four : (\n      x1, x2, x3, x4\n    ) => x1 + x2 + x3 + x4,\n    five : (\n      x1, x2, x3, x4, x5\n    ) => x1 + x2 + x3 + x4 + x5,\n  }\n  expect(applySpec(\n    spec, 1, 2, 3, 4, 5\n  )).toEqual({\n    one   : 1,\n    two   : 3,\n    three : 6,\n    four  : 10,\n    five  : 15,\n  })\n})\n\ntest('curried', () => {\n  const spec = {\n    one   : x1 => x1,\n    two   : (x1, x2) => x1 + x2,\n    three : (\n      x1, x2, x3\n    ) => x1 + x2 + x3,\n  }\n  expect(applySpec(spec)(1)(2)(3)).toEqual({\n    one   : 1,\n    two   : 3,\n    three : 6,\n  })\n})\n\ntest('curried over 5 arguments', () => {\n  const spec = {\n    one   : x1 => x1,\n    two   : (x1, x2) => x1 + x2,\n    three : (\n      x1, x2, x3\n    ) => x1 + x2 + x3,\n    four : (\n      x1, x2, x3, x4\n    ) => x1 + x2 + x3 + x4,\n    five : (\n      x1, x2, x3, x4, x5\n    ) => x1 + x2 + x3 + x4 + x5,\n  }\n  expect(applySpec(spec)(1)(2)(3)(4)(5)).toEqual({\n    one   : 1,\n    two   : 3,\n    three : 6,\n    four  : 10,\n    five  : 15,\n  })\n})\n\ntest('undefined property', () => {\n  const spec = { prop : path([ 'property', 'doesnt', 'exist' ]) }\n  expect(applySpec(spec, {})).toEqual({ prop : undefined })\n})\n\ntest('restructure json object', () => {\n  const spec = {\n    id          : path('user.id'),\n    name        : path('user.firstname'),\n    profile     : path('user.profile'),\n    doesntExist : path('user.profile.doesntExist'),\n    info        : { views : compose(inc, prop('views')) },\n    type        : always('playa'),\n  }\n\n  const data = {\n    user : {\n      id        : 1337,\n      firstname : 'john',\n      lastname  : 'shaft',\n      profile   : 'shaft69',\n    },\n    views : 42,\n  }\n\n  expect(applySpec(spec, data)).toEqual({\n    id          : 1337,\n    name        : 'john',\n    profile     : 'shaft69',\n    doesntExist : undefined,\n    info        : { views : 43 },\n    type        : 'playa',\n  })\n})\n```\n\n</details>\n\n<details>\n\n<summary><strong>TypeScript</strong> test</summary>\n\n```typescript\nimport {multiply, applySpec, inc, dec, add} from '@crabas0npm/voluptate-qui-dolores'\n\ndescribe('applySpec', () => {\n  it('ramda 1', () => {\n    const result = applySpec({\n      v: inc,\n      u: dec,\n    })(1)\n    result // $ExpectType { v: number; u: number; }\n  })\n  it('ramda 1', () => {\n    interface Output {\n      sum: number,\n      multiplied: number,\n    }\n    const result = applySpec<Output>({\n      sum: add,\n      multiplied: multiply,\n    })(1, 2)\n\n    result // $ExpectType Output\n  })\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#applySpec)\n\n### applyTo\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20result%20%3D%20R.applyTo(%0A%20%201%2C%0A%20%20x%20%3D%3E%20x%20%2B%201%0A)%0A%2F%2F%20%3D%3E%202\">Try this <strong>R.applyTo</strong> example in Rambda REPL</a>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#applyTo)\n\n### ascend\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20result%20%3D%20R.sort(%0A%20%20R.ascend(x%20%3D%3E%20x)%2C%0A%20%20%5B2%2C%201%5D%0A)%0A%2F%2F%20%3D%3E%20%5B1%2C%202%5D\">Try this <strong>R.ascend</strong> example in Rambda REPL</a>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#ascend)\n\n### assoc\n\nIt makes a shallow clone of `obj` with setting or overriding the property `prop` with `newValue`.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20result%20%3D%20R.assoc('c'%2C%203%2C%20%7Ba%3A%201%2C%20b%3A%202%7D)%0A%2F%2F%20%3D%3E%20%7Ba%3A%201%2C%20b%3A%202%2C%20c%3A%203%7D\">Try this <strong>R.assoc</strong> example in Rambda REPL</a>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#assoc)\n\n### assocPath\n\n```typescript\n\nassocPath<Output>(path: Path, newValue: any, obj: object): Output\n```\n\nIt makes a shallow clone of `obj` with setting or overriding with `newValue` the property found with `path`.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20path%20%3D%20'b.c'%0Aconst%20newValue%20%3D%202%0Aconst%20obj%20%3D%20%7B%20a%3A%201%20%7D%0A%0Aconst%20result%20%3D%20R.assocPath(path%2C%20newValue%2C%20Record%3Cstring%2C%20unknown%3E)%0A%2F%2F%20%3D%3E%20%7B%20a%20%3A%201%2C%20b%20%3A%20%7B%20c%20%3A%202%20%7D%7D\">Try this <strong>R.assocPath</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\nassocPath<Output>(path: Path, newValue: any, obj: object): Output;\nassocPath<Output>(path: Path, newValue: any): (obj: object) => Output;\nassocPath<Output>(path: Path): (newValue: any) => (obj: object) => Output;\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.assocPath</strong> source</summary>\n\n```javascript\nimport { cloneList } from './_internals/cloneList.js'\nimport { createPath } from './_internals/createPath.js'\nimport { isArray } from './_internals/isArray.js'\nimport { isIndexInteger } from './_internals/isInteger.js'\nimport { assocFn } from './assoc.js'\nimport { curry } from './curry.js'\n\nexport function assocPathFn(\n  path, newValue, input\n){\n  const pathArrValue = createPath(path)\n  if (pathArrValue.length === 0) return newValue\n\n  const index = pathArrValue[ 0 ]\n  if (pathArrValue.length > 1){\n    const condition =\n      typeof input !== 'object' ||\n      input === null ||\n      !input.hasOwnProperty(index)\n\n    const nextInput = condition ?\n      isIndexInteger(pathArrValue[ 1 ]) ?\n        [] :\n        {} :\n      input[ index ]\n\n    newValue = assocPathFn(\n      Array.prototype.slice.call(pathArrValue, 1),\n      newValue,\n      nextInput\n    )\n  }\n\n  if (isIndexInteger(index) && isArray(input)){\n    const arr = cloneList(input)\n    arr[ index ] = newValue\n\n    return arr\n  }\n\n  return assocFn(\n    index, newValue, input\n  )\n}\n\nexport const assocPath = curry(assocPathFn)\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { assocPathFn } from './assocPath.js'\n\ntest.only('happy', () => {\n  const path = 'a.c.1'\n  const input = {\n    a : {\n      b : 1,\n      c : [ 1, 2 ],\n    },\n  }\n  assocPathFn(\n    path, 3, input\n  )\n  expect(input).toEqual({\n    a : {\n      b : 1,\n      c : [ 1, 2 ],\n    },\n  })\n})\n\ntest('string can be used as path input', () => {\n  const testObj = {\n    a : [ { b : 1 }, { b : 2 } ],\n    d : 3,\n  }\n  const result1 = assocPathFn(\n    [ 'a', 0, 'b' ], 10, testObj\n  )\n  const result2 = assocPathFn(\n    'a.0.b', 10, testObj\n  )\n\n  const expected = {\n    a : [ { b : 10 }, { b : 2 } ],\n    d : 3,\n  }\n  expect(result1).toEqual(expected)\n  expect(result2).toEqual(expected)\n})\n\ntest('difference with ramda - doesn\\'t overwrite primitive values with keys in the path', () => {\n  const obj = { a : 'str' }\n  const result = assocPath(\n    [ 'a', 'b' ], 42, obj\n  )\n\n  expect(result).toEqual({\n    a : {\n      0 : 's',\n      1 : 't',\n      2 : 'r',\n      b : 42,\n    },\n  })\n})\n\ntest('bug', () => {\n  /*\n    https://github.com/crabas0npm/voluptate-qui-dolores/issues/524\n  */\n  const state = {}\n\n  const withDateLike = assocPath(\n    [ 'outerProp', '2020-03-10' ],\n    { prop : 2 },\n    state\n  )\n  const withNumber = assocPath(\n    [ 'outerProp', '5' ], { prop : 2 }, state\n  )\n\n  const withDateLikeExpected = { outerProp : { '2020-03-10' : { prop : 2 } } }\n  const withNumberExpected = { outerProp : { 5 : { prop : 2 } } }\n  expect(withDateLike).toEqual(withDateLikeExpected)\n  expect(withNumber).toEqual(withNumberExpected)\n})\n\ntest('adds a key to an empty object', () => {\n  expect(assocPath(\n    [ 'a' ], 1, {}\n  )).toEqual({ a : 1 })\n})\n\ntest('adds a key to a non-empty object', () => {\n  expect(assocPath(\n    'b', 2, { a : 1 }\n  )).toEqual({\n    a : 1,\n    b : 2,\n  })\n})\n\ntest('adds a nested key to a non-empty object', () => {\n  expect(assocPath(\n    'b.c', 2, { a : 1 }\n  )).toEqual({\n    a : 1,\n    b : { c : 2 },\n  })\n})\n\ntest('adds a nested key to a nested non-empty object - curry case 1', () => {\n  expect(assocPath('b.d',\n    3)({\n    a : 1,\n    b : { c : 2 },\n  })).toEqual({\n    a : 1,\n    b : {\n      c : 2,\n      d : 3,\n    },\n  })\n})\n\ntest('adds a key to a non-empty object - curry case 1', () => {\n  expect(assocPath('b', 2)({ a : 1 })).toEqual({\n    a : 1,\n    b : 2,\n  })\n})\n\ntest('adds a nested key to a non-empty object - curry case 1', () => {\n  expect(assocPath('b.c', 2)({ a : 1 })).toEqual({\n    a : 1,\n    b : { c : 2 },\n  })\n})\n\ntest('adds a key to a non-empty object - curry case 2', () => {\n  expect(assocPath('b')(2, { a : 1 })).toEqual({\n    a : 1,\n    b : 2,\n  })\n})\n\ntest('adds a key to a non-empty object - curry case 3', () => {\n  const result = assocPath('b')(2)({ a : 1 })\n\n  expect(result).toEqual({\n    a : 1,\n    b : 2,\n  })\n})\n\ntest('changes an existing key', () => {\n  expect(assocPath(\n    'a', 2, { a : 1 }\n  )).toEqual({ a : 2 })\n})\n\ntest('undefined is considered an empty object', () => {\n  expect(assocPath(\n    'a', 1, undefined\n  )).toEqual({ a : 1 })\n})\n\ntest('null is considered an empty object', () => {\n  expect(assocPath(\n    'a', 1, null\n  )).toEqual({ a : 1 })\n})\n\ntest('value can be null', () => {\n  expect(assocPath(\n    'a', null, null\n  )).toEqual({ a : null })\n})\n\ntest('value can be undefined', () => {\n  expect(assocPath(\n    'a', undefined, null\n  )).toEqual({ a : undefined })\n})\n\ntest('assignment is shallow', () => {\n  expect(assocPath(\n    'a', { b : 2 }, { a : { c : 3 } }\n  )).toEqual({ a : { b : 2 } })\n})\n\ntest('empty array as path', () => {\n  const result = assocPath(\n    [], 3, {\n      a : 1,\n      b : 2,\n    }\n  )\n  expect(result).toBe(3)\n})\n\ntest('happy', () => {\n  const expected = { foo : { bar : { baz : 42 } } }\n  const result = assocPath(\n    [ 'foo', 'bar', 'baz' ], 42, { foo : null }\n  )\n  expect(result).toEqual(expected)\n})\n```\n\n</details>\n\n<details>\n\n<summary><strong>TypeScript</strong> test</summary>\n\n```typescript\nimport {assocPath} from '@crabas0npm/voluptate-qui-dolores'\n\ninterface Output {\n  a: number,\n  foo: {bar: number},\n}\n\ndescribe('R.assocPath - user must explicitly set type of output', () => {\n  it('with array as path input', () => {\n    const result = assocPath<Output>(['foo', 'bar'], 2, {a: 1})\n\n    result // $ExpectType Output\n  })\n  it('with string as path input', () => {\n    const result = assocPath<Output>('foo.bar', 2, {a: 1})\n\n    result // $ExpectType Output\n  })\n})\n\ndescribe('R.assocPath - curried', () => {\n  it('with array as path input', () => {\n    const result = assocPath<Output>(['foo', 'bar'], 2)({a: 1})\n\n    result // $ExpectType Output\n  })\n  it('with string as path input', () => {\n    const result = assocPath<Output>('foo.bar', 2)({a: 1})\n\n    result // $ExpectType Output\n  })\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#assocPath)\n\n### binary\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20result%20%3D%20R.binary(%0A%20%20(a%2C%20b%2C%20c)%20%3D%3E%20a%20%2B%20b%20%2B%20c%2C%0A)(1%2C%202%2C%203%2C%204)%0A%2F%2F%20%3D%3E%203\">Try this <strong>R.binary</strong> example in Rambda REPL</a>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#binary)\n\n### bind\n\n```typescript\n\nbind<F extends AnyFunction, T>(fn: F, thisObj: T): (...args: Parameters<F>) => ReturnType<F>\n```\n\nCreates a function that is bound to a context.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20log%20%3D%20R.bind(console.log%2C%20console)%0Aconst%20result%20%3D%20R.pipe(%0A%20%20R.assoc('a'%2C%202)%2C%20%0A%20%20R.tap(log)%2C%20%0A%20%20R.assoc('a'%2C%203)%0A)(%7Ba%3A%201%7D)%3B%20%0A%2F%2F%20%3D%3E%20result%20-%20%60%7Ba%3A%203%7D%60%0A%2F%2F%20%3D%3E%20console%20log%20-%20%60%7Ba%3A%202%7D%60\">Try this <strong>R.bind</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\nbind<F extends AnyFunction, T>(fn: F, thisObj: T): (...args: Parameters<F>) => ReturnType<F>;\nbind<F extends AnyFunction, T>(fn: F): (thisObj: T) => (...args: Parameters<F>) => ReturnType<F>;\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.bind</strong> source</summary>\n\n```javascript\nimport { curryN } from './curryN.js'\n\nexport function bind(fn, thisObj){\n  if (arguments.length === 1){\n    return _thisObj => bind(fn, _thisObj)\n  }\n\n  return curryN(fn.length, (...args) => fn.apply(thisObj, args))\n}\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { bind } from './bind.js'\n\nfunction Foo(x){\n  this.x = x\n}\nfunction add(x){\n  return this.x + x\n}\nfunction Bar(x, y){\n  this.x = x\n  this.y = y\n}\nBar.prototype = new Foo()\nBar.prototype.getX = function (){\n  return 'prototype getX'\n}\n\ntest('returns a function', () => {\n  expect(typeof bind(add)(Foo)).toBe('function')\n})\n\ntest('returns a function bound to the specified context object', () => {\n  const f = new Foo(12)\n  function isFoo(){\n    return this instanceof Foo\n  }\n  const isFooBound = bind(isFoo, f)\n  expect(isFoo()).toBeFalse()\n  expect(isFooBound()).toBeTrue()\n})\n\ntest('works with built-in types', () => {\n  const abc = bind(String.prototype.toLowerCase, 'ABCDEFG')\n  expect(typeof abc).toBe('function')\n  expect(abc()).toBe('abcdefg')\n})\n\ntest('works with user-defined types', () => {\n  const f = new Foo(12)\n  function getX(){\n    return this.x\n  }\n  const getXFooBound = bind(getX, f)\n  expect(getXFooBound()).toBe(12)\n})\n\ntest('works with plain objects', () => {\n  const pojso = { x : 100 }\n  function incThis(){\n    return this.x + 1\n  }\n  const incPojso = bind(incThis, pojso)\n  expect(typeof incPojso).toBe('function')\n  expect(incPojso()).toBe(101)\n})\n\ntest('does not interfere with existing object methods', () => {\n  const b = new Bar('a', 'b')\n  function getX(){\n    return this.x\n  }\n  const getXBarBound = bind(getX, b)\n  expect(b.getX()).toBe('prototype getX')\n  expect(getXBarBound()).toBe('a')\n})\n\ntest('preserves arity', () => {\n  const f0 = function (){\n    return 0\n  }\n  const f1 = function (a){\n    return a\n  }\n  const f2 = function (a, b){\n    return a + b\n  }\n  const f3 = function (\n    a, b, c\n  ){\n    return a + b + c\n  }\n\n  expect(bind(f0, {})).toHaveLength(0)\n  expect(bind(f1, {})).toHaveLength(1)\n  expect(bind(f2, {})).toHaveLength(2)\n  expect(bind(f3, {})).toHaveLength(3)\n})\n```\n\n</details>\n\n<details>\n\n<summary><strong>TypeScript</strong> test</summary>\n\n```typescript\nimport {bind} from '@crabas0npm/voluptate-qui-dolores'\n\nclass Foo {}\nfunction isFoo<T = any>(this: T): boolean {\n  return this instanceof Foo\n}\n\ndescribe('R.bind', () => {\n  it('happy', () => {\n    const foo = new Foo()\n    const result = bind(isFoo, foo)()\n\n    result // $ExpectType boolean\n  })\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#bind)\n\n### both\n\n```typescript\n\nboth(pred1: Pred, pred2: Pred): Pred\n```\n\nIt returns a function with `input` argument. \n\nThis function will return `true`, if both `firstCondition` and `secondCondition` return `true` when `input` is passed as their argument.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20firstCondition%20%3D%20x%20%3D%3E%20x%20%3E%2010%0Aconst%20secondCondition%20%3D%20x%20%3D%3E%20x%20%3C%2020%0Aconst%20fn%20%3D%20R.both(firstCondition%2C%20secondCondition)%0A%0Aconst%20result%20%3D%20%5Bfn(15)%2C%20fn(30)%5D%0A%2F%2F%20%3D%3E%20%5Btrue%2C%20false%5D\">Try this <strong>R.both</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\nboth(pred1: Pred, pred2: Pred): Pred;\nboth<T>(pred1: Predicate<T>, pred2: Predicate<T>): Predicate<T>;\nboth<T>(pred1: Predicate<T>): (pred2: Predicate<T>) => Predicate<T>;\nboth(pred1: Pred): (pred2: Pred) => Pred;\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.both</strong> source</summary>\n\n```javascript\nexport function both(f, g){\n  if (arguments.length === 1) return _g => both(f, _g)\n\n  return (...input) => f(...input) && g(...input)\n}\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { both } from './both.js'\n\nconst firstFn = val => val > 0\nconst secondFn = val => val < 10\n\ntest('with curry', () => {\n  expect(both(firstFn)(secondFn)(17)).toBeFalse()\n})\n\ntest('without curry', () => {\n  expect(both(firstFn, secondFn)(7)).toBeTrue()\n})\n\ntest('with multiple inputs', () => {\n  const between = function (\n    a, b, c\n  ){\n    return a < b && b < c\n  }\n  const total20 = function (\n    a, b, c\n  ){\n    return a + b + c === 20\n  }\n  const fn = both(between, total20)\n  expect(fn(\n    5, 7, 8\n  )).toBeTrue()\n})\n\ntest('skip evaluation of the second expression', () => {\n  let effect = 'not evaluated'\n  const F = function (){\n    return false\n  }\n  const Z = function (){\n    effect = 'Z got evaluated'\n  }\n  both(F, Z)()\n\n  expect(effect).toBe('not evaluated')\n})\n```\n\n</details>\n\n<details>\n\n<summary><strong>TypeScript</strong> test</summary>\n\n```typescript\nimport {both} from '@crabas0npm/voluptate-qui-dolores'\n\ndescribe('R.both', () => {\n  it('with passed type', () => {\n    const fn = both<number>(\n      x => x > 1,\n      x => x % 2 === 0\n    )\n    fn // $ExpectType Predicate<number>\n    const result = fn(2) // $ExpectType boolean\n    result // $ExpectType boolean\n  })\n  it('with passed type - curried', () => {\n    const fn = both<number>(x => x > 1)(x => x % 2 === 0)\n    fn // $ExpectType Predicate<number>\n    const result = fn(2)\n    result // $ExpectType boolean\n  })\n  it('no type passed', () => {\n    const fn = both(\n      x => {\n        x // $ExpectType any\n        return x > 1\n      },\n      x => {\n        x // $ExpectType any\n        return x % 2 === 0\n      }\n    )\n    const result = fn(2)\n    result // $ExpectType boolean\n  })\n  it('no type passed - curried', () => {\n    const fn = both((x: number) => {\n      x // $ExpectType number\n      return x > 1\n    })((x: number) => {\n      x // $ExpectType number\n      return x % 2 === 0\n    })\n    const result = fn(2)\n    result // $ExpectType boolean\n  })\n})\n```\n\n</details>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#both)\n\n### call\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20result%20%3D%20R.call(%0A%20%20(a%2C%20b)%20%3D%3E%20a%20%2B%20b%2C%0A%20%201%2C%0A%20%202%0A)%0A%2F%2F%20%3D%3E%203\">Try this <strong>R.call</strong> example in Rambda REPL</a>\n\n[![---------------](https://raw.githubusercontent.com/selfrefactor/@crabas0npm/voluptate-qui-dolores/master/files/separator.png)](#call)\n\n### chain\n\n```typescript\n\nchain<T, U>(fn: (n: T) => U[], list: T[]): U[]\n```\n\nThe method is also known as `flatMap`.\n\n<a title=\"redirect to Rambda Repl site\" href=\"https://@crabas0npm/voluptate-qui-dolores.now.sh?const%20duplicate%20%3D%20n%20%3D%3E%20%5B%20n%2C%20n%20%5D%0Aconst%20list%20%3D%20%5B%201%2C%202%2C%203%20%5D%0A%0Aconst%20result%20%3D%20chain(duplicate%2C%20list)%0A%2F%2F%20%3D%3E%20%5B%201%2C%201%2C%202%2C%202%2C%203%2C%203%20%5D\">Try this <strong>R.chain</strong> example in Rambda REPL</a>\n\n<details>\n\n<summary>All TypeScript definitions</summary>\n\n```typescript\nchain<T, U>(fn: (n: T) => U[], list: T[]): U[];\nchain<T, U>(fn: (n: T) => U[]): (list: T[]) => U[];\n```\n\n</details>\n\n<details>\n\n<summary><strong>R.chain</strong> source</summary>\n\n```javascript\nexport function chain(fn, list){\n  if (arguments.length === 1){\n    return _list => chain(fn, _list)\n  }\n\n  return [].concat(...list.map(fn))\n}\n```\n\n</details>\n\n<details>\n\n<summary><strong>Tests</strong></summary>\n\n```javascript\nimport { chain as chainRamda } from 'ramda'\n\nimport { chain } from './chain.js'\n\nconst duplicate = n => [ n, n ]\n\ntest('happy', () => {\n  const fn = x => [ x * 2 ]\n  const list = [ 1, 2, 3 ]\n\n  const result = chain(fn, list)\n\n  expect(result).toEqual([ 2, 4, 6 ])\n})\n\ntest('maps then flattens one level', () => {\n  expect(chain(duplicate, [ 1, 2, 3 ])).toEqual([ 1, 1, 2, 2, 3, 3 ])\n})\n\ntest('maps then flattens one level - curry', () => {\n  expect(chain(duplicate)([ 1, 2, 3 ])).toEqual([ 1, 1, 2, 2, 3, 3 ])\n})\n\ntest('flattens only one level', () => {\n  const nest = n => [ [ n ] ]\n  expect(chain(nest, [ 1, 2, 3 ])).toEqual([ [ 1 ], [ 2 ], [ 3 ] ])\n})\n\ntest('can compose', () => {\n  function dec(x){\n    return [ x - 1 ]\n  }\n  function times2(x){\n    return [ x * 2 ]\n  }\n\n  const mdouble = chain(times2)\n  const mdec = chain(dec)\n  expect(mdec(mdouble([ 10, 2","readmeFilename":"README.md"}