Compare commits

...

20 Commits

Author SHA1 Message Date
Jon Church
19c9251b36 fix: setCacheHas JSDoc return type should be boolean (#6071) 2025-12-18 17:52:05 -05:00
Muhammad Mughees Raza
b5e672995a jsdoc: Add -0 and BigInt zeros to _.compact falsey values list (#6062)
* extend falsy values to include negative zero and BigInt zeros in _.compact JSDoc

* refactor: correct spell falsey to falsy

Co-authored-by: Jordan Harband <ljharb@gmail.com>

---------

Co-authored-by: Jordan Harband <ljharb@gmail.com>
2025-12-18 16:12:55 -05:00
Ulises Gascón
edadd45214 Prevent prototype pollution on baseUnset function
* test: add tests to prevent security regressions

* sec: prevent prototype pollution on `baseUnset` function

* chore: improve security patch

- Expand both `_.omit` & `_.unset` security tests to loop over `__proto__`, `constructor`, `prototype`
- Only block `__proto__` if not an own property
2025-12-05 13:29:20 -05:00
Jon Church
4879a7a7d0 doc: fix autoLink function, conversion of source links (#6056)
* doc: fix autoLink function, dont autolink from headers

* doc: fix conversion of source only links from md to html
2025-12-04 14:28:43 -05:00
Ulises Gascón
9648f692b0 chore: remove yarn.lock file (#6053) 2025-11-19 13:38:22 +01:00
Ulises Gascón
dfa407db0b ci: remove legacy configuration files (#6052)
Main Changes:
- Remove Travis configuration file
- Remove SauceLabs configuration file
- Remove GreenKeeper configuration
2025-11-19 13:37:32 +01:00
Ulises Gascón
156e1965ae feat: add renovate setup (#6039) 2025-11-16 22:18:32 +01:00
Ulises Gascón
933e1061b8 ci: add pipeline for Bun (#6023)
Co-authored-by: Jon Church <me@jonchurch.com>
2025-11-05 22:18:36 +01:00
Peter Clarke
072a807ff7 docs: update links related to Open JS Foundation (#5968)
Co-authored-by: Ulises Gascón <ulisesgascongonzalez@gmail.com>
2025-11-05 22:15:05 +01:00
Benjamin Sternthal
70d9d037c3 Add contributors section to README
Added contributors section with committers, security triage, and publishers.

Co-authored-by: Benjamin Sternthal <ben@devpatch.com>
Co-authored-by: Jon Church <me@jonchurch.com>
Co-authored-by: Tobie Langel <tobie@unlockopen.com>
2025-10-28 09:20:14 -07:00
Ulises Gascón
2235819f76 fix: linting issues (#6033) 2025-10-28 11:12:28 -04:00
Ulises Gascón
4afb725803 Add CI pipeline for Node (#6022)
* chore: linting

* ci: add ci pipeline for Node.js

* ci: add support for Node@25

* Update .github/workflows/ci-node.yml

Co-authored-by: Jon Church <me@jonchurch.com>

---------

Co-authored-by: Jon Church <me@jonchurch.com>
2025-10-27 06:31:52 -04:00
Ulises Gascón
20c530121e security: Include a threat model (#6026)
* docs: add a reference to the threat model

* docs: add a threat model
2025-10-27 06:30:56 -04:00
Ulises Gascón
717fe4f37c feat: add CodeQL (#6032) 2025-10-27 06:29:41 -04:00
Ulises Gascón
23903d3c80 docs: add an IRP (#6028) 2025-10-27 06:26:16 -04:00
Ulises Gascón
4e856eb123 feat: add scorecard reporting (#6030) 2025-10-27 06:25:37 -04:00
Ulises Gascón
519b3d1f0d docs: add security escalation policy (#6025) 2025-10-27 06:24:14 -04:00
Ulises Gascón
61ff26e089 ci: add pipeline to run tests on browsers (#6021) 2025-10-27 06:20:37 -04:00
Ulises Gascón
c93ba2d878 ci: add ci pipeline for documentation (#6020) 2025-10-27 06:17:43 -04:00
Jon Church
8a26eb42ad add security.md from afcd5bc (#5946) 2024-12-12 17:27:03 -05:00
25 changed files with 935 additions and 4478 deletions

View File

@@ -1,7 +1,7 @@
# Contributing to Lodash
Contributions are always welcome. Before contributing please read the
[code of conduct](https://js.foundation/community/code-of-conduct) &
[code of conduct](https://github.com/openjs-foundation/cross-project-council/blob/main/CODE_OF_CONDUCT.md) &
[search the issue tracker](https://github.com/lodash/lodash/issues); your issue
may have already been discussed or fixed in `master`. To contribute,
[fork](https://help.github.com/articles/fork-a-repo/) Lodash, commit your changes,
@@ -33,7 +33,7 @@ Run unit tests from the command-line via `npm test`, or open `test/index.html` &
Lodash is a member of the [Open JS Foundation](https://openjsf.org/).
As such, we request that all contributors sign our
[contributor license agreement (CLA)](https://js.foundation/CLA/).
[contributor license agreement (CLA)](https://openjsf.org/cla).
For more information about CLAs, please check out Alex Russells excellent post,
[“Why Do I Need to Sign This?”](https://infrequently.org/2008/06/why-do-i-need-to-sign-this/).

39
.github/workflows/browser-testing.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: CI Browsers
on:
push:
branches: [ main ]
pull_request:
# Run on every PR, regardless of branch
branches: [ '*' ]
workflow_dispatch:
jobs:
test-docs:
name: Modern Browsers Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: '24'
- name: Install dependencies
run: |
npm install
npx playwright install --with-deps
npm install -D @playwright/test@latest
- name: Build project
run: npm run build
- name: Start server
run: |
npx http-server -p 9001 &
sleep 2
- name: Run Playwright tests
run: npx playwright test

34
.github/workflows/ci-bun.yml vendored Normal file
View File

@@ -0,0 +1,34 @@
name: CI Bun
on:
push:
branches: [ main ]
pull_request:
jobs:
test:
name: Bun CI
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
bun-version: [1.0.0, 1.1.0, 1.2.0, 1.3.0]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ matrix.bun-version }}
# TODO: Remove this step once the lockfile has been updated to v3 in the repository
- name: Install npm dependencies (lockfile v3)
run: npm i --lockfile-version 3 --package-lock-only
- name: Install dependencies
run: bun install
- name: Run validate
run: bun run validate

32
.github/workflows/ci-docs.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: CI Docs
on:
push:
branches: [ main ]
pull_request:
# Run on every PR, regardless of branch
branches: [ '*' ]
jobs:
test-docs:
name: Docs Test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js (latest)
uses: actions/setup-node@v4
with:
node-version: 'node' # Use 'node' for the latest version
cache: 'npm'
- name: Install dependencies
run: npm install
- name: Test documentation
run: |
npm run doc:fp
npm run doc:site
npm run doc

61
.github/workflows/ci-node.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: CI Node.js
on:
push:
branches: [ main ]
pull_request:
jobs:
test:
name: Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
node-version: [
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'11',
'12',
'13',
'14',
'15',
'16',
'17',
'18',
'19',
'20',
'21',
'22',
'23',
'24',
'25'
]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
# This is due to bugs in npm 3s handling of newer package formats.
- name: Use npm@3.10.10 for Node@5
if: matrix.node-version == '5'
run: npm install -g npm@3.10.10
- name: Install dependencies
run: npm install
- name: Run Validate
run: npm run validate

73
.github/workflows/codeql.yml vendored Normal file
View File

@@ -0,0 +1,73 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: ["main"]
pull_request:
# The branches below must be a subset of the branches above
branches: ["main"]
schedule:
- cron: "0 0 * * 1"
permissions:
contents: read
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: ["javascript"]
# CodeQL supports [ $supported-codeql-languages ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@42213152a85ae7569bdb6bec7bcd74cd691bfe41 # v3.30.9
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@42213152a85ae7569bdb6bec7bcd74cd691bfe41 # v3.30.9
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@42213152a85ae7569bdb6bec7bcd74cd691bfe41 # v3.30.9
with:
category: "/language:${{matrix.language}}"

19
.github/workflows/renovate.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: Renovate
on:
schedule:
- cron: '0 23 1 * *' # 23:00 on the first day of each month
workflow_dispatch: # allow manual runs
jobs:
renovate:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5.0.0
- name: Self-hosted Renovate
uses: renovatebot/github-action@v44.0.0
with:
configurationFile: renovate.json
env:
RENOVATE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
LOG_LEVEL: info

58
.github/workflows/scorecards.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
name: Scorecard supply-chain security
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: '20 7 * * 2'
push:
branches: ["main"]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write
contents: read
actions: read
# To allow GraphQL ListCommits to work
issues: read
pull-requests: read
# To detect SAST tools
checks: read
steps:
- name: "Checkout code"
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
with:
results_file: results.sarif
results_format: sarif
publish_results: true
# Upload the results as artifacts so they can be downloaded later if needed.
- name: "Upload artifact"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@42213152a85ae7569bdb6bec7bcd74cd691bfe41 # v3.30.9
with:
sarif_file: results.sarif

View File

@@ -1,135 +0,0 @@
language: node_js
sudo: false
node_js:
- 7
addons:
jwt:
secure: OYhRpW+8A0Iik+9GmHwa45ZwXeBXw/6zh6I+1w2H9g/LqPRp+Nhq3f4FSpvrrfno8lO8W4h+7s6+JOzF8C8NxNda5UUygKjF9pUphgiQdqls3YZMJlC9zXVl7gQXAHi3nG1s8vWSpwpzYD9fqczE1FX9n0+R63qX3eB6C/LbPeI=
cache:
directories:
- ~/.npm
- ~/.yarn-cache
- travis_phantomjs
env:
global:
- BIN=node ISTANBUL=false OPTION=""
- SAUCE_LABS=false SAUCE_USERNAME=lodash
matrix:
-
- BIN=phantomjs
- ISTANBUL=true
- SAUCE_LABS=true
matrix:
include:
- node_js: 6
env:
git:
depth: 10
branches:
only:
- master
- 4.17
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/4aab6358b0e9aed0b628
on_success: change
on_failure: always
before_install:
# Upgrade PhantomJS.
- |
export PHANTOMJS_VERSION=2.1.1
export PATH=$PWD/travis_phantomjs/phantomjs-$PHANTOMJS_VERSION-linux-x86_64/bin:$PATH
if [ $(phantomjs --version) != $PHANTOMJS_VERSION ]; then
rm -rf $PWD/travis_phantomjs
mkdir -p $PWD/travis_phantomjs
wget https://github.com/Medium/phantomjs/releases/download/v$PHANTOMJS_VERSION/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2
tar -xvf phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2 -C $PWD/travis_phantomjs
fi
phantomjs -v
# Use exact Node version.
- nvm use $TRAVIS_NODE_VERSION
# Setup package managers.
- npm set loglevel error
- npm set progress false
- npm i -g yarn@0.16.1
- yarn -V
# Remove code skipped on the coverage run.
- |
PATTERN[0]="|\s*while\s*\([^)]+\)\s*\{\s*iteratee\(index\);\s*\}|"
PATTERN[1]="|\bindex,\s*iterable\)\s*===\s*false\)[^}]+?(break;)|"
PATTERN[2]="|\bcase\s+(?:dataView|promise|set|map|weakMap)CtorString:.+|g"
PATTERN[3]="|\s*if\s*\(cache\.size\b[\s\S]+?\}|"
PATTERN[4]="|\s*if\s*\(\!lodashFunc\)\s*\{\s*return;\s*\}|"
PATTERN[5]="|\s*define\([\s\S]+?\);|"
PATTERN[6]="|\s*root\._\s*=\s*_;|"
if [ $ISTANBUL = true ]; then
set -e
for PTRN in ${PATTERN[@]}; do
node ./test/remove.js $PTRN ./lodash.js
done
fi
install:
# Install packages.
- yarn
# Use lodash-cli from GitHub. Temporarily use a fork.
- git clone --depth=10 --branch=master git://github.com/bnjmnt4n/lodash-cli ./node_modules/lodash-cli
- cd ./node_modules/lodash-cli/; npm i --production; cd ../../
- mkdir -p ./node_modules/lodash-cli/node_modules/lodash; cd $_; cp ../../../../lodash.js ./lodash.js; cp ../../../../package.json ./package.json; cd ../../../../
script:
# Detect code coverage.
- |
if [ $ISTANBUL = true ]; then
istanbul cover -x "**/vendor/**" --report lcovonly ./test/test.js -- ./lodash.js
if [ $TRAVIS_SECURE_ENV_VARS = true ]; then
cat ./coverage/lcov.info | coveralls
cat ./coverage/coverage.json | codecov
fi
fi
# Test in Node.js and PhantomJS.
- |
if [ $ISTANBUL = false ]; then
node ./node_modules/lodash-cli/bin/lodash -o ./dist/lodash.js
node ./node_modules/lodash-cli/bin/lodash modularize exports=node -o ./
node ./node_modules/lodash-cli/bin/lodash -d -o ./lodash.js
if [ $SAUCE_LABS = false ]; then
cd ./test
$BIN $OPTION ./test.js ../lodash.js
if [ $TRAVIS_SECURE_ENV_VARS = true ]; then
$BIN $OPTION ./test.js ../dist/lodash.min.js
fi
fi
fi
# Test in Sauce Labs.
- |
if [ $SAUCE_LABS = true ]; then
node ./node_modules/lodash-cli/bin/lodash core -o ./dist/lodash.core.js
npm run build
$BIN ./test/saucelabs.js name="lodash tests" runner="test/index.html?build=../dist/lodash.js&noglobals=true" tags=development
$BIN ./test/saucelabs.js name="lodash tests" runner="test/index.html?build=../dist/lodash.min.js&noglobals=true" tags=production
$BIN ./test/saucelabs.js name="lodash-fp tests" runner="test/fp.html?noglobals=true" tags=development
$BIN ./test/saucelabs.js name="underscore tests" runner="test/underscore.html?build=../dist/lodash.js" tags=development,underscore
$BIN ./test/saucelabs.js name="underscore tests" runner="test/underscore.html?build=../dist/lodash.min.js" tags=production,underscore
$BIN ./test/saucelabs.js name="backbone tests" runner="test/backbone.html?build=../dist/lodash.js" tags=development,backbone
$BIN ./test/saucelabs.js name="backbone tests" runner="test/backbone.html?build=../dist/lodash.min.js" tags=production,backbone
$BIN ./test/saucelabs.js name="backbone tests" runner="test/backbone.html?build=../dist/lodash.core.js" tags=development,backbone
$BIN ./test/saucelabs.js name="backbone tests" runner="test/backbone.html?build=../dist/lodash.core.min.js" tags=production,backbone
fi

25
GOVERNANCE.md Normal file
View File

@@ -0,0 +1,25 @@
> [!IMPORTANT]
> As announced on the [OpenJS Foundation blog](https://openjsf.org/blog/sta-supports-lodash), Lodash has received support from the Sovereign Tech Agency and will transition to the Feature-Complete maturity stage so that it remains stable, secure, and sustainable long-term. As part of this effort, Lodash is rebooting its governance. A draft charter will be published shortly. The upcoming Technical Steering Committee (TSC) is already at work. For transparency, its members are listed below.
# Lodash Governance
## Technical Steering Committee Members
The current Technical Steering Committee (TSC) members are:
- John-David Dalton ([@jdalton](https://github.com/jdalton)), _(Lodash creator)_
- Jon Church ([@jonchurch](https://github.com/jonchurch))
- Jordan Harband ([@ljharb](https://github.com/ljharb))
- Michał Lipiński ([@falsyvalues](https://github.com/falsyvalues))
- Tobie Langel ([@tobie](https://github.com/tobie))
- Ulises Gascón ([@ulisesgascon](https://github.com/UlisesGascon))
## Security Triage Team
The Security Triage Team is responsible for assessing and managing vulnerability and incident reports. Security triaging is currently handled by the [TSC](#technical-steering-committee-members).
## Release Team
The Release Team is solely responsible for publishing new versions of Lodash to npm. Its current member is:
- John-David Dalton ([@jdalton](https://github.com/jdalton))

View File

@@ -5,10 +5,14 @@
[FP Guide](https://github.com/lodash/lodash/wiki/FP-Guide) |
[Contributing](https://github.com/lodash/lodash/blob/master/.github/CONTRIBUTING.md) |
[Wiki](https://github.com/lodash/lodash/wiki "Changelog, Roadmap, etc.") |
[Code of Conduct](https://js.foundation/conduct/) |
[Code of Conduct](https://github.com/openjs-foundation/cross-project-council/blob/main/CODE_OF_CONDUCT.md) |
[Governance](https://github.com/lodash/lodash/blob/HEAD/GOVERNANCE.md) |
[Twitter](https://twitter.com/bestiejs) |
[Chat](https://gitter.im/lodash/lodash)
> [!IMPORTANT]
> As announced on the [OpenJS Foundation blog](https://openjsf.org/blog/sta-supports-lodash), Lodash has received support from the Sovereign Tech Agency and will transition to the Feature-Complete maturity stage so that it remains stable, secure, and sustainable long-term. As part of this effort, Lodash is rebooting its governance. A draft charter will be published shortly. The upcoming Technical Steering Committee (TSC) is already at work. For transparency, its members are listed in [GOVERNANCE.md](https://github.com/lodash/lodash/blob/HEAD/GOVERNANCE.md).
The [Lodash](https://lodash.com/) library exported as a [UMD](https://github.com/umdjs/umd) module.
Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli):
@@ -78,3 +82,5 @@ Lodash is available in a [variety of builds](https://lodash.com/custom-builds) &
* [lodash-es](https://www.npmjs.com/package/lodash-es), [babel-plugin-lodash](https://www.npmjs.com/package/babel-plugin-lodash), & [lodash-webpack-plugin](https://www.npmjs.com/package/lodash-webpack-plugin)
* [lodash/fp](https://github.com/lodash/lodash/tree/npm/fp)
* [lodash-amd](https://www.npmjs.com/package/lodash-amd)

47
SECURITY.md Normal file
View File

@@ -0,0 +1,47 @@
# Security Policy
## Supported versions
The following table describes the versions of this project that are currently
supported with security updates:
| Version | Supported |
| ------- | ------------------ |
| 4.x | :white_check_mark: |
| 3.x | :x: |
| 2.x | :x: |
| 1.x | :x: |
## Threat Model
To better understand which classes of vulnerabilities are considered in-scope or out-of-scope for Lodash, please review the [Lodash Threat Model](./threat-model.md).
The threat model defines Lodashs trust boundaries and clarifies how security issues are assessed for triage and disclosure.
## Responsible disclosure security policy
A responsible disclosure policy helps protect users of the project from publicly
disclosed security vulnerabilities without a fix by employing a process where
vulnerabilities are first triaged in a private manner, and only publicly disclosed
after a reasonable time period that allows patching the vulnerability and provides
an upgrade path for users.
We kindly ask you to refrain from malicious acts that put our users, the project,
or any of the projects team members at risk.
## Reporting a security issue
We consider the security of Lodash a top priority. But no matter how much effort
we put into security, there can still be vulnerabilities present.
If you discover a security vulnerability, please report the security issue
directly to the Lodash maintainers through the [Security tab](https://github.com/lodash/lodash/security) of the Lodash
repository.
Your efforts to responsibly disclose your findings are sincerely appreciated.
## Escalation
If you do not receive an acknowledgement of your report within 6 business days, or if you cannot find a private security contact for the project, you may escalate to the OpenJS Foundation CNA at `security@lists.openjsf.org`.
If the project acknowledges your report but does not provide any further response or engagement within 14 days, escalation is also appropriate.

47
dist/lodash.js vendored
View File

@@ -2300,7 +2300,7 @@
* @name has
* @memberOf SetCache
* @param {*} value The value to search for.
* @returns {number} Returns `true` if `value` is found, else `false`.
* @returns {boolean} Returns `true` if `value` is found, else `false`.
*/
function setCacheHas(value) {
return this.__data__.has(value);
@@ -3766,7 +3766,7 @@
if (isArray(iteratee)) {
return function(value) {
return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
}
};
}
return iteratee;
});
@@ -4370,8 +4370,47 @@
*/
function baseUnset(object, path) {
path = castPath(path, object);
object = parent(object, path);
return object == null || delete object[toKey(last(path))];
// Prevent prototype pollution, see: https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg
var index = -1,
length = path.length;
if (!length) {
return true;
}
var isRootPrimitive = object == null || (typeof object !== 'object' && typeof object !== 'function');
while (++index < length) {
var key = path[index];
// skip non-string keys (e.g., Symbols, numbers)
if (typeof key !== 'string') {
continue;
}
// Always block "__proto__" anywhere in the path if it's not expected
if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {
return false;
}
// Block "constructor.prototype" chains
if (key === 'constructor' &&
(index + 1) < length &&
typeof path[index + 1] === 'string' &&
path[index + 1] === 'prototype') {
// Allow ONLY when the path starts at a primitive root, e.g., _.unset(0, 'constructor.prototype.a')
if (isRootPrimitive && index === 0) {
continue;
}
return false;
}
}
var obj = parent(object, path);
return obj == null || delete obj[toKey(last(path))];
}
/**

112
dist/lodash.min.js vendored
View File

@@ -45,62 +45,62 @@ var u=t[r];if(r==e||u!==i){var i=u;Ci(u)?Ll.call(n,u,1):yu(n,u)}}return n}functi
for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++u<i;){var c=no(t[u]),a=r;if("__proto__"===c||"constructor"===c||"prototype"===c)return n;if(u!=o){var l=f[c];a=e?e(l,c,f):X,a===X&&(a=fc(l)?l:Ci(t[u+1])?[]:{})}Sr(f,c,a),f=f[c]}return n}function cu(n){return Xi(ra(n))}function au(n,t,r){var e=-1,u=n.length;t<0&&(t=-t>u?0:u+t),r=r>u?u:r,r<0&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0;for(var i=il(u);++e<u;)i[e]=n[e+t];return i}function lu(n,t){var r;return ys(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function su(n,t,r){
var e=0,u=null==n?e:n.length;if("number"==typeof t&&t===t&&u<=Tn){for(;e<u;){var i=e+u>>>1,o=n[i];null!==o&&!bc(o)&&(r?o<=t:o<t)?e=i+1:u=i}return u}return hu(n,t,La,r)}function hu(n,t,r,e){var u=0,i=null==n?0:n.length;if(0===i)return 0;t=r(t);for(var o=t!==t,f=null===t,c=bc(t),a=t===X;u<i;){var l=Nl((u+i)/2),s=r(n[l]),h=s!==X,p=null===s,_=s===s,v=bc(s);if(o)var g=e||_;else g=a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):!p&&!v&&(e?s<=t:s<t);g?u=l+1:i=l}return Hl(i,Bn)}function pu(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){
var o=n[r],f=t?t(o):o;if(!r||!Gf(f,c)){var c=f;i[u++]=0===o?0:o}}return i}function _u(n){return"number"==typeof n?n:bc(n)?Cn:+n}function vu(n){if("string"==typeof n)return n;if(bh(n))return c(n,vu)+"";if(bc(n))return vs?vs.call(n):"";var t=n+"";return"0"==t&&1/n==-Sn?"-0":t}function gu(n,t,r){var e=-1,u=o,i=n.length,c=!0,a=[],l=a;if(r)c=!1,u=f;else if(i>=tn){var s=t?null:ks(n);if(s)return P(s);c=!1,u=S,l=new yr}else l=t?[]:a;n:for(;++e<i;){var h=n[e],p=t?t(h):h;if(h=r||0!==h?h:0,c&&p===p){for(var _=l.length;_--;)if(l[_]===p)continue n;
t&&l.push(p),a.push(h)}else u(l,p,r)||(l!==a&&l.push(p),a.push(h))}return a}function yu(n,t){return t=ku(t,n),n=Gi(n,t),null==n||delete n[no(jo(t))]}function du(n,t,r,e){return fu(n,t,r(_e(n,t)),e)}function bu(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?au(n,e?0:i,e?i+1:u):au(n,e?i+1:0,e?u:i)}function wu(n,t){var r=n;return r instanceof Ct&&(r=r.value()),l(t,function(n,t){return t.func.apply(t.thisArg,a([n],t.args))},r)}function mu(n,t,r){var e=n.length;if(e<2)return e?gu(n[0]):[];
for(var u=-1,i=il(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=Hr(i[u]||o,n[f],t,r));return gu(ee(i,1),t,r)}function xu(n,t,r){for(var e=-1,u=n.length,i=t.length,o={};++e<u;){r(o,n[e],e<i?t[e]:X)}return o}function ju(n){return Jf(n)?n:[]}function Au(n){return"function"==typeof n?n:La}function ku(n,t){return bh(n)?n:Bi(n,t)?[n]:Cs(Ec(n))}function Ou(n,t,r){var e=n.length;return r=r===X?e:r,!t&&r>=e?n:au(n,t,r)}function Iu(n,t){if(t)return n.slice();var r=n.length,e=zl?zl(r):new n.constructor(r);
return n.copy(e),e}function Ru(n){var t=new n.constructor(n.byteLength);return new Rl(t).set(new Rl(n)),t}function zu(n,t){return new n.constructor(t?Ru(n.buffer):n.buffer,n.byteOffset,n.byteLength)}function Eu(n){var t=new n.constructor(n.source,Nt.exec(n));return t.lastIndex=n.lastIndex,t}function Su(n){return _s?ll(_s.call(n)):{}}function Wu(n,t){return new n.constructor(t?Ru(n.buffer):n.buffer,n.byteOffset,n.length)}function Lu(n,t){if(n!==t){var r=n!==X,e=null===n,u=n===n,i=bc(n),o=t!==X,f=null===t,c=t===t,a=bc(t);
if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&n<t||a&&r&&u&&!e&&!i||f&&r&&u||!o&&u||!c)return-1}return 0}function Cu(n,t,r){for(var e=-1,u=n.criteria,i=t.criteria,o=u.length,f=r.length;++e<o;){var c=Lu(u[e],i[e]);if(c){if(e>=f)return c;return c*("desc"==r[e]?-1:1)}}return n.index-t.index}function Uu(n,t,r,e){for(var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Gl(i-o,0),l=il(c+a),s=!e;++f<c;)l[f]=t[f];for(;++u<o;)(s||u<i)&&(l[r[u]]=n[u]);for(;a--;)l[f++]=n[u++];return l;
}function Bu(n,t,r,e){for(var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Gl(i-f,0),s=il(l+a),h=!e;++u<l;)s[u]=n[u];for(var p=u;++c<a;)s[p+c]=t[c];for(;++o<f;)(h||u<i)&&(s[p+r[o]]=n[u++]);return s}function Tu(n,t){var r=-1,e=n.length;for(t||(t=il(e));++r<e;)t[r]=n[r];return t}function $u(n,t,r,e){var u=!r;r||(r={});for(var i=-1,o=t.length;++i<o;){var f=t[i],c=e?e(r[f],n[f],f,r,n):X;c===X&&(c=n[f]),u?Br(r,f,c):Sr(r,f,c)}return r}function Du(n,t){return $u(n,Is(n),t)}function Mu(n,t){return $u(n,Rs(n),t);
}function Fu(n,r){return function(e,u){var i=bh(e)?t:Lr,o=r?r():{};return i(e,n,mi(u,2),o)}}function Nu(n){return uu(function(t,r){var e=-1,u=r.length,i=u>1?r[u-1]:X,o=u>2?r[2]:X;for(i=n.length>3&&"function"==typeof i?(u--,i):X,o&&Ui(r[0],r[1],o)&&(i=u<3?X:i,u=1),t=ll(t);++e<u;){var f=r[e];f&&n(t,f,e,i)}return t})}function Pu(n,t){return function(r,e){if(null==r)return r;if(!Hf(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=ll(r);(t?i--:++i<u)&&e(o[i],i,o)!==!1;);return r}}function qu(n){return function(t,r,e){
for(var u=-1,i=ll(t),o=e(t),f=o.length;f--;){var c=o[n?f:++u];if(r(i[c],c,i)===!1)break}return t}}function Zu(n,t,r){function e(){return(this&&this!==re&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=t&_n,i=Gu(n);return e}function Ku(n){return function(t){t=Ec(t);var r=T(t)?G(t):X,e=r?r[0]:t.charAt(0),u=r?Ou(r,1).join(""):t.slice(1);return e[n]()+u}}function Vu(n){return function(t){return l(Ra(ca(t).replace($r,"")),n,"")}}function Gu(n){return function(){var t=arguments;switch(t.length){
case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=gs(n.prototype),e=n.apply(r,t);return fc(e)?e:r}}function Hu(t,r,e){function u(){for(var o=arguments.length,f=il(o),c=o,a=wi(u);c--;)f[c]=arguments[c];var l=o<3&&f[0]!==a&&f[o-1]!==a?[]:N(f,a);
return o-=l.length,o<e?oi(t,r,Qu,u.placeholder,X,f,l,X,X,e-o):n(this&&this!==re&&this instanceof u?i:t,this,f)}var i=Gu(t);return u}function Ju(n){return function(t,r,e){var u=ll(t);if(!Hf(t)){var i=mi(r,3);t=Pc(t),r=function(n){return i(u[n],n,u)}}var o=n(t,r,e);return o>-1?u[i?t[o]:o]:X}}function Yu(n){return gi(function(t){var r=t.length,e=r,u=Y.prototype.thru;for(n&&t.reverse();e--;){var i=t[e];if("function"!=typeof i)throw new pl(en);if(u&&!o&&"wrapper"==bi(i))var o=new Y([],!0)}for(e=o?e:r;++e<r;){
i=t[e];var f=bi(i),c="wrapper"==f?Os(i):X;o=c&&$i(c[0])&&c[1]==(mn|yn|bn|xn)&&!c[4].length&&1==c[9]?o[bi(c[0])].apply(o,c[3]):1==i.length&&$i(i)?o[f]():o.thru(i)}return function(){var n=arguments,e=n[0];if(o&&1==n.length&&bh(e))return o.plant(e).value();for(var u=0,i=r?t[u].apply(this,n):e;++u<r;)i=t[u].call(this,i);return i}})}function Qu(n,t,r,e,u,i,o,f,c,a){function l(){for(var y=arguments.length,d=il(y),b=y;b--;)d[b]=arguments[b];if(_)var w=wi(l),m=C(d,w);if(e&&(d=Uu(d,e,u,_)),i&&(d=Bu(d,i,o,_)),
y-=m,_&&y<a){return oi(n,t,Qu,l.placeholder,r,d,N(d,w),f,c,a-y)}var x=h?r:this,j=p?x[n]:n;return y=d.length,f?d=Hi(d,f):v&&y>1&&d.reverse(),s&&c<y&&(d.length=c),this&&this!==re&&this instanceof l&&(j=g||Gu(j)),j.apply(x,d)}var s=t&mn,h=t&_n,p=t&vn,_=t&(yn|dn),v=t&jn,g=p?X:Gu(n);return l}function Xu(n,t){return function(r,e){return Oe(r,n,t(e),{})}}function ni(n,t){return function(r,e){var u;if(r===X&&e===X)return t;if(r!==X&&(u=r),e!==X){if(u===X)return e;"string"==typeof r||"string"==typeof e?(r=vu(r),
e=vu(e)):(r=_u(r),e=_u(e)),u=n(r,e)}return u}}function ti(t){return gi(function(r){return r=c(r,z(mi())),uu(function(e){var u=this;return t(r,function(t){return n(t,u,e)})})})}function ri(n,t){t=t===X?" ":vu(t);var r=t.length;if(r<2)return r?eu(t,n):t;var e=eu(t,Fl(n/V(t)));return T(t)?Ou(G(e),0,n).join(""):e.slice(0,n)}function ei(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=il(l+c),h=this&&this!==re&&this instanceof i?f:t;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++r];
return n(h,o?e:this,s)}var o=r&_n,f=Gu(t);return i}function ui(n){return function(t,r,e){return e&&"number"!=typeof e&&Ui(t,r,e)&&(r=e=X),t=Ac(t),r===X?(r=t,t=0):r=Ac(r),e=e===X?t<r?1:-1:Ac(e),ru(t,r,e,n)}}function ii(n){return function(t,r){return"string"==typeof t&&"string"==typeof r||(t=Ic(t),r=Ic(r)),n(t,r)}}function oi(n,t,r,e,u,i,o,f,c,a){var l=t&yn,s=l?o:X,h=l?X:o,p=l?i:X,_=l?X:i;t|=l?bn:wn,t&=~(l?wn:bn),t&gn||(t&=~(_n|vn));var v=[n,t,u,p,s,_,h,f,c,a],g=r.apply(X,v);return $i(n)&&Ss(g,v),g.placeholder=e,
Yi(g,n,t)}function fi(n){var t=al[n];return function(n,r){if(n=Ic(n),r=null==r?0:Hl(kc(r),292),r&&Zl(n)){var e=(Ec(n)+"e").split("e");return e=(Ec(t(e[0]+"e"+(+e[1]+r)))+"e").split("e"),+(e[0]+"e"+(+e[1]-r))}return t(n)}}function ci(n){return function(t){var r=zs(t);return r==Gn?M(t):r==tt?q(t):I(t,n(t))}}function ai(n,t,r,e,u,i,o,f){var c=t&vn;if(!c&&"function"!=typeof n)throw new pl(en);var a=e?e.length:0;if(a||(t&=~(bn|wn),e=u=X),o=o===X?o:Gl(kc(o),0),f=f===X?f:kc(f),a-=u?u.length:0,t&wn){var l=e,s=u;
e=u=X}var h=c?X:Os(n),p=[n,t,r,e,u,l,s,i,o,f];if(h&&qi(p,h),n=p[0],t=p[1],r=p[2],e=p[3],u=p[4],f=p[9]=p[9]===X?c?0:n.length:Gl(p[9]-a,0),!f&&t&(yn|dn)&&(t&=~(yn|dn)),t&&t!=_n)_=t==yn||t==dn?Hu(n,t,f):t!=bn&&t!=(_n|bn)||u.length?Qu.apply(X,p):ei(n,t,r,e);else var _=Zu(n,t,r);return Yi((h?ms:Ss)(_,p),n,t)}function li(n,t,r,e){return n===X||Gf(n,gl[r])&&!bl.call(e,r)?t:n}function si(n,t,r,e,u,i){return fc(n)&&fc(t)&&(i.set(t,n),Ke(n,t,X,si,i),i.delete(t)),n}function hi(n){return gc(n)?X:n}function pi(n,t,r,e,u,i){
var o=r&hn,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return!1;var a=i.get(n),l=i.get(t);if(a&&l)return a==t&&l==n;var s=-1,p=!0,_=r&pn?new yr:X;for(i.set(n,t),i.set(t,n);++s<f;){var v=n[s],g=t[s];if(e)var y=o?e(g,v,s,t,n,i):e(v,g,s,n,t,i);if(y!==X){if(y)continue;p=!1;break}if(_){if(!h(t,function(n,t){if(!S(_,t)&&(v===n||u(v,n,r,e,i)))return _.push(t)})){p=!1;break}}else if(v!==g&&!u(v,g,r,e,i)){p=!1;break}}return i.delete(n),i.delete(t),p}function _i(n,t,r,e,u,i,o){switch(r){case ct:if(n.byteLength!=t.byteLength||n.byteOffset!=t.byteOffset)return!1;
n=n.buffer,t=t.buffer;case ft:return!(n.byteLength!=t.byteLength||!i(new Rl(n),new Rl(t)));case Nn:case Pn:case Hn:return Gf(+n,+t);case Zn:return n.name==t.name&&n.message==t.message;case nt:case rt:return n==t+"";case Gn:var f=M;case tt:var c=e&hn;if(f||(f=P),n.size!=t.size&&!c)return!1;var a=o.get(n);if(a)return a==t;e|=pn,o.set(n,t);var l=pi(f(n),f(t),e,u,i,o);return o.delete(n),l;case et:if(_s)return _s.call(n)==_s.call(t)}return!1}function vi(n,t,r,e,u,i){var o=r&hn,f=yi(n),c=f.length;if(c!=yi(t).length&&!o)return!1;
for(var a=c;a--;){var l=f[a];if(!(o?l in t:bl.call(t,l)))return!1}var s=i.get(n),h=i.get(t);if(s&&h)return s==t&&h==n;var p=!0;i.set(n,t),i.set(t,n);for(var _=o;++a<c;){l=f[a];var v=n[l],g=t[l];if(e)var y=o?e(g,v,l,t,n,i):e(v,g,l,n,t,i);if(!(y===X?v===g||u(v,g,r,e,i):y)){p=!1;break}_||(_="constructor"==l)}if(p&&!_){var d=n.constructor,b=t.constructor;d!=b&&"constructor"in n&&"constructor"in t&&!("function"==typeof d&&d instanceof d&&"function"==typeof b&&b instanceof b)&&(p=!1)}return i.delete(n),
i.delete(t),p}function gi(n){return Ls(Vi(n,X,_o),n+"")}function yi(n){return de(n,Pc,Is)}function di(n){return de(n,qc,Rs)}function bi(n){for(var t=n.name+"",r=fs[t],e=bl.call(fs,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function wi(n){return(bl.call(Z,"placeholder")?Z:n).placeholder}function mi(){var n=Z.iteratee||Ca;return n=n===Ca?De:n,arguments.length?n(arguments[0],arguments[1]):n}function xi(n,t){var r=n.__data__;return Ti(t)?r["string"==typeof t?"string":"hash"]:r.map;
}function ji(n){for(var t=Pc(n),r=t.length;r--;){var e=t[r],u=n[e];t[r]=[e,u,Fi(u)]}return t}function Ai(n,t){var r=B(n,t);return Ue(r)?r:X}function ki(n){var t=bl.call(n,Bl),r=n[Bl];try{n[Bl]=X;var e=!0}catch(n){}var u=xl.call(n);return e&&(t?n[Bl]=r:delete n[Bl]),u}function Oi(n,t,r){for(var e=-1,u=r.length;++e<u;){var i=r[e],o=i.size;switch(i.type){case"drop":n+=o;break;case"dropRight":t-=o;break;case"take":t=Hl(t,n+o);break;case"takeRight":n=Gl(n,t-o)}}return{start:n,end:t}}function Ii(n){var t=n.match(Bt);
return t?t[1].split(Tt):[]}function Ri(n,t,r){t=ku(t,n);for(var e=-1,u=t.length,i=!1;++e<u;){var o=no(t[e]);if(!(i=null!=n&&r(n,o)))break;n=n[o]}return i||++e!=u?i:(u=null==n?0:n.length,!!u&&oc(u)&&Ci(o,u)&&(bh(n)||dh(n)))}function zi(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&bl.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Ei(n){return"function"!=typeof n.constructor||Mi(n)?{}:gs(El(n))}function Si(n,t,r){var e=n.constructor;switch(t){case ft:return Ru(n);
case Nn:case Pn:return new e(+n);case ct:return zu(n,r);case at:case lt:case st:case ht:case pt:case _t:case vt:case gt:case yt:return Wu(n,r);case Gn:return new e;case Hn:case rt:return new e(n);case nt:return Eu(n);case tt:return new e;case et:return Su(n)}}function Wi(n,t){var r=t.length;if(!r)return n;var e=r-1;return t[e]=(r>1?"& ":"")+t[e],t=t.join(r>2?", ":" "),n.replace(Ut,"{\n/* [wrapped with "+t+"] */\n")}function Li(n){return bh(n)||dh(n)||!!(Cl&&n&&n[Cl])}function Ci(n,t){var r=typeof n;
return t=null==t?Wn:t,!!t&&("number"==r||"symbol"!=r&&Vt.test(n))&&n>-1&&n%1==0&&n<t}function Ui(n,t,r){if(!fc(r))return!1;var e=typeof t;return!!("number"==e?Hf(r)&&Ci(t,r.length):"string"==e&&t in r)&&Gf(r[t],n)}function Bi(n,t){if(bh(n))return!1;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!bc(n))||(zt.test(n)||!Rt.test(n)||null!=t&&n in ll(t))}function Ti(n){var t=typeof n;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==n:null===n}function $i(n){
var t=bi(n),r=Z[t];if("function"!=typeof r||!(t in Ct.prototype))return!1;if(n===r)return!0;var e=Os(r);return!!e&&n===e[0]}function Di(n){return!!ml&&ml in n}function Mi(n){var t=n&&n.constructor;return n===("function"==typeof t&&t.prototype||gl)}function Fi(n){return n===n&&!fc(n)}function Ni(n,t){return function(r){return null!=r&&(r[n]===t&&(t!==X||n in ll(r)))}}function Pi(n){var t=Cf(n,function(n){return r.size===fn&&r.clear(),n}),r=t.cache;return t}function qi(n,t){var r=n[1],e=t[1],u=r|e,i=u<(_n|vn|mn),o=e==mn&&r==yn||e==mn&&r==xn&&n[7].length<=t[8]||e==(mn|xn)&&t[7].length<=t[8]&&r==yn;
if(!i&&!o)return n;e&_n&&(n[2]=t[2],u|=r&_n?0:gn);var f=t[3];if(f){var c=n[3];n[3]=c?Uu(c,f,t[4]):f,n[4]=c?N(n[3],cn):t[4]}return f=t[5],f&&(c=n[5],n[5]=c?Bu(c,f,t[6]):f,n[6]=c?N(n[5],cn):t[6]),f=t[7],f&&(n[7]=f),e&mn&&(n[8]=null==n[8]?t[8]:Hl(n[8],t[8])),null==n[9]&&(n[9]=t[9]),n[0]=t[0],n[1]=u,n}function Zi(n){var t=[];if(null!=n)for(var r in ll(n))t.push(r);return t}function Ki(n){return xl.call(n)}function Vi(t,r,e){return r=Gl(r===X?t.length-1:r,0),function(){for(var u=arguments,i=-1,o=Gl(u.length-r,0),f=il(o);++i<o;)f[i]=u[r+i];
i=-1;for(var c=il(r+1);++i<r;)c[i]=u[i];return c[r]=e(f),n(t,this,c)}}function Gi(n,t){return t.length<2?n:_e(n,au(t,0,-1))}function Hi(n,t){for(var r=n.length,e=Hl(t.length,r),u=Tu(n);e--;){var i=t[e];n[e]=Ci(i,r)?u[i]:X}return n}function Ji(n,t){if(("constructor"!==t||"function"!=typeof n[t])&&"__proto__"!=t)return n[t]}function Yi(n,t,r){var e=t+"";return Ls(n,Wi(e,ro(Ii(e),r)))}function Qi(n){var t=0,r=0;return function(){var e=Jl(),u=In-(e-r);if(r=e,u>0){if(++t>=On)return arguments[0]}else t=0;
return n.apply(X,arguments)}}function Xi(n,t){var r=-1,e=n.length,u=e-1;for(t=t===X?e:t;++r<t;){var i=tu(r,u),o=n[i];n[i]=n[r],n[r]=o}return n.length=t,n}function no(n){if("string"==typeof n||bc(n))return n;var t=n+"";return"0"==t&&1/n==-Sn?"-0":t}function to(n){if(null!=n){try{return dl.call(n)}catch(n){}try{return n+""}catch(n){}}return""}function ro(n,t){return r($n,function(r){var e="_."+r[0];t&r[1]&&!o(n,e)&&n.push(e)}),n.sort()}function eo(n){if(n instanceof Ct)return n.clone();var t=new Y(n.__wrapped__,n.__chain__);
return t.__actions__=Tu(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function uo(n,t,r){t=(r?Ui(n,t,r):t===X)?1:Gl(kc(t),0);var e=null==n?0:n.length;if(!e||t<1)return[];for(var u=0,i=0,o=il(Fl(e/t));u<e;)o[i++]=au(n,u,u+=t);return o}function io(n){for(var t=-1,r=null==n?0:n.length,e=0,u=[];++t<r;){var i=n[t];i&&(u[e++]=i)}return u}function oo(){var n=arguments.length;if(!n)return[];for(var t=il(n-1),r=arguments[0],e=n;e--;)t[e-1]=arguments[e];return a(bh(r)?Tu(r):[r],ee(t,1));
}function fo(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===X?1:kc(t),au(n,t<0?0:t,e)):[]}function co(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===X?1:kc(t),t=e-t,au(n,0,t<0?0:t)):[]}function ao(n,t){return n&&n.length?bu(n,mi(t,3),!0,!0):[]}function lo(n,t){return n&&n.length?bu(n,mi(t,3),!0):[]}function so(n,t,r,e){var u=null==n?0:n.length;return u?(r&&"number"!=typeof r&&Ui(n,t,r)&&(r=0,e=u),ne(n,t,r,e)):[]}function ho(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=null==r?0:kc(r);
return u<0&&(u=Gl(e+u,0)),g(n,mi(t,3),u)}function po(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==X&&(u=kc(r),u=r<0?Gl(e+u,0):Hl(u,e-1)),g(n,mi(t,3),u,!0)}function _o(n){return(null==n?0:n.length)?ee(n,1):[]}function vo(n){return(null==n?0:n.length)?ee(n,Sn):[]}function go(n,t){return(null==n?0:n.length)?(t=t===X?1:kc(t),ee(n,t)):[]}function yo(n){for(var t=-1,r=null==n?0:n.length,e={};++t<r;){var u=n[t];e[u[0]]=u[1]}return e}function bo(n){return n&&n.length?n[0]:X}function wo(n,t,r){
var e=null==n?0:n.length;if(!e)return-1;var u=null==r?0:kc(r);return u<0&&(u=Gl(e+u,0)),y(n,t,u)}function mo(n){return(null==n?0:n.length)?au(n,0,-1):[]}function xo(n,t){return null==n?"":Kl.call(n,t)}function jo(n){var t=null==n?0:n.length;return t?n[t-1]:X}function Ao(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;return r!==X&&(u=kc(r),u=u<0?Gl(e+u,0):Hl(u,e-1)),t===t?K(n,t,u):g(n,b,u,!0)}function ko(n,t){return n&&n.length?Ge(n,kc(t)):X}function Oo(n,t){return n&&n.length&&t&&t.length?Xe(n,t):n;
}function Io(n,t,r){return n&&n.length&&t&&t.length?Xe(n,t,mi(r,2)):n}function Ro(n,t,r){return n&&n.length&&t&&t.length?Xe(n,t,X,r):n}function zo(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=mi(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),u.push(e))}return nu(n,u),r}function Eo(n){return null==n?n:Xl.call(n)}function So(n,t,r){var e=null==n?0:n.length;return e?(r&&"number"!=typeof r&&Ui(n,t,r)?(t=0,r=e):(t=null==t?0:kc(t),r=r===X?e:kc(r)),au(n,t,r)):[]}function Wo(n,t){
return su(n,t)}function Lo(n,t,r){return hu(n,t,mi(r,2))}function Co(n,t){var r=null==n?0:n.length;if(r){var e=su(n,t);if(e<r&&Gf(n[e],t))return e}return-1}function Uo(n,t){return su(n,t,!0)}function Bo(n,t,r){return hu(n,t,mi(r,2),!0)}function To(n,t){if(null==n?0:n.length){var r=su(n,t,!0)-1;if(Gf(n[r],t))return r}return-1}function $o(n){return n&&n.length?pu(n):[]}function Do(n,t){return n&&n.length?pu(n,mi(t,2)):[]}function Mo(n){var t=null==n?0:n.length;return t?au(n,1,t):[]}function Fo(n,t,r){
return n&&n.length?(t=r||t===X?1:kc(t),au(n,0,t<0?0:t)):[]}function No(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===X?1:kc(t),t=e-t,au(n,t<0?0:t,e)):[]}function Po(n,t){return n&&n.length?bu(n,mi(t,3),!1,!0):[]}function qo(n,t){return n&&n.length?bu(n,mi(t,3)):[]}function Zo(n){return n&&n.length?gu(n):[]}function Ko(n,t){return n&&n.length?gu(n,mi(t,2)):[]}function Vo(n,t){return t="function"==typeof t?t:X,n&&n.length?gu(n,X,t):[]}function Go(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){
if(Jf(n))return t=Gl(n.length,t),!0}),O(t,function(t){return c(n,m(t))})}function Ho(t,r){if(!t||!t.length)return[];var e=Go(t);return null==r?e:c(e,function(t){return n(r,X,t)})}function Jo(n,t){return xu(n||[],t||[],Sr)}function Yo(n,t){return xu(n||[],t||[],fu)}function Qo(n){var t=Z(n);return t.__chain__=!0,t}function Xo(n,t){return t(n),n}function nf(n,t){return t(n)}function tf(){return Qo(this)}function rf(){return new Y(this.value(),this.__chain__)}function ef(){this.__values__===X&&(this.__values__=jc(this.value()));
var n=this.__index__>=this.__values__.length;return{done:n,value:n?X:this.__values__[this.__index__++]}}function uf(){return this}function of(n){for(var t,r=this;r instanceof J;){var e=eo(r);e.__index__=0,e.__values__=X,t?u.__wrapped__=e:t=e;var u=e;r=r.__wrapped__}return u.__wrapped__=n,t}function ff(){var n=this.__wrapped__;if(n instanceof Ct){var t=n;return this.__actions__.length&&(t=new Ct(this)),t=t.reverse(),t.__actions__.push({func:nf,args:[Eo],thisArg:X}),new Y(t,this.__chain__)}return this.thru(Eo);
}function cf(){return wu(this.__wrapped__,this.__actions__)}function af(n,t,r){var e=bh(n)?u:Jr;return r&&Ui(n,t,r)&&(t=X),e(n,mi(t,3))}function lf(n,t){return(bh(n)?i:te)(n,mi(t,3))}function sf(n,t){return ee(yf(n,t),1)}function hf(n,t){return ee(yf(n,t),Sn)}function pf(n,t,r){return r=r===X?1:kc(r),ee(yf(n,t),r)}function _f(n,t){return(bh(n)?r:ys)(n,mi(t,3))}function vf(n,t){return(bh(n)?e:ds)(n,mi(t,3))}function gf(n,t,r,e){n=Hf(n)?n:ra(n),r=r&&!e?kc(r):0;var u=n.length;return r<0&&(r=Gl(u+r,0)),
dc(n)?r<=u&&n.indexOf(t,r)>-1:!!u&&y(n,t,r)>-1}function yf(n,t){return(bh(n)?c:Pe)(n,mi(t,3))}function df(n,t,r,e){return null==n?[]:(bh(t)||(t=null==t?[]:[t]),r=e?X:r,bh(r)||(r=null==r?[]:[r]),He(n,t,r))}function bf(n,t,r){var e=bh(n)?l:j,u=arguments.length<3;return e(n,mi(t,4),r,u,ys)}function wf(n,t,r){var e=bh(n)?s:j,u=arguments.length<3;return e(n,mi(t,4),r,u,ds)}function mf(n,t){return(bh(n)?i:te)(n,Uf(mi(t,3)))}function xf(n){return(bh(n)?Ir:iu)(n)}function jf(n,t,r){return t=(r?Ui(n,t,r):t===X)?1:kc(t),
(bh(n)?Rr:ou)(n,t)}function Af(n){return(bh(n)?zr:cu)(n)}function kf(n){if(null==n)return 0;if(Hf(n))return dc(n)?V(n):n.length;var t=zs(n);return t==Gn||t==tt?n.size:Me(n).length}function Of(n,t,r){var e=bh(n)?h:lu;return r&&Ui(n,t,r)&&(t=X),e(n,mi(t,3))}function If(n,t){if("function"!=typeof t)throw new pl(en);return n=kc(n),function(){if(--n<1)return t.apply(this,arguments)}}function Rf(n,t,r){return t=r?X:t,t=n&&null==t?n.length:t,ai(n,mn,X,X,X,X,t)}function zf(n,t){var r;if("function"!=typeof t)throw new pl(en);
return n=kc(n),function(){return--n>0&&(r=t.apply(this,arguments)),n<=1&&(t=X),r}}function Ef(n,t,r){t=r?X:t;var e=ai(n,yn,X,X,X,X,X,t);return e.placeholder=Ef.placeholder,e}function Sf(n,t,r){t=r?X:t;var e=ai(n,dn,X,X,X,X,X,t);return e.placeholder=Sf.placeholder,e}function Wf(n,t,r){function e(t){var r=h,e=p;return h=p=X,d=t,v=n.apply(e,r)}function u(n){return d=n,g=Ws(f,t),b?e(n):v}function i(n){var r=n-y,e=n-d,u=t-r;return w?Hl(u,_-e):u}function o(n){var r=n-y,e=n-d;return y===X||r>=t||r<0||w&&e>=_;
}function f(){var n=fh();return o(n)?c(n):(g=Ws(f,i(n)),X)}function c(n){return g=X,m&&h?e(n):(h=p=X,v)}function a(){g!==X&&As(g),d=0,h=y=p=g=X}function l(){return g===X?v:c(fh())}function s(){var n=fh(),r=o(n);if(h=arguments,p=this,y=n,r){if(g===X)return u(y);if(w)return As(g),g=Ws(f,t),e(y)}return g===X&&(g=Ws(f,t)),v}var h,p,_,v,g,y,d=0,b=!1,w=!1,m=!0;if("function"!=typeof n)throw new pl(en);return t=Ic(t)||0,fc(r)&&(b=!!r.leading,w="maxWait"in r,_=w?Gl(Ic(r.maxWait)||0,t):_,m="trailing"in r?!!r.trailing:m),
s.cancel=a,s.flush=l,s}function Lf(n){return ai(n,jn)}function Cf(n,t){if("function"!=typeof n||null!=t&&"function"!=typeof t)throw new pl(en);var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;if(i.has(u))return i.get(u);var o=n.apply(this,e);return r.cache=i.set(u,o)||i,o};return r.cache=new(Cf.Cache||sr),r}function Uf(n){if("function"!=typeof n)throw new pl(en);return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:
return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function Bf(n){return zf(2,n)}function Tf(n,t){if("function"!=typeof n)throw new pl(en);return t=t===X?t:kc(t),uu(n,t)}function $f(t,r){if("function"!=typeof t)throw new pl(en);return r=null==r?0:Gl(kc(r),0),uu(function(e){var u=e[r],i=Ou(e,0,r);return u&&a(i,u),n(t,this,i)})}function Df(n,t,r){var e=!0,u=!0;if("function"!=typeof n)throw new pl(en);return fc(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),
Wf(n,t,{leading:e,maxWait:t,trailing:u})}function Mf(n){return Rf(n,1)}function Ff(n,t){return ph(Au(t),n)}function Nf(){if(!arguments.length)return[];var n=arguments[0];return bh(n)?n:[n]}function Pf(n){return Fr(n,sn)}function qf(n,t){return t="function"==typeof t?t:X,Fr(n,sn,t)}function Zf(n){return Fr(n,an|sn)}function Kf(n,t){return t="function"==typeof t?t:X,Fr(n,an|sn,t)}function Vf(n,t){return null==t||Pr(n,t,Pc(t))}function Gf(n,t){return n===t||n!==n&&t!==t}function Hf(n){return null!=n&&oc(n.length)&&!uc(n);
}function Jf(n){return cc(n)&&Hf(n)}function Yf(n){return n===!0||n===!1||cc(n)&&we(n)==Nn}function Qf(n){return cc(n)&&1===n.nodeType&&!gc(n)}function Xf(n){if(null==n)return!0;if(Hf(n)&&(bh(n)||"string"==typeof n||"function"==typeof n.splice||mh(n)||Oh(n)||dh(n)))return!n.length;var t=zs(n);if(t==Gn||t==tt)return!n.size;if(Mi(n))return!Me(n).length;for(var r in n)if(bl.call(n,r))return!1;return!0}function nc(n,t){return Se(n,t)}function tc(n,t,r){r="function"==typeof r?r:X;var e=r?r(n,t):X;return e===X?Se(n,t,X,r):!!e;
}function rc(n){if(!cc(n))return!1;var t=we(n);return t==Zn||t==qn||"string"==typeof n.message&&"string"==typeof n.name&&!gc(n)}function ec(n){return"number"==typeof n&&Zl(n)}function uc(n){if(!fc(n))return!1;var t=we(n);return t==Kn||t==Vn||t==Fn||t==Xn}function ic(n){return"number"==typeof n&&n==kc(n)}function oc(n){return"number"==typeof n&&n>-1&&n%1==0&&n<=Wn}function fc(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function cc(n){return null!=n&&"object"==typeof n}function ac(n,t){
return n===t||Ce(n,t,ji(t))}function lc(n,t,r){return r="function"==typeof r?r:X,Ce(n,t,ji(t),r)}function sc(n){return vc(n)&&n!=+n}function hc(n){if(Es(n))throw new fl(rn);return Ue(n)}function pc(n){return null===n}function _c(n){return null==n}function vc(n){return"number"==typeof n||cc(n)&&we(n)==Hn}function gc(n){if(!cc(n)||we(n)!=Yn)return!1;var t=El(n);if(null===t)return!0;var r=bl.call(t,"constructor")&&t.constructor;return"function"==typeof r&&r instanceof r&&dl.call(r)==jl}function yc(n){
return ic(n)&&n>=-Wn&&n<=Wn}function dc(n){return"string"==typeof n||!bh(n)&&cc(n)&&we(n)==rt}function bc(n){return"symbol"==typeof n||cc(n)&&we(n)==et}function wc(n){return n===X}function mc(n){return cc(n)&&zs(n)==it}function xc(n){return cc(n)&&we(n)==ot}function jc(n){if(!n)return[];if(Hf(n))return dc(n)?G(n):Tu(n);if(Ul&&n[Ul])return D(n[Ul]());var t=zs(n);return(t==Gn?M:t==tt?P:ra)(n)}function Ac(n){if(!n)return 0===n?n:0;if(n=Ic(n),n===Sn||n===-Sn){return(n<0?-1:1)*Ln}return n===n?n:0}function kc(n){
var t=Ac(n),r=t%1;return t===t?r?t-r:t:0}function Oc(n){return n?Mr(kc(n),0,Un):0}function Ic(n){if("number"==typeof n)return n;if(bc(n))return Cn;if(fc(n)){var t="function"==typeof n.valueOf?n.valueOf():n;n=fc(t)?t+"":t}if("string"!=typeof n)return 0===n?n:+n;n=R(n);var r=qt.test(n);return r||Kt.test(n)?Xr(n.slice(2),r?2:8):Pt.test(n)?Cn:+n}function Rc(n){return $u(n,qc(n))}function zc(n){return n?Mr(kc(n),-Wn,Wn):0===n?n:0}function Ec(n){return null==n?"":vu(n)}function Sc(n,t){var r=gs(n);return null==t?r:Cr(r,t);
}function Wc(n,t){return v(n,mi(t,3),ue)}function Lc(n,t){return v(n,mi(t,3),oe)}function Cc(n,t){return null==n?n:bs(n,mi(t,3),qc)}function Uc(n,t){return null==n?n:ws(n,mi(t,3),qc)}function Bc(n,t){return n&&ue(n,mi(t,3))}function Tc(n,t){return n&&oe(n,mi(t,3))}function $c(n){return null==n?[]:fe(n,Pc(n))}function Dc(n){return null==n?[]:fe(n,qc(n))}function Mc(n,t,r){var e=null==n?X:_e(n,t);return e===X?r:e}function Fc(n,t){return null!=n&&Ri(n,t,xe)}function Nc(n,t){return null!=n&&Ri(n,t,je);
}function Pc(n){return Hf(n)?Or(n):Me(n)}function qc(n){return Hf(n)?Or(n,!0):Fe(n)}function Zc(n,t){var r={};return t=mi(t,3),ue(n,function(n,e,u){Br(r,t(n,e,u),n)}),r}function Kc(n,t){var r={};return t=mi(t,3),ue(n,function(n,e,u){Br(r,e,t(n,e,u))}),r}function Vc(n,t){return Gc(n,Uf(mi(t)))}function Gc(n,t){if(null==n)return{};var r=c(di(n),function(n){return[n]});return t=mi(t),Ye(n,r,function(n,r){return t(n,r[0])})}function Hc(n,t,r){t=ku(t,n);var e=-1,u=t.length;for(u||(u=1,n=X);++e<u;){var i=null==n?X:n[no(t[e])];
i===X&&(e=u,i=r),n=uc(i)?i.call(n):i}return n}function Jc(n,t,r){return null==n?n:fu(n,t,r)}function Yc(n,t,r,e){return e="function"==typeof e?e:X,null==n?n:fu(n,t,r,e)}function Qc(n,t,e){var u=bh(n),i=u||mh(n)||Oh(n);if(t=mi(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:fc(n)&&uc(o)?gs(El(n)):{}}return(i?r:ue)(n,function(n,r,u){return t(e,n,r,u)}),e}function Xc(n,t){return null==n||yu(n,t)}function na(n,t,r){return null==n?n:du(n,t,Au(r))}function ta(n,t,r,e){return e="function"==typeof e?e:X,
null==n?n:du(n,t,Au(r),e)}function ra(n){return null==n?[]:E(n,Pc(n))}function ea(n){return null==n?[]:E(n,qc(n))}function ua(n,t,r){return r===X&&(r=t,t=X),r!==X&&(r=Ic(r),r=r===r?r:0),t!==X&&(t=Ic(t),t=t===t?t:0),Mr(Ic(n),t,r)}function ia(n,t,r){return t=Ac(t),r===X?(r=t,t=0):r=Ac(r),n=Ic(n),Ae(n,t,r)}function oa(n,t,r){if(r&&"boolean"!=typeof r&&Ui(n,t,r)&&(t=r=X),r===X&&("boolean"==typeof t?(r=t,t=X):"boolean"==typeof n&&(r=n,n=X)),n===X&&t===X?(n=0,t=1):(n=Ac(n),t===X?(t=n,n=0):t=Ac(t)),n>t){
var e=n;n=t,t=e}if(r||n%1||t%1){var u=Ql();return Hl(n+u*(t-n+Qr("1e-"+((u+"").length-1))),t)}return tu(n,t)}function fa(n){return Qh(Ec(n).toLowerCase())}function ca(n){return n=Ec(n),n&&n.replace(Gt,ve).replace(Dr,"")}function aa(n,t,r){n=Ec(n),t=vu(t);var e=n.length;r=r===X?e:Mr(kc(r),0,e);var u=r;return r-=t.length,r>=0&&n.slice(r,u)==t}function la(n){return n=Ec(n),n&&At.test(n)?n.replace(xt,ge):n}function sa(n){return n=Ec(n),n&&Wt.test(n)?n.replace(St,"\\$&"):n}function ha(n,t,r){n=Ec(n),t=kc(t);
var e=t?V(n):0;if(!t||e>=t)return n;var u=(t-e)/2;return ri(Nl(u),r)+n+ri(Fl(u),r)}function pa(n,t,r){n=Ec(n),t=kc(t);var e=t?V(n):0;return t&&e<t?n+ri(t-e,r):n}function _a(n,t,r){n=Ec(n),t=kc(t);var e=t?V(n):0;return t&&e<t?ri(t-e,r)+n:n}function va(n,t,r){return r||null==t?t=0:t&&(t=+t),Yl(Ec(n).replace(Lt,""),t||0)}function ga(n,t,r){return t=(r?Ui(n,t,r):t===X)?1:kc(t),eu(Ec(n),t)}function ya(){var n=arguments,t=Ec(n[0]);return n.length<3?t:t.replace(n[1],n[2])}function da(n,t,r){return r&&"number"!=typeof r&&Ui(n,t,r)&&(t=r=X),
(r=r===X?Un:r>>>0)?(n=Ec(n),n&&("string"==typeof t||null!=t&&!Ah(t))&&(t=vu(t),!t&&T(n))?Ou(G(n),0,r):n.split(t,r)):[]}function ba(n,t,r){return n=Ec(n),r=null==r?0:Mr(kc(r),0,n.length),t=vu(t),n.slice(r,r+t.length)==t}function wa(n,t,r){var e=Z.templateSettings;r&&Ui(n,t,r)&&(t=X),n=Ec(n),t=Sh({},t,e,li);var u,i,o=Sh({},t.imports,e.imports,li),f=Pc(o),c=E(o,f),a=0,l=t.interpolate||Ht,s="__p += '",h=sl((t.escape||Ht).source+"|"+l.source+"|"+(l===It?Ft:Ht).source+"|"+(t.evaluate||Ht).source+"|$","g"),p="//# sourceURL="+(bl.call(t,"sourceURL")?(t.sourceURL+"").replace(/\s/g," "):"lodash.templateSources["+ ++Zr+"]")+"\n";
t&&l.push(p),a.push(h)}else u(l,p,r)||(l!==a&&l.push(p),a.push(h))}return a}function yu(n,t){t=ku(t,n);var r=-1,e=t.length;if(!e)return!0;for(var u=null==n||"object"!=typeof n&&"function"!=typeof n;++r<e;){var i=t[r];if("string"==typeof i){if("__proto__"===i&&!bl.call(n,"__proto__"))return!1;if("constructor"===i&&r+1<e&&"string"==typeof t[r+1]&&"prototype"===t[r+1]){if(u&&0===r)continue;return!1}}}var o=Gi(n,t);return null==o||delete o[no(jo(t))]}function du(n,t,r,e){return fu(n,t,r(_e(n,t)),e)}function bu(n,t,r,e){
for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?au(n,e?0:i,e?i+1:u):au(n,e?i+1:0,e?u:i)}function wu(n,t){var r=n;return r instanceof Ct&&(r=r.value()),l(t,function(n,t){return t.func.apply(t.thisArg,a([n],t.args))},r)}function mu(n,t,r){var e=n.length;if(e<2)return e?gu(n[0]):[];for(var u=-1,i=il(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=Hr(i[u]||o,n[f],t,r));return gu(ee(i,1),t,r)}function xu(n,t,r){for(var e=-1,u=n.length,i=t.length,o={};++e<u;){r(o,n[e],e<i?t[e]:X)}return o;
}function ju(n){return Jf(n)?n:[]}function Au(n){return"function"==typeof n?n:La}function ku(n,t){return bh(n)?n:Bi(n,t)?[n]:Cs(Ec(n))}function Ou(n,t,r){var e=n.length;return r=r===X?e:r,!t&&r>=e?n:au(n,t,r)}function Iu(n,t){if(t)return n.slice();var r=n.length,e=zl?zl(r):new n.constructor(r);return n.copy(e),e}function Ru(n){var t=new n.constructor(n.byteLength);return new Rl(t).set(new Rl(n)),t}function zu(n,t){return new n.constructor(t?Ru(n.buffer):n.buffer,n.byteOffset,n.byteLength)}function Eu(n){
var t=new n.constructor(n.source,Nt.exec(n));return t.lastIndex=n.lastIndex,t}function Su(n){return _s?ll(_s.call(n)):{}}function Wu(n,t){return new n.constructor(t?Ru(n.buffer):n.buffer,n.byteOffset,n.length)}function Lu(n,t){if(n!==t){var r=n!==X,e=null===n,u=n===n,i=bc(n),o=t!==X,f=null===t,c=t===t,a=bc(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&n<t||a&&r&&u&&!e&&!i||f&&r&&u||!o&&u||!c)return-1}return 0}function Cu(n,t,r){for(var e=-1,u=n.criteria,i=t.criteria,o=u.length,f=r.length;++e<o;){
var c=Lu(u[e],i[e]);if(c){if(e>=f)return c;return c*("desc"==r[e]?-1:1)}}return n.index-t.index}function Uu(n,t,r,e){for(var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Gl(i-o,0),l=il(c+a),s=!e;++f<c;)l[f]=t[f];for(;++u<o;)(s||u<i)&&(l[r[u]]=n[u]);for(;a--;)l[f++]=n[u++];return l}function Bu(n,t,r,e){for(var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Gl(i-f,0),s=il(l+a),h=!e;++u<l;)s[u]=n[u];for(var p=u;++c<a;)s[p+c]=t[c];for(;++o<f;)(h||u<i)&&(s[p+r[o]]=n[u++]);return s}function Tu(n,t){
var r=-1,e=n.length;for(t||(t=il(e));++r<e;)t[r]=n[r];return t}function $u(n,t,r,e){var u=!r;r||(r={});for(var i=-1,o=t.length;++i<o;){var f=t[i],c=e?e(r[f],n[f],f,r,n):X;c===X&&(c=n[f]),u?Br(r,f,c):Sr(r,f,c)}return r}function Du(n,t){return $u(n,Is(n),t)}function Mu(n,t){return $u(n,Rs(n),t)}function Fu(n,r){return function(e,u){var i=bh(e)?t:Lr,o=r?r():{};return i(e,n,mi(u,2),o)}}function Nu(n){return uu(function(t,r){var e=-1,u=r.length,i=u>1?r[u-1]:X,o=u>2?r[2]:X;for(i=n.length>3&&"function"==typeof i?(u--,
i):X,o&&Ui(r[0],r[1],o)&&(i=u<3?X:i,u=1),t=ll(t);++e<u;){var f=r[e];f&&n(t,f,e,i)}return t})}function Pu(n,t){return function(r,e){if(null==r)return r;if(!Hf(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=ll(r);(t?i--:++i<u)&&e(o[i],i,o)!==!1;);return r}}function qu(n){return function(t,r,e){for(var u=-1,i=ll(t),o=e(t),f=o.length;f--;){var c=o[n?f:++u];if(r(i[c],c,i)===!1)break}return t}}function Zu(n,t,r){function e(){return(this&&this!==re&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=t&_n,i=Gu(n);
return e}function Ku(n){return function(t){t=Ec(t);var r=T(t)?G(t):X,e=r?r[0]:t.charAt(0),u=r?Ou(r,1).join(""):t.slice(1);return e[n]()+u}}function Vu(n){return function(t){return l(Ra(ca(t).replace($r,"")),n,"")}}function Gu(n){return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);
case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=gs(n.prototype),e=n.apply(r,t);return fc(e)?e:r}}function Hu(t,r,e){function u(){for(var o=arguments.length,f=il(o),c=o,a=wi(u);c--;)f[c]=arguments[c];var l=o<3&&f[0]!==a&&f[o-1]!==a?[]:N(f,a);return o-=l.length,o<e?oi(t,r,Qu,u.placeholder,X,f,l,X,X,e-o):n(this&&this!==re&&this instanceof u?i:t,this,f)}var i=Gu(t);return u}function Ju(n){return function(t,r,e){var u=ll(t);if(!Hf(t)){var i=mi(r,3);t=Pc(t),r=function(n){return i(u[n],n,u);
}}var o=n(t,r,e);return o>-1?u[i?t[o]:o]:X}}function Yu(n){return gi(function(t){var r=t.length,e=r,u=Y.prototype.thru;for(n&&t.reverse();e--;){var i=t[e];if("function"!=typeof i)throw new pl(en);if(u&&!o&&"wrapper"==bi(i))var o=new Y([],!0)}for(e=o?e:r;++e<r;){i=t[e];var f=bi(i),c="wrapper"==f?Os(i):X;o=c&&$i(c[0])&&c[1]==(mn|yn|bn|xn)&&!c[4].length&&1==c[9]?o[bi(c[0])].apply(o,c[3]):1==i.length&&$i(i)?o[f]():o.thru(i)}return function(){var n=arguments,e=n[0];if(o&&1==n.length&&bh(e))return o.plant(e).value();
for(var u=0,i=r?t[u].apply(this,n):e;++u<r;)i=t[u].call(this,i);return i}})}function Qu(n,t,r,e,u,i,o,f,c,a){function l(){for(var y=arguments.length,d=il(y),b=y;b--;)d[b]=arguments[b];if(_)var w=wi(l),m=C(d,w);if(e&&(d=Uu(d,e,u,_)),i&&(d=Bu(d,i,o,_)),y-=m,_&&y<a){return oi(n,t,Qu,l.placeholder,r,d,N(d,w),f,c,a-y)}var x=h?r:this,j=p?x[n]:n;return y=d.length,f?d=Hi(d,f):v&&y>1&&d.reverse(),s&&c<y&&(d.length=c),this&&this!==re&&this instanceof l&&(j=g||Gu(j)),j.apply(x,d)}var s=t&mn,h=t&_n,p=t&vn,_=t&(yn|dn),v=t&jn,g=p?X:Gu(n);
return l}function Xu(n,t){return function(r,e){return Oe(r,n,t(e),{})}}function ni(n,t){return function(r,e){var u;if(r===X&&e===X)return t;if(r!==X&&(u=r),e!==X){if(u===X)return e;"string"==typeof r||"string"==typeof e?(r=vu(r),e=vu(e)):(r=_u(r),e=_u(e)),u=n(r,e)}return u}}function ti(t){return gi(function(r){return r=c(r,z(mi())),uu(function(e){var u=this;return t(r,function(t){return n(t,u,e)})})})}function ri(n,t){t=t===X?" ":vu(t);var r=t.length;if(r<2)return r?eu(t,n):t;var e=eu(t,Fl(n/V(t)));
return T(t)?Ou(G(e),0,n).join(""):e.slice(0,n)}function ei(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=il(l+c),h=this&&this!==re&&this instanceof i?f:t;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++r];return n(h,o?e:this,s)}var o=r&_n,f=Gu(t);return i}function ui(n){return function(t,r,e){return e&&"number"!=typeof e&&Ui(t,r,e)&&(r=e=X),t=Ac(t),r===X?(r=t,t=0):r=Ac(r),e=e===X?t<r?1:-1:Ac(e),ru(t,r,e,n)}}function ii(n){return function(t,r){return"string"==typeof t&&"string"==typeof r||(t=Ic(t),
r=Ic(r)),n(t,r)}}function oi(n,t,r,e,u,i,o,f,c,a){var l=t&yn,s=l?o:X,h=l?X:o,p=l?i:X,_=l?X:i;t|=l?bn:wn,t&=~(l?wn:bn),t&gn||(t&=~(_n|vn));var v=[n,t,u,p,s,_,h,f,c,a],g=r.apply(X,v);return $i(n)&&Ss(g,v),g.placeholder=e,Yi(g,n,t)}function fi(n){var t=al[n];return function(n,r){if(n=Ic(n),r=null==r?0:Hl(kc(r),292),r&&Zl(n)){var e=(Ec(n)+"e").split("e");return e=(Ec(t(e[0]+"e"+(+e[1]+r)))+"e").split("e"),+(e[0]+"e"+(+e[1]-r))}return t(n)}}function ci(n){return function(t){var r=zs(t);return r==Gn?M(t):r==tt?q(t):I(t,n(t));
}}function ai(n,t,r,e,u,i,o,f){var c=t&vn;if(!c&&"function"!=typeof n)throw new pl(en);var a=e?e.length:0;if(a||(t&=~(bn|wn),e=u=X),o=o===X?o:Gl(kc(o),0),f=f===X?f:kc(f),a-=u?u.length:0,t&wn){var l=e,s=u;e=u=X}var h=c?X:Os(n),p=[n,t,r,e,u,l,s,i,o,f];if(h&&qi(p,h),n=p[0],t=p[1],r=p[2],e=p[3],u=p[4],f=p[9]=p[9]===X?c?0:n.length:Gl(p[9]-a,0),!f&&t&(yn|dn)&&(t&=~(yn|dn)),t&&t!=_n)_=t==yn||t==dn?Hu(n,t,f):t!=bn&&t!=(_n|bn)||u.length?Qu.apply(X,p):ei(n,t,r,e);else var _=Zu(n,t,r);return Yi((h?ms:Ss)(_,p),n,t);
}function li(n,t,r,e){return n===X||Gf(n,gl[r])&&!bl.call(e,r)?t:n}function si(n,t,r,e,u,i){return fc(n)&&fc(t)&&(i.set(t,n),Ke(n,t,X,si,i),i.delete(t)),n}function hi(n){return gc(n)?X:n}function pi(n,t,r,e,u,i){var o=r&hn,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return!1;var a=i.get(n),l=i.get(t);if(a&&l)return a==t&&l==n;var s=-1,p=!0,_=r&pn?new yr:X;for(i.set(n,t),i.set(t,n);++s<f;){var v=n[s],g=t[s];if(e)var y=o?e(g,v,s,t,n,i):e(v,g,s,n,t,i);if(y!==X){if(y)continue;p=!1;break}if(_){if(!h(t,function(n,t){
if(!S(_,t)&&(v===n||u(v,n,r,e,i)))return _.push(t)})){p=!1;break}}else if(v!==g&&!u(v,g,r,e,i)){p=!1;break}}return i.delete(n),i.delete(t),p}function _i(n,t,r,e,u,i,o){switch(r){case ct:if(n.byteLength!=t.byteLength||n.byteOffset!=t.byteOffset)return!1;n=n.buffer,t=t.buffer;case ft:return!(n.byteLength!=t.byteLength||!i(new Rl(n),new Rl(t)));case Nn:case Pn:case Hn:return Gf(+n,+t);case Zn:return n.name==t.name&&n.message==t.message;case nt:case rt:return n==t+"";case Gn:var f=M;case tt:var c=e&hn;
if(f||(f=P),n.size!=t.size&&!c)return!1;var a=o.get(n);if(a)return a==t;e|=pn,o.set(n,t);var l=pi(f(n),f(t),e,u,i,o);return o.delete(n),l;case et:if(_s)return _s.call(n)==_s.call(t)}return!1}function vi(n,t,r,e,u,i){var o=r&hn,f=yi(n),c=f.length;if(c!=yi(t).length&&!o)return!1;for(var a=c;a--;){var l=f[a];if(!(o?l in t:bl.call(t,l)))return!1}var s=i.get(n),h=i.get(t);if(s&&h)return s==t&&h==n;var p=!0;i.set(n,t),i.set(t,n);for(var _=o;++a<c;){l=f[a];var v=n[l],g=t[l];if(e)var y=o?e(g,v,l,t,n,i):e(v,g,l,n,t,i);
if(!(y===X?v===g||u(v,g,r,e,i):y)){p=!1;break}_||(_="constructor"==l)}if(p&&!_){var d=n.constructor,b=t.constructor;d!=b&&"constructor"in n&&"constructor"in t&&!("function"==typeof d&&d instanceof d&&"function"==typeof b&&b instanceof b)&&(p=!1)}return i.delete(n),i.delete(t),p}function gi(n){return Ls(Vi(n,X,_o),n+"")}function yi(n){return de(n,Pc,Is)}function di(n){return de(n,qc,Rs)}function bi(n){for(var t=n.name+"",r=fs[t],e=bl.call(fs,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name;
}return t}function wi(n){return(bl.call(Z,"placeholder")?Z:n).placeholder}function mi(){var n=Z.iteratee||Ca;return n=n===Ca?De:n,arguments.length?n(arguments[0],arguments[1]):n}function xi(n,t){var r=n.__data__;return Ti(t)?r["string"==typeof t?"string":"hash"]:r.map}function ji(n){for(var t=Pc(n),r=t.length;r--;){var e=t[r],u=n[e];t[r]=[e,u,Fi(u)]}return t}function Ai(n,t){var r=B(n,t);return Ue(r)?r:X}function ki(n){var t=bl.call(n,Bl),r=n[Bl];try{n[Bl]=X;var e=!0}catch(n){}var u=xl.call(n);return e&&(t?n[Bl]=r:delete n[Bl]),
u}function Oi(n,t,r){for(var e=-1,u=r.length;++e<u;){var i=r[e],o=i.size;switch(i.type){case"drop":n+=o;break;case"dropRight":t-=o;break;case"take":t=Hl(t,n+o);break;case"takeRight":n=Gl(n,t-o)}}return{start:n,end:t}}function Ii(n){var t=n.match(Bt);return t?t[1].split(Tt):[]}function Ri(n,t,r){t=ku(t,n);for(var e=-1,u=t.length,i=!1;++e<u;){var o=no(t[e]);if(!(i=null!=n&&r(n,o)))break;n=n[o]}return i||++e!=u?i:(u=null==n?0:n.length,!!u&&oc(u)&&Ci(o,u)&&(bh(n)||dh(n)))}function zi(n){var t=n.length,r=new n.constructor(t);
return t&&"string"==typeof n[0]&&bl.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Ei(n){return"function"!=typeof n.constructor||Mi(n)?{}:gs(El(n))}function Si(n,t,r){var e=n.constructor;switch(t){case ft:return Ru(n);case Nn:case Pn:return new e(+n);case ct:return zu(n,r);case at:case lt:case st:case ht:case pt:case _t:case vt:case gt:case yt:return Wu(n,r);case Gn:return new e;case Hn:case rt:return new e(n);case nt:return Eu(n);case tt:return new e;case et:return Su(n)}}function Wi(n,t){
var r=t.length;if(!r)return n;var e=r-1;return t[e]=(r>1?"& ":"")+t[e],t=t.join(r>2?", ":" "),n.replace(Ut,"{\n/* [wrapped with "+t+"] */\n")}function Li(n){return bh(n)||dh(n)||!!(Cl&&n&&n[Cl])}function Ci(n,t){var r=typeof n;return t=null==t?Wn:t,!!t&&("number"==r||"symbol"!=r&&Vt.test(n))&&n>-1&&n%1==0&&n<t}function Ui(n,t,r){if(!fc(r))return!1;var e=typeof t;return!!("number"==e?Hf(r)&&Ci(t,r.length):"string"==e&&t in r)&&Gf(r[t],n)}function Bi(n,t){if(bh(n))return!1;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!bc(n))||(zt.test(n)||!Rt.test(n)||null!=t&&n in ll(t));
}function Ti(n){var t=typeof n;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==n:null===n}function $i(n){var t=bi(n),r=Z[t];if("function"!=typeof r||!(t in Ct.prototype))return!1;if(n===r)return!0;var e=Os(r);return!!e&&n===e[0]}function Di(n){return!!ml&&ml in n}function Mi(n){var t=n&&n.constructor;return n===("function"==typeof t&&t.prototype||gl)}function Fi(n){return n===n&&!fc(n)}function Ni(n,t){return function(r){return null!=r&&(r[n]===t&&(t!==X||n in ll(r)))}}function Pi(n){
var t=Cf(n,function(n){return r.size===fn&&r.clear(),n}),r=t.cache;return t}function qi(n,t){var r=n[1],e=t[1],u=r|e,i=u<(_n|vn|mn),o=e==mn&&r==yn||e==mn&&r==xn&&n[7].length<=t[8]||e==(mn|xn)&&t[7].length<=t[8]&&r==yn;if(!i&&!o)return n;e&_n&&(n[2]=t[2],u|=r&_n?0:gn);var f=t[3];if(f){var c=n[3];n[3]=c?Uu(c,f,t[4]):f,n[4]=c?N(n[3],cn):t[4]}return f=t[5],f&&(c=n[5],n[5]=c?Bu(c,f,t[6]):f,n[6]=c?N(n[5],cn):t[6]),f=t[7],f&&(n[7]=f),e&mn&&(n[8]=null==n[8]?t[8]:Hl(n[8],t[8])),null==n[9]&&(n[9]=t[9]),n[0]=t[0],
n[1]=u,n}function Zi(n){var t=[];if(null!=n)for(var r in ll(n))t.push(r);return t}function Ki(n){return xl.call(n)}function Vi(t,r,e){return r=Gl(r===X?t.length-1:r,0),function(){for(var u=arguments,i=-1,o=Gl(u.length-r,0),f=il(o);++i<o;)f[i]=u[r+i];i=-1;for(var c=il(r+1);++i<r;)c[i]=u[i];return c[r]=e(f),n(t,this,c)}}function Gi(n,t){return t.length<2?n:_e(n,au(t,0,-1))}function Hi(n,t){for(var r=n.length,e=Hl(t.length,r),u=Tu(n);e--;){var i=t[e];n[e]=Ci(i,r)?u[i]:X}return n}function Ji(n,t){if(("constructor"!==t||"function"!=typeof n[t])&&"__proto__"!=t)return n[t];
}function Yi(n,t,r){var e=t+"";return Ls(n,Wi(e,ro(Ii(e),r)))}function Qi(n){var t=0,r=0;return function(){var e=Jl(),u=In-(e-r);if(r=e,u>0){if(++t>=On)return arguments[0]}else t=0;return n.apply(X,arguments)}}function Xi(n,t){var r=-1,e=n.length,u=e-1;for(t=t===X?e:t;++r<t;){var i=tu(r,u),o=n[i];n[i]=n[r],n[r]=o}return n.length=t,n}function no(n){if("string"==typeof n||bc(n))return n;var t=n+"";return"0"==t&&1/n==-Sn?"-0":t}function to(n){if(null!=n){try{return dl.call(n)}catch(n){}try{return n+"";
}catch(n){}}return""}function ro(n,t){return r($n,function(r){var e="_."+r[0];t&r[1]&&!o(n,e)&&n.push(e)}),n.sort()}function eo(n){if(n instanceof Ct)return n.clone();var t=new Y(n.__wrapped__,n.__chain__);return t.__actions__=Tu(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function uo(n,t,r){t=(r?Ui(n,t,r):t===X)?1:Gl(kc(t),0);var e=null==n?0:n.length;if(!e||t<1)return[];for(var u=0,i=0,o=il(Fl(e/t));u<e;)o[i++]=au(n,u,u+=t);return o}function io(n){for(var t=-1,r=null==n?0:n.length,e=0,u=[];++t<r;){
var i=n[t];i&&(u[e++]=i)}return u}function oo(){var n=arguments.length;if(!n)return[];for(var t=il(n-1),r=arguments[0],e=n;e--;)t[e-1]=arguments[e];return a(bh(r)?Tu(r):[r],ee(t,1))}function fo(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===X?1:kc(t),au(n,t<0?0:t,e)):[]}function co(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===X?1:kc(t),t=e-t,au(n,0,t<0?0:t)):[]}function ao(n,t){return n&&n.length?bu(n,mi(t,3),!0,!0):[]}function lo(n,t){return n&&n.length?bu(n,mi(t,3),!0):[]}function so(n,t,r,e){
var u=null==n?0:n.length;return u?(r&&"number"!=typeof r&&Ui(n,t,r)&&(r=0,e=u),ne(n,t,r,e)):[]}function ho(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=null==r?0:kc(r);return u<0&&(u=Gl(e+u,0)),g(n,mi(t,3),u)}function po(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==X&&(u=kc(r),u=r<0?Gl(e+u,0):Hl(u,e-1)),g(n,mi(t,3),u,!0)}function _o(n){return(null==n?0:n.length)?ee(n,1):[]}function vo(n){return(null==n?0:n.length)?ee(n,Sn):[]}function go(n,t){return(null==n?0:n.length)?(t=t===X?1:kc(t),
ee(n,t)):[]}function yo(n){for(var t=-1,r=null==n?0:n.length,e={};++t<r;){var u=n[t];e[u[0]]=u[1]}return e}function bo(n){return n&&n.length?n[0]:X}function wo(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=null==r?0:kc(r);return u<0&&(u=Gl(e+u,0)),y(n,t,u)}function mo(n){return(null==n?0:n.length)?au(n,0,-1):[]}function xo(n,t){return null==n?"":Kl.call(n,t)}function jo(n){var t=null==n?0:n.length;return t?n[t-1]:X}function Ao(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;return r!==X&&(u=kc(r),
u=u<0?Gl(e+u,0):Hl(u,e-1)),t===t?K(n,t,u):g(n,b,u,!0)}function ko(n,t){return n&&n.length?Ge(n,kc(t)):X}function Oo(n,t){return n&&n.length&&t&&t.length?Xe(n,t):n}function Io(n,t,r){return n&&n.length&&t&&t.length?Xe(n,t,mi(r,2)):n}function Ro(n,t,r){return n&&n.length&&t&&t.length?Xe(n,t,X,r):n}function zo(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=mi(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),u.push(e))}return nu(n,u),r}function Eo(n){return null==n?n:Xl.call(n)}function So(n,t,r){
var e=null==n?0:n.length;return e?(r&&"number"!=typeof r&&Ui(n,t,r)?(t=0,r=e):(t=null==t?0:kc(t),r=r===X?e:kc(r)),au(n,t,r)):[]}function Wo(n,t){return su(n,t)}function Lo(n,t,r){return hu(n,t,mi(r,2))}function Co(n,t){var r=null==n?0:n.length;if(r){var e=su(n,t);if(e<r&&Gf(n[e],t))return e}return-1}function Uo(n,t){return su(n,t,!0)}function Bo(n,t,r){return hu(n,t,mi(r,2),!0)}function To(n,t){if(null==n?0:n.length){var r=su(n,t,!0)-1;if(Gf(n[r],t))return r}return-1}function $o(n){return n&&n.length?pu(n):[];
}function Do(n,t){return n&&n.length?pu(n,mi(t,2)):[]}function Mo(n){var t=null==n?0:n.length;return t?au(n,1,t):[]}function Fo(n,t,r){return n&&n.length?(t=r||t===X?1:kc(t),au(n,0,t<0?0:t)):[]}function No(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===X?1:kc(t),t=e-t,au(n,t<0?0:t,e)):[]}function Po(n,t){return n&&n.length?bu(n,mi(t,3),!1,!0):[]}function qo(n,t){return n&&n.length?bu(n,mi(t,3)):[]}function Zo(n){return n&&n.length?gu(n):[]}function Ko(n,t){return n&&n.length?gu(n,mi(t,2)):[]}
function Vo(n,t){return t="function"==typeof t?t:X,n&&n.length?gu(n,X,t):[]}function Go(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){if(Jf(n))return t=Gl(n.length,t),!0}),O(t,function(t){return c(n,m(t))})}function Ho(t,r){if(!t||!t.length)return[];var e=Go(t);return null==r?e:c(e,function(t){return n(r,X,t)})}function Jo(n,t){return xu(n||[],t||[],Sr)}function Yo(n,t){return xu(n||[],t||[],fu)}function Qo(n){var t=Z(n);return t.__chain__=!0,t}function Xo(n,t){return t(n),n}function nf(n,t){
return t(n)}function tf(){return Qo(this)}function rf(){return new Y(this.value(),this.__chain__)}function ef(){this.__values__===X&&(this.__values__=jc(this.value()));var n=this.__index__>=this.__values__.length;return{done:n,value:n?X:this.__values__[this.__index__++]}}function uf(){return this}function of(n){for(var t,r=this;r instanceof J;){var e=eo(r);e.__index__=0,e.__values__=X,t?u.__wrapped__=e:t=e;var u=e;r=r.__wrapped__}return u.__wrapped__=n,t}function ff(){var n=this.__wrapped__;if(n instanceof Ct){
var t=n;return this.__actions__.length&&(t=new Ct(this)),t=t.reverse(),t.__actions__.push({func:nf,args:[Eo],thisArg:X}),new Y(t,this.__chain__)}return this.thru(Eo)}function cf(){return wu(this.__wrapped__,this.__actions__)}function af(n,t,r){var e=bh(n)?u:Jr;return r&&Ui(n,t,r)&&(t=X),e(n,mi(t,3))}function lf(n,t){return(bh(n)?i:te)(n,mi(t,3))}function sf(n,t){return ee(yf(n,t),1)}function hf(n,t){return ee(yf(n,t),Sn)}function pf(n,t,r){return r=r===X?1:kc(r),ee(yf(n,t),r)}function _f(n,t){return(bh(n)?r:ys)(n,mi(t,3));
}function vf(n,t){return(bh(n)?e:ds)(n,mi(t,3))}function gf(n,t,r,e){n=Hf(n)?n:ra(n),r=r&&!e?kc(r):0;var u=n.length;return r<0&&(r=Gl(u+r,0)),dc(n)?r<=u&&n.indexOf(t,r)>-1:!!u&&y(n,t,r)>-1}function yf(n,t){return(bh(n)?c:Pe)(n,mi(t,3))}function df(n,t,r,e){return null==n?[]:(bh(t)||(t=null==t?[]:[t]),r=e?X:r,bh(r)||(r=null==r?[]:[r]),He(n,t,r))}function bf(n,t,r){var e=bh(n)?l:j,u=arguments.length<3;return e(n,mi(t,4),r,u,ys)}function wf(n,t,r){var e=bh(n)?s:j,u=arguments.length<3;return e(n,mi(t,4),r,u,ds);
}function mf(n,t){return(bh(n)?i:te)(n,Uf(mi(t,3)))}function xf(n){return(bh(n)?Ir:iu)(n)}function jf(n,t,r){return t=(r?Ui(n,t,r):t===X)?1:kc(t),(bh(n)?Rr:ou)(n,t)}function Af(n){return(bh(n)?zr:cu)(n)}function kf(n){if(null==n)return 0;if(Hf(n))return dc(n)?V(n):n.length;var t=zs(n);return t==Gn||t==tt?n.size:Me(n).length}function Of(n,t,r){var e=bh(n)?h:lu;return r&&Ui(n,t,r)&&(t=X),e(n,mi(t,3))}function If(n,t){if("function"!=typeof t)throw new pl(en);return n=kc(n),function(){if(--n<1)return t.apply(this,arguments);
}}function Rf(n,t,r){return t=r?X:t,t=n&&null==t?n.length:t,ai(n,mn,X,X,X,X,t)}function zf(n,t){var r;if("function"!=typeof t)throw new pl(en);return n=kc(n),function(){return--n>0&&(r=t.apply(this,arguments)),n<=1&&(t=X),r}}function Ef(n,t,r){t=r?X:t;var e=ai(n,yn,X,X,X,X,X,t);return e.placeholder=Ef.placeholder,e}function Sf(n,t,r){t=r?X:t;var e=ai(n,dn,X,X,X,X,X,t);return e.placeholder=Sf.placeholder,e}function Wf(n,t,r){function e(t){var r=h,e=p;return h=p=X,d=t,v=n.apply(e,r)}function u(n){return d=n,
g=Ws(f,t),b?e(n):v}function i(n){var r=n-y,e=n-d,u=t-r;return w?Hl(u,_-e):u}function o(n){var r=n-y,e=n-d;return y===X||r>=t||r<0||w&&e>=_}function f(){var n=fh();return o(n)?c(n):(g=Ws(f,i(n)),X)}function c(n){return g=X,m&&h?e(n):(h=p=X,v)}function a(){g!==X&&As(g),d=0,h=y=p=g=X}function l(){return g===X?v:c(fh())}function s(){var n=fh(),r=o(n);if(h=arguments,p=this,y=n,r){if(g===X)return u(y);if(w)return As(g),g=Ws(f,t),e(y)}return g===X&&(g=Ws(f,t)),v}var h,p,_,v,g,y,d=0,b=!1,w=!1,m=!0;if("function"!=typeof n)throw new pl(en);
return t=Ic(t)||0,fc(r)&&(b=!!r.leading,w="maxWait"in r,_=w?Gl(Ic(r.maxWait)||0,t):_,m="trailing"in r?!!r.trailing:m),s.cancel=a,s.flush=l,s}function Lf(n){return ai(n,jn)}function Cf(n,t){if("function"!=typeof n||null!=t&&"function"!=typeof t)throw new pl(en);var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;if(i.has(u))return i.get(u);var o=n.apply(this,e);return r.cache=i.set(u,o)||i,o};return r.cache=new(Cf.Cache||sr),r}function Uf(n){if("function"!=typeof n)throw new pl(en);
return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function Bf(n){return zf(2,n)}function Tf(n,t){if("function"!=typeof n)throw new pl(en);return t=t===X?t:kc(t),uu(n,t)}function $f(t,r){if("function"!=typeof t)throw new pl(en);return r=null==r?0:Gl(kc(r),0),uu(function(e){var u=e[r],i=Ou(e,0,r);return u&&a(i,u),n(t,this,i)})}function Df(n,t,r){
var e=!0,u=!0;if("function"!=typeof n)throw new pl(en);return fc(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),Wf(n,t,{leading:e,maxWait:t,trailing:u})}function Mf(n){return Rf(n,1)}function Ff(n,t){return ph(Au(t),n)}function Nf(){if(!arguments.length)return[];var n=arguments[0];return bh(n)?n:[n]}function Pf(n){return Fr(n,sn)}function qf(n,t){return t="function"==typeof t?t:X,Fr(n,sn,t)}function Zf(n){return Fr(n,an|sn)}function Kf(n,t){return t="function"==typeof t?t:X,Fr(n,an|sn,t);
}function Vf(n,t){return null==t||Pr(n,t,Pc(t))}function Gf(n,t){return n===t||n!==n&&t!==t}function Hf(n){return null!=n&&oc(n.length)&&!uc(n)}function Jf(n){return cc(n)&&Hf(n)}function Yf(n){return n===!0||n===!1||cc(n)&&we(n)==Nn}function Qf(n){return cc(n)&&1===n.nodeType&&!gc(n)}function Xf(n){if(null==n)return!0;if(Hf(n)&&(bh(n)||"string"==typeof n||"function"==typeof n.splice||mh(n)||Oh(n)||dh(n)))return!n.length;var t=zs(n);if(t==Gn||t==tt)return!n.size;if(Mi(n))return!Me(n).length;for(var r in n)if(bl.call(n,r))return!1;
return!0}function nc(n,t){return Se(n,t)}function tc(n,t,r){r="function"==typeof r?r:X;var e=r?r(n,t):X;return e===X?Se(n,t,X,r):!!e}function rc(n){if(!cc(n))return!1;var t=we(n);return t==Zn||t==qn||"string"==typeof n.message&&"string"==typeof n.name&&!gc(n)}function ec(n){return"number"==typeof n&&Zl(n)}function uc(n){if(!fc(n))return!1;var t=we(n);return t==Kn||t==Vn||t==Fn||t==Xn}function ic(n){return"number"==typeof n&&n==kc(n)}function oc(n){return"number"==typeof n&&n>-1&&n%1==0&&n<=Wn}function fc(n){
var t=typeof n;return null!=n&&("object"==t||"function"==t)}function cc(n){return null!=n&&"object"==typeof n}function ac(n,t){return n===t||Ce(n,t,ji(t))}function lc(n,t,r){return r="function"==typeof r?r:X,Ce(n,t,ji(t),r)}function sc(n){return vc(n)&&n!=+n}function hc(n){if(Es(n))throw new fl(rn);return Ue(n)}function pc(n){return null===n}function _c(n){return null==n}function vc(n){return"number"==typeof n||cc(n)&&we(n)==Hn}function gc(n){if(!cc(n)||we(n)!=Yn)return!1;var t=El(n);if(null===t)return!0;
var r=bl.call(t,"constructor")&&t.constructor;return"function"==typeof r&&r instanceof r&&dl.call(r)==jl}function yc(n){return ic(n)&&n>=-Wn&&n<=Wn}function dc(n){return"string"==typeof n||!bh(n)&&cc(n)&&we(n)==rt}function bc(n){return"symbol"==typeof n||cc(n)&&we(n)==et}function wc(n){return n===X}function mc(n){return cc(n)&&zs(n)==it}function xc(n){return cc(n)&&we(n)==ot}function jc(n){if(!n)return[];if(Hf(n))return dc(n)?G(n):Tu(n);if(Ul&&n[Ul])return D(n[Ul]());var t=zs(n);return(t==Gn?M:t==tt?P:ra)(n);
}function Ac(n){if(!n)return 0===n?n:0;if(n=Ic(n),n===Sn||n===-Sn){return(n<0?-1:1)*Ln}return n===n?n:0}function kc(n){var t=Ac(n),r=t%1;return t===t?r?t-r:t:0}function Oc(n){return n?Mr(kc(n),0,Un):0}function Ic(n){if("number"==typeof n)return n;if(bc(n))return Cn;if(fc(n)){var t="function"==typeof n.valueOf?n.valueOf():n;n=fc(t)?t+"":t}if("string"!=typeof n)return 0===n?n:+n;n=R(n);var r=qt.test(n);return r||Kt.test(n)?Xr(n.slice(2),r?2:8):Pt.test(n)?Cn:+n}function Rc(n){return $u(n,qc(n))}function zc(n){
return n?Mr(kc(n),-Wn,Wn):0===n?n:0}function Ec(n){return null==n?"":vu(n)}function Sc(n,t){var r=gs(n);return null==t?r:Cr(r,t)}function Wc(n,t){return v(n,mi(t,3),ue)}function Lc(n,t){return v(n,mi(t,3),oe)}function Cc(n,t){return null==n?n:bs(n,mi(t,3),qc)}function Uc(n,t){return null==n?n:ws(n,mi(t,3),qc)}function Bc(n,t){return n&&ue(n,mi(t,3))}function Tc(n,t){return n&&oe(n,mi(t,3))}function $c(n){return null==n?[]:fe(n,Pc(n))}function Dc(n){return null==n?[]:fe(n,qc(n))}function Mc(n,t,r){
var e=null==n?X:_e(n,t);return e===X?r:e}function Fc(n,t){return null!=n&&Ri(n,t,xe)}function Nc(n,t){return null!=n&&Ri(n,t,je)}function Pc(n){return Hf(n)?Or(n):Me(n)}function qc(n){return Hf(n)?Or(n,!0):Fe(n)}function Zc(n,t){var r={};return t=mi(t,3),ue(n,function(n,e,u){Br(r,t(n,e,u),n)}),r}function Kc(n,t){var r={};return t=mi(t,3),ue(n,function(n,e,u){Br(r,e,t(n,e,u))}),r}function Vc(n,t){return Gc(n,Uf(mi(t)))}function Gc(n,t){if(null==n)return{};var r=c(di(n),function(n){return[n]});return t=mi(t),
Ye(n,r,function(n,r){return t(n,r[0])})}function Hc(n,t,r){t=ku(t,n);var e=-1,u=t.length;for(u||(u=1,n=X);++e<u;){var i=null==n?X:n[no(t[e])];i===X&&(e=u,i=r),n=uc(i)?i.call(n):i}return n}function Jc(n,t,r){return null==n?n:fu(n,t,r)}function Yc(n,t,r,e){return e="function"==typeof e?e:X,null==n?n:fu(n,t,r,e)}function Qc(n,t,e){var u=bh(n),i=u||mh(n)||Oh(n);if(t=mi(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:fc(n)&&uc(o)?gs(El(n)):{}}return(i?r:ue)(n,function(n,r,u){return t(e,n,r,u)}),e}
function Xc(n,t){return null==n||yu(n,t)}function na(n,t,r){return null==n?n:du(n,t,Au(r))}function ta(n,t,r,e){return e="function"==typeof e?e:X,null==n?n:du(n,t,Au(r),e)}function ra(n){return null==n?[]:E(n,Pc(n))}function ea(n){return null==n?[]:E(n,qc(n))}function ua(n,t,r){return r===X&&(r=t,t=X),r!==X&&(r=Ic(r),r=r===r?r:0),t!==X&&(t=Ic(t),t=t===t?t:0),Mr(Ic(n),t,r)}function ia(n,t,r){return t=Ac(t),r===X?(r=t,t=0):r=Ac(r),n=Ic(n),Ae(n,t,r)}function oa(n,t,r){if(r&&"boolean"!=typeof r&&Ui(n,t,r)&&(t=r=X),
r===X&&("boolean"==typeof t?(r=t,t=X):"boolean"==typeof n&&(r=n,n=X)),n===X&&t===X?(n=0,t=1):(n=Ac(n),t===X?(t=n,n=0):t=Ac(t)),n>t){var e=n;n=t,t=e}if(r||n%1||t%1){var u=Ql();return Hl(n+u*(t-n+Qr("1e-"+((u+"").length-1))),t)}return tu(n,t)}function fa(n){return Qh(Ec(n).toLowerCase())}function ca(n){return n=Ec(n),n&&n.replace(Gt,ve).replace(Dr,"")}function aa(n,t,r){n=Ec(n),t=vu(t);var e=n.length;r=r===X?e:Mr(kc(r),0,e);var u=r;return r-=t.length,r>=0&&n.slice(r,u)==t}function la(n){return n=Ec(n),
n&&At.test(n)?n.replace(xt,ge):n}function sa(n){return n=Ec(n),n&&Wt.test(n)?n.replace(St,"\\$&"):n}function ha(n,t,r){n=Ec(n),t=kc(t);var e=t?V(n):0;if(!t||e>=t)return n;var u=(t-e)/2;return ri(Nl(u),r)+n+ri(Fl(u),r)}function pa(n,t,r){n=Ec(n),t=kc(t);var e=t?V(n):0;return t&&e<t?n+ri(t-e,r):n}function _a(n,t,r){n=Ec(n),t=kc(t);var e=t?V(n):0;return t&&e<t?ri(t-e,r)+n:n}function va(n,t,r){return r||null==t?t=0:t&&(t=+t),Yl(Ec(n).replace(Lt,""),t||0)}function ga(n,t,r){return t=(r?Ui(n,t,r):t===X)?1:kc(t),
eu(Ec(n),t)}function ya(){var n=arguments,t=Ec(n[0]);return n.length<3?t:t.replace(n[1],n[2])}function da(n,t,r){return r&&"number"!=typeof r&&Ui(n,t,r)&&(t=r=X),(r=r===X?Un:r>>>0)?(n=Ec(n),n&&("string"==typeof t||null!=t&&!Ah(t))&&(t=vu(t),!t&&T(n))?Ou(G(n),0,r):n.split(t,r)):[]}function ba(n,t,r){return n=Ec(n),r=null==r?0:Mr(kc(r),0,n.length),t=vu(t),n.slice(r,r+t.length)==t}function wa(n,t,r){var e=Z.templateSettings;r&&Ui(n,t,r)&&(t=X),n=Ec(n),t=Sh({},t,e,li);var u,i,o=Sh({},t.imports,e.imports,li),f=Pc(o),c=E(o,f),a=0,l=t.interpolate||Ht,s="__p += '",h=sl((t.escape||Ht).source+"|"+l.source+"|"+(l===It?Ft:Ht).source+"|"+(t.evaluate||Ht).source+"|$","g"),p="//# sourceURL="+(bl.call(t,"sourceURL")?(t.sourceURL+"").replace(/\s/g," "):"lodash.templateSources["+ ++Zr+"]")+"\n";
n.replace(h,function(t,r,e,o,f,c){return e||(e=o),s+=n.slice(a,c).replace(Jt,U),r&&(u=!0,s+="' +\n__e("+r+") +\n'"),f&&(i=!0,s+="';\n"+f+";\n__p += '"),e&&(s+="' +\n((__t = ("+e+")) == null ? '' : __t) +\n'"),a=c+t.length,t}),s+="';\n";var _=bl.call(t,"variable")&&t.variable;if(_){if(Dt.test(_))throw new fl(un)}else s="with (obj) {\n"+s+"\n}\n";s=(i?s.replace(dt,""):s).replace(bt,"$1").replace(wt,"$1;"),s="function("+(_||"obj")+") {\n"+(_?"":"obj || (obj = {});\n")+"var __t, __p = ''"+(u?", __e = _.escape":"")+(i?", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n":";\n")+s+"return __p\n}";
var v=Xh(function(){return cl(f,p+"return "+s).apply(X,c)});if(v.source=s,rc(v))throw v;return v}function ma(n){return Ec(n).toLowerCase()}function xa(n){return Ec(n).toUpperCase()}function ja(n,t,r){if(n=Ec(n),n&&(r||t===X))return R(n);if(!n||!(t=vu(t)))return n;var e=G(n),u=G(t);return Ou(e,W(e,u),L(e,u)+1).join("")}function Aa(n,t,r){if(n=Ec(n),n&&(r||t===X))return n.slice(0,H(n)+1);if(!n||!(t=vu(t)))return n;var e=G(n);return Ou(e,0,L(e,G(t))+1).join("")}function ka(n,t,r){if(n=Ec(n),n&&(r||t===X))return n.replace(Lt,"");
if(!n||!(t=vu(t)))return n;var e=G(n);return Ou(e,W(e,G(t))).join("")}function Oa(n,t){var r=An,e=kn;if(fc(t)){var u="separator"in t?t.separator:u;r="length"in t?kc(t.length):r,e="omission"in t?vu(t.omission):e}n=Ec(n);var i=n.length;if(T(n)){var o=G(n);i=o.length}if(r>=i)return n;var f=r-V(e);if(f<1)return e;var c=o?Ou(o,0,f).join(""):n.slice(0,f);if(u===X)return c+e;if(o&&(f+=c.length-f),Ah(u)){if(n.slice(f).search(u)){var a,l=c;for(u.global||(u=sl(u.source,Ec(Nt.exec(u))+"g")),u.lastIndex=0;a=u.exec(l);)var s=a.index;

184
incident_response_plan.md Normal file
View File

@@ -0,0 +1,184 @@
# Incident Response Plan
## Introduction
Security is a top priority for Lodash. This document outlines the **formal process** for handling **security reports**, including how to **triage**, **assess**, and **disclose** vulnerabilities responsibly.
## Scope
The [Security Triage Team][] will use this document as a process guide when a security vulnerability is reported, from triage to resolution. This process must align with the project's [SECURITY policy](SECURITY.md) and cannot diverge significantly.
## Security Report Handling Flowchart
The following diagram details the **decision-making process** for handling security reports:
```mermaid
flowchart TD
A[Security Report Received] --> B[Assign Security Report Coordinator]
B --> E{Premature Disclosure?}
E -- No --> J[Proceed with Standard Private Process]
E -- Yes --> F[Privatize Disclosure]
F --> G[Handle Related PRs & Issues]
G --> H[Request GitHub to Remove Public PR/Issues]
H --> I[Create Public Placeholder Issue]
I --> J[Acknowledge within 5 days to the Reporter]
J --> K[Create Issue in Triage Repo for Visibility]
K --> L[Assess Report]
L --> M{Enough Information?}
M -- No --> N[Request Additional Info]
N --> L[Assess Report]
M -- Yes --> O{Valid Vulnerability?}
O -- No --> X[Close Report as Invalid]
X --> Y[Acknowledge within 10 days to the Reporter]
O -- Yes --> Q[Create Advisory]
Q --> Q1[Calculate CVSS Score]
Q1 --> Q2[Request a CVE]
Q2 --> R{Patch Required?}
R -- No --> Z[Public Disclosure]
R -- Yes --> T[Develop Patch]
T --> U[Test Solution]
U --> V[Add Regression Testing]
V --> W[Create a Security Release with CVE Included]
W --> Z[Public Disclosure]
Z --> Z1[Notify Community]
Z1 --> Z2[Official Blog Post]
Z1 --> Z3[Social Media Announcements]
```
## Roles & Responsibilities
### Finder
This person identifies a potential security vulnerability in the project. The Finder may or may not be the same person as the Reporter. If the Finder is not the Reporter, they may share the details with someone else who submits the report to the Security Triage Team.
**Responsibilities**
- Identify potential security vulnerabilities in the project.
- Share sufficient details about the vulnerability with the Reporter or directly with the Security Triage Team.
**Expectations**
- Follow responsible disclosure guidelines by ensuring the vulnerability is reported privately before public disclosure.
- Provide clear and accurate information about the vulnerability to facilitate the reporting process.
### Reporter
This person submits a security report to the Security Triage Team and provides detailed information about the suspected vulnerability. It is expected that the Reporter will cooperate with the Security Triage Team during this process and follow responsible disclosure guidelines.
**Responsibilities**
- Submit a security report to the Security Triage Team.
**Expectations**
- Provide detailed information about the suspected vulnerability.
- Follow responsible disclosure guidelines (report privately before public disclosure).
- Cooperate with the Security Triage Team by providing additional details when needed.
- Test and verify patches (when applicable).
- Respect security timelines and avoid premature public disclosure.
### Coordinator
This person acts as the focal point for a specific security report and ensures the report follows all responsible disclosure guidelines. The SRC coordinates the remediation process if a vulnerability is confirmed and ensures that the security report follows the process and necessary actions are taken. While the SRC is not necessarily responsible for performing analysis, remediation, or patching, they may take on these tasks if they also hold the role of Analyst or Remediation Developer.
**Responsibilities**
- Acknowledge receipt of security reports within the required timeframe.
- Orchestrate the embargo and identify the minimum set of individuals involved.
- Remind everyone involved that they must not notify/involve any other individuals. If someone else needs to be involved, that must go through the Coordinator.
- Assign an Analyst to assess and validate the report.
- Ensure communication with the reporter throughout the process.
- Coordinate the remediation process if a vulnerability is confirmed.
- Oversee the advisory & CVE request process if applicable.
- Escalate critical vulnerabilities when necessary.
- Track all security reports for visibility and reporting.
**Requirements**
- Must be a member of the Security Triage Team.
### Analyst
**Responsibilities**
- Determine if the reported issue is a real vulnerability, and is in within the scope of our [threat model](threat-model.md)
- Validate proof-of-concept exploits
- Assess the security report and determine its severity (assist in CVSS).
- Validate the reported vulnerability against best practices.
- Identify potential mitigation strategies and workarounds.
- Prepare a report for the Security Report Coordinator.
### Remediation Developer
**Responsibilities**
- Develop a patch or solution based on the reported vulnerability.
- Ensure the patch follows best practices and is testable.
- Add test(s) to the existing test suite to confirm the vulnerability (pre-patch) and confirm the fix (post-patch).
- Test the patch to ensure it works as expected.
- Create a pull request to merge the patch into the project.
## Runbook
The following sections outline the **step-by-step process**, explaining each decision, scenario, and possible actions. In this guide we also include links that are private (limited to the Security Triage Team), a general overview of the process in flowchart format can be found [here](#security-report-handling-flowchart).
### Step 0: Security Report Received
A security vulnerability report is received via [official channels](SECURITY.md#reporting-a-security-issue) or otherwise (i.e. via third-party advisory services, blog post, social media, etc.).
Ideally, the report must contain **clear and detailed information** like (Affected versions, a small PoC/sample project demonstrating the issue, steps to reproduce, expected vs. actual behavior, potential impact...) but this might not be the case depending on the communication channel used. Later on we will try to collect this information and refine the report.
### Step 1: Assign Security Report Coordinator (SRC) and consolidate the report
1.1 One person from the Security Triage Team will volunteer and self-assign to oversee the case. It is expected that the person will remain assigned until the end of the process, so they effectively take the role of [the Security Report Coordinator (SRC)](#security-report-coordinator-src).
> [!Note]
> While this document refers to a single SRC for simplicity, in practice, having two coordinators is acceptable and often beneficial. A second coordinator can assist with tasks such as reviewing the advisory content before it is published, ensuring accuracy and completeness.
1.2 If the report was created accidentally or intentionally in a public channel (e.g. GitHub issues), it is important to share this information ASAP in the private slack channel `#lodash-security-triage` so the Security Triage Team is aware of it. At this stage, our priority is to remove the report from public view as soon as possible and let the reporter know what happened next.
1.2.1 In the case of a report made public in a Pull request or issue under the Lodash GitHub organization the following process will be followed (by a Lodash TSC Member):
* Move the issue to the private repository called [lodash/security-triage](https://github.com/lodash/security-triage).
* For any related pull requests, create an associated issue in [lodash/security-triage](https://github.com/lodash/security-triage) repository. Add a copy of the patch for the pull request to the issue. Add screenshots of discussion from the pull request to the issue.
* [Open a ticket with GitHub](https://support.github.com/contact) to delete the pull request using Lodash (team) as the account organization.
* Force-push to the PR branch to overwrite the code with a placeholder commit (if "allow edits by maintainers" is enabled). This ensures sensitive information is removed immediately.
* In the PR comments, notify the author about the force-push and explain the reason:
> FYI @xxxx, we force-pushed to your branch to remove sensitive information while we work on releases in private.
* Open a new issue in the public repository with the title `FYI - pull request deleted #YYYY`. Include an explanation for the user:
> FYI @xxxx we asked GitHub to delete your pull request while we work on releases in private.
* Update the team in the slack channel #lodash-security-triage`.
1.2.2 In the case that the report is made public in a different channel that we don't own/control, the Lodash TSC will attempt to mitigate this by trying to remove the report from public view (reporting to support, asking the reporter to remove the report, etc...).
1.3 At this stage the Security Report Coordinator (SRC) will create a (private) issue in [lodash/security-triage](https://github.com/lodash/security-triage) repository with the existing information from the security report unless it already exists (step 1.2.1). This issue will serve as the central discussion point for this particular report. At this stage is expected from the Security Report Coordinator (SRC) to acknowledge receipt of the security report to the reporter.
> [!Note]
> It is expected that the issue will be assigned to the Security Report Coordinator (SRC) and will remain open until the end of the process.
### Step 2: Review the Report and determine its severity
2.1 It is expected from the security triage team to review the report and determine its severity, also evaluating the impact on the project(s). In some cases the report might be too vague to properly determine its severity. In this case the Security Report Coordinator (SRC) will need to reach out to the reporter for more information and refine the report.
2.2 At this stage we are capable of determining the severity of the report based on the information provided and also if the report is still relevant. In case that the team has considered the report to be irrelevant or not valid, the Security Report Coordinator (SRC) will need to close the issue and inform the reporter that the report has been dismissed, ideally we can provide a reason for dismissal to prevent the report from being resubmitted within the project(s) in the future.
2.3 If the report is considered relevant and valid, the Security Report Coordinator (SRC) will create an advisory and request a CVE number. The Security Report Coordinator (SRC) will also include the remediation developer(s), analyst(s) and potentially the reporter in the advisory, so they can start to work on private fork to fix the security issue.
### Step 3: Patch and release
3.1 The security triage team will determine if this vulnerability will be patched and work on it. In case that the vulnerability won't be patched jump to step 4.
3.2 The mitigation team (remediation developer(s), analyst(s), reporter(s)) will work on the patch(es), re-evaluate the report once the patch is ready and include regression tests (when possible).
3.3 The Lodash TSC will announce publicly on a public issue that there is security patch available and the plan to do a release with an specific date (ideally) and the versions affected without providing additional information to prevent early disclosure.
3.4 The Lodash TSC will create the releases and publish them to npm.
### Step 4: Public disclosure
4.1 At this stage the Security Report Coordinator (SRC) will make the advisory public and close the coordination issue (opened in step 1).
4.2 The Security Report Coordinator (SRC) can ask the Lodash TSC to coordinate blog post or social media announcements using the OpenJS Foundation channels.
[Security Triage Team]: GOVERNANCE.md#security-triage-team

View File

@@ -34,11 +34,19 @@ const exts = _.keys(highlights);
/**
* Converts Lodash method references into documentation links.
*
* Searches for inline code references matching `_.word` (e.g., `_.map`, `_.filter`)
* in documentation body text and wraps them in anchor links. Excludes code within
* headers as those already have proper anchors.
*
* @private
* @param {Object} $ The Cheerio object.
*
* @example
* // Body text: <code>_.map</code> → <a href="#map"><code>_.map</code></a>
* // Headers: <h3><code>_.VERSION</code></h3> → unchanged (excluded)
*/
function autoLink($) {
$('.doc-container code').each(function() {
$('.doc-container code:not(:header code)').each(function() {
const $code = $(this);
const html = $code.html();
if (/^_\.\w+$/.test(html)) {
@@ -176,9 +184,16 @@ function build() {
.readFileSync(readmePath, 'utf8')
// Uncomment docdown HTML hints.
.replace(/(<)!--\s*|\s*--(>)/g, '$1$2')
// Convert source and npm package links to anchors.
.replace(/\[source\]\(([^)]+)\) \[npm package\]\(([^)]+)\)/g, (match, href1, href2) =>
`<p><a href="${ href1 }">source</a> <a href="${ href2 }">npm package</a></p>`
// Convert docdown-generated [source] and [npm package] links to HTML.
// These appear as markdown immediately after h3 tags, which marky-markdown
// doesn't process (it treats content after HTML blocks as plain text).
// Pattern 1: Dual links for methods with npm packages.
.replace(/(<h3[^>]*>.*?<\/h3>)\n\[source\]\(([^)]+)\) \[npm package\]\(([^)]+)\)/g, (match, h3, href1, href2) =>
`${h3}\n<p><a href="${ href1 }">source</a> <a href="${ href2 }">npm package</a></p>`
)
// Pattern 2: Standalone [source] links for properties without npm packages.
.replace(/(<h3[^>]*>.*?<\/h3>)\n\[source\]\(([^)]+)\)(?! \[npm package\])/g, (match, h3, href) =>
`${h3}\n<p><a href="${ href }">source</a></p>`
);
const $ = cheerio.load(marky(markdown, {

View File

@@ -2300,7 +2300,7 @@
* @name has
* @memberOf SetCache
* @param {*} value The value to search for.
* @returns {number} Returns `true` if `value` is found, else `false`.
* @returns {boolean} Returns `true` if `value` is found, else `false`.
*/
function setCacheHas(value) {
return this.__data__.has(value);
@@ -3766,7 +3766,7 @@
if (isArray(iteratee)) {
return function(value) {
return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
}
};
}
return iteratee;
});
@@ -4370,8 +4370,47 @@
*/
function baseUnset(object, path) {
path = castPath(path, object);
object = parent(object, path);
return object == null || delete object[toKey(last(path))];
// Prevent prototype pollution, see: https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg
var index = -1,
length = path.length;
if (!length) {
return true;
}
var isRootPrimitive = object == null || (typeof object !== 'object' && typeof object !== 'function');
while (++index < length) {
var key = path[index];
// skip non-string keys (e.g., Symbols, numbers)
if (typeof key !== 'string') {
continue;
}
// Always block "__proto__" anywhere in the path if it's not expected
if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {
return false;
}
// Block "constructor.prototype" chains
if (key === 'constructor' &&
(index + 1) < length &&
typeof path[index + 1] === 'string' &&
path[index + 1] === 'prototype') {
// Allow ONLY when the path starts at a primitive root, e.g., _.unset(0, 'constructor.prototype.a')
if (isRootPrimitive && index === 0) {
continue;
}
return false;
}
}
var obj = parent(object, path);
return obj == null || delete obj[toKey(last(path))];
}
/**
@@ -6922,7 +6961,7 @@
/**
* Creates an array with all falsey values removed. The values `false`, `null`,
* `0`, `""`, `undefined`, and `NaN` are falsey.
* `0`, `-0', '0n`, `""`, `undefined`, and `NaN` are falsy.
*
* @static
* @memberOf _

View File

@@ -57,10 +57,5 @@
"sauce-tunnel": "^2.5.0",
"uglify-js": "2.7.5",
"webpack": "^1.14.0"
},
"greenkeeper": {
"ignore": [
"lodash"
]
}
}

28
playwright.config.js Normal file
View File

@@ -0,0 +1,28 @@
const { devices } = require('@playwright/test');
module.exports = {
retries: 0,
testDir: './test',
testMatch: '**/*.spec.js',
use: {
baseURL: 'http://localhost:9001',
headless: true,
},
projects: [
{ name: 'Chromium', use: { browserName: 'chromium' } },
{ name: 'Firefox', use: { browserName: 'firefox' } },
{ name: 'WebKit', use: { browserName: 'webkit' } },
{
name: 'Microsoft Edge',
use: { browserName: 'chromium', channel: 'msedge' },
},
{
name: 'Mobile Safari',
use: { ...devices['iPhone 12'], browserName: 'webkit' },
},
{
name: 'Mobile Chrome',
use: { ...devices['Pixel 5'], browserName: 'chromium' },
},
],
};

17
renovate.json Normal file
View File

@@ -0,0 +1,17 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
],
"enabledManagers": ["npm", "github-actions"],
"packageRules": [
{
"matchManagers": ["npm"],
"matchUpdateTypes": ["major"],
"enabled": false
}
],
"prHourlyLimit": 0,
"prConcurrentLimit": 10,
"minimumReleaseAge": "14d"
}

View File

@@ -0,0 +1,23 @@
const { test, expect } = require('@playwright/test');
test.describe.configure({ mode: 'parallel' });
test('index', async ({ page }) => {
await page.goto('http://localhost:9001/test/index.html');
await expect(page.locator('text=0 failed')).toBeVisible({ timeout: 60000 });
});
test('fp', async ({ page }) => {
await page.goto('http://localhost:9001/test/fp.html');
await expect(page.locator('text=0 failed')).toBeVisible({ timeout: 60000 });
});
test('backbone', async ({ page }) => {
await page.goto('http://localhost:9001/test/backbone.html');
await expect(page.locator('text=0 failed')).toBeVisible({ timeout: 60000 });
});
test('underscore', async ({ page }) => {
await page.goto('http://localhost:9001/test/underscore.html');
await expect(page.locator('text=0 failed')).toBeVisible({ timeout: 60000 });
});

View File

@@ -1,908 +0,0 @@
#!/usr/bin/env node
'use strict';
/** Environment shortcut. */
var env = process.env;
/** Load Node.js modules. */
var EventEmitter = require('events').EventEmitter,
http = require('http'),
path = require('path'),
url = require('url'),
util = require('util');
/** Load other modules. */
var _ = require('../lodash.js'),
chalk = require('chalk'),
ecstatic = require('ecstatic'),
request = require('request'),
SauceTunnel = require('sauce-tunnel');
/** Used for Sauce Labs credentials. */
var accessKey = env.SAUCE_ACCESS_KEY,
username = env.SAUCE_USERNAME;
/** Used as the default maximum number of times to retry a job and tunnel. */
var maxJobRetries = 3,
maxTunnelRetries = 3;
/** Used as the static file server middleware. */
var mount = ecstatic({
'cache': 'no-cache',
'root': process.cwd()
});
/** Used as the list of ports supported by Sauce Connect. */
var ports = [
80, 443, 888, 2000, 2001, 2020, 2109, 2222, 2310, 3000, 3001, 3030, 3210,
3333, 4000, 4001, 4040, 4321, 4502, 4503, 4567, 5000, 5001, 5050, 5555, 5432,
6000, 6001, 6060, 6666, 6543, 7000, 7070, 7774, 7777, 8000, 8001, 8003, 8031,
8080, 8081, 8765, 8777, 8888, 9000, 9001, 9080, 9090, 9876, 9877, 9999, 49221,
55001
];
/** Used by `logInline` to clear previously logged messages. */
var prevLine = '';
/** Method shortcut. */
var push = Array.prototype.push;
/** Used to detect error messages. */
var reError = /(?:\be|E)rror\b/;
/** Used to detect valid job ids. */
var reJobId = /^[a-z0-9]{32}$/;
/** Used to display the wait throbber. */
var throbberDelay = 500,
waitCount = -1;
/**
* Used as Sauce Labs config values.
* See the [Sauce Labs documentation](https://docs.saucelabs.com/reference/test-configuration/)
* for more details.
*/
var advisor = getOption('advisor', false),
build = getOption('build', (env.TRAVIS_COMMIT || '').slice(0, 10)),
commandTimeout = getOption('commandTimeout', 90),
compatMode = getOption('compatMode', null),
customData = Function('return {' + getOption('customData', '').replace(/^\{|}$/g, '') + '}')(),
deviceOrientation = getOption('deviceOrientation', 'portrait'),
framework = getOption('framework', 'qunit'),
idleTimeout = getOption('idleTimeout', 60),
jobName = getOption('name', 'unit tests'),
maxDuration = getOption('maxDuration', 180),
port = ports[Math.min(_.sortedIndex(ports, getOption('port', 9001)), ports.length - 1)],
publicAccess = getOption('public', true),
queueTimeout = getOption('queueTimeout', 240),
recordVideo = getOption('recordVideo', true),
recordScreenshots = getOption('recordScreenshots', false),
runner = getOption('runner', 'test/index.html').replace(/^\W+/, ''),
runnerUrl = getOption('runnerUrl', 'http://localhost:' + port + '/' + runner),
statusInterval = getOption('statusInterval', 5),
tags = getOption('tags', []),
throttled = getOption('throttled', 10),
tunneled = getOption('tunneled', true),
tunnelId = getOption('tunnelId', 'tunnel_' + (env.TRAVIS_JOB_ID || 0)),
tunnelTimeout = getOption('tunnelTimeout', 120),
videoUploadOnPass = getOption('videoUploadOnPass', false);
/** Used to convert Sauce Labs browser identifiers to their formal names. */
var browserNameMap = {
'googlechrome': 'Chrome',
'iehta': 'Internet Explorer',
'ipad': 'iPad',
'iphone': 'iPhone',
'microsoftedge': 'Edge'
};
/** List of platforms to load the runner on. */
var platforms = [
['Linux', 'android', '5.1'],
['Windows 10', 'chrome', '54'],
['Windows 10', 'chrome', '53'],
['Windows 10', 'firefox', '50'],
['Windows 10', 'firefox', '49'],
['Windows 10', 'microsoftedge', '14'],
['Windows 10', 'internet explorer', '11'],
['Windows 8', 'internet explorer', '10'],
['Windows 7', 'internet explorer', '9'],
['macOS 10.12', 'safari', '10'],
['OS X 10.11', 'safari', '9']
];
/** Used to tailor the `platforms` array. */
var isAMD = _.includes(tags, 'amd'),
isBackbone = _.includes(tags, 'backbone'),
isModern = _.includes(tags, 'modern');
// The platforms to test IE compatibility modes.
if (compatMode) {
platforms = [
['Windows 10', 'internet explorer', '11'],
['Windows 8', 'internet explorer', '10'],
['Windows 7', 'internet explorer', '9'],
['Windows 7', 'internet explorer', '8']
];
}
// The platforms for AMD tests.
if (isAMD) {
platforms = _.filter(platforms, function(platform) {
var browser = browserName(platform[1]),
version = +platform[2];
switch (browser) {
case 'Android': return version >= 4.4;
case 'Opera': return version >= 10;
}
return true;
});
}
// The platforms for Backbone tests.
if (isBackbone) {
platforms = _.filter(platforms, function(platform) {
var browser = browserName(platform[1]),
version = +platform[2];
switch (browser) {
case 'Firefox': return version >= 4;
case 'Internet Explorer': return version >= 7;
case 'iPad': return version >= 5;
case 'Opera': return version >= 12;
}
return true;
});
}
// The platforms for modern builds.
if (isModern) {
platforms = _.filter(platforms, function(platform) {
var browser = browserName(platform[1]),
version = +platform[2];
switch (browser) {
case 'Android': return version >= 4.1;
case 'Firefox': return version >= 10;
case 'Internet Explorer': return version >= 9;
case 'iPad': return version >= 6;
case 'Opera': return version >= 12;
case 'Safari': return version >= 6;
}
return true;
});
}
/** Used as the default `Job` options object. */
var jobOptions = {
'build': build,
'command-timeout': commandTimeout,
'custom-data': customData,
'device-orientation': deviceOrientation,
'framework': framework,
'idle-timeout': idleTimeout,
'max-duration': maxDuration,
'name': jobName,
'public': publicAccess,
'platforms': platforms,
'record-screenshots': recordScreenshots,
'record-video': recordVideo,
'sauce-advisor': advisor,
'tags': tags,
'url': runnerUrl,
'video-upload-on-pass': videoUploadOnPass
};
if (publicAccess === true) {
jobOptions['public'] = 'public';
}
if (tunneled) {
jobOptions['tunnel-identifier'] = tunnelId;
}
/*----------------------------------------------------------------------------*/
/**
* Resolves the formal browser name for a given Sauce Labs browser identifier.
*
* @private
* @param {string} identifier The browser identifier.
* @returns {string} Returns the formal browser name.
*/
function browserName(identifier) {
return browserNameMap[identifier] || _.startCase(identifier);
}
/**
* Gets the value for the given option name. If no value is available the
* `defaultValue` is returned.
*
* @private
* @param {string} name The name of the option.
* @param {*} defaultValue The default option value.
* @returns {*} Returns the option value.
*/
function getOption(name, defaultValue) {
var isArr = _.isArray(defaultValue);
return _.reduce(process.argv, function(result, value) {
if (isArr) {
value = optionToArray(name, value);
return _.isEmpty(value) ? result : value;
}
value = optionToValue(name, value);
return value == null ? result : value;
}, defaultValue);
}
/**
* Checks if `value` is a job ID.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a job ID, else `false`.
*/
function isJobId(value) {
return reJobId.test(value);
}
/**
* Writes an inline message to standard output.
*
* @private
* @param {string} [text=''] The text to log.
*/
function logInline(text) {
var blankLine = _.repeat(' ', _.size(prevLine));
prevLine = text = _.truncate(text, { 'length': 40 });
process.stdout.write(text + blankLine.slice(text.length) + '\r');
}
/**
* Writes the wait throbber to standard output.
*
* @private
*/
function logThrobber() {
logInline('Please wait' + _.repeat('.', (++waitCount % 3) + 1));
}
/**
* Converts a comma separated option value into an array.
*
* @private
* @param {string} name The name of the option to inspect.
* @param {string} string The options string.
* @returns {Array} Returns the new converted array.
*/
function optionToArray(name, string) {
return _.compact(_.invokeMap((optionToValue(name, string) || '').split(/, */), 'trim'));
}
/**
* Extracts the option value from an option string.
*
* @private
* @param {string} name The name of the option to inspect.
* @param {string} string The options string.
* @returns {string|undefined} Returns the option value, else `undefined`.
*/
function optionToValue(name, string) {
var result = string.match(RegExp('^' + name + '(?:=([\\s\\S]+))?$'));
if (result) {
result = _.get(result, 1);
result = result ? _.trim(result) : true;
}
if (result === 'false') {
return false;
}
return result || undefined;
}
/*----------------------------------------------------------------------------*/
/**
* The `Job#remove` and `Tunnel#stop` callback used by `Jobs#restart`
* and `Tunnel#restart` respectively.
*
* @private
*/
function onGenericRestart() {
this.restarting = false;
this.emit('restart');
this.start();
}
/**
* The `request.put` and `SauceTunnel#stop` callback used by `Jobs#stop`
* and `Tunnel#stop` respectively.
*
* @private
* @param {Object} [error] The error object.
*/
function onGenericStop(error) {
this.running = this.stopping = false;
this.emit('stop', error);
}
/**
* The `request.del` callback used by `Jobs#remove`.
*
* @private
*/
function onJobRemove(error, res, body) {
this.id = this.taskId = this.url = null;
this.removing = false;
this.emit('remove');
}
/**
* The `Job#remove` callback used by `Jobs#reset`.
*
* @private
*/
function onJobReset() {
this.attempts = 0;
this.failed = this.resetting = false;
this._pollerId = this.id = this.result = this.taskId = this.url = null;
this.emit('reset');
}
/**
* The `request.post` callback used by `Jobs#start`.
*
* @private
* @param {Object} [error] The error object.
* @param {Object} res The response data object.
* @param {Object} body The response body JSON object.
*/
function onJobStart(error, res, body) {
this.starting = false;
if (this.stopping) {
return;
}
var statusCode = _.get(res, 'statusCode'),
taskId = _.first(_.get(body, 'js tests'));
if (error || !taskId || statusCode != 200) {
if (this.attempts < this.retries) {
this.restart();
return;
}
var na = 'unavailable',
bodyStr = _.isObject(body) ? '\n' + JSON.stringify(body) : na,
statusStr = _.isFinite(statusCode) ? statusCode : na;
logInline();
console.error('Failed to start job; status: %s, body: %s', statusStr, bodyStr);
if (error) {
console.error(error);
}
this.failed = true;
this.emit('complete');
return;
}
this.running = true;
this.taskId = taskId;
this.timestamp = _.now();
this.emit('start');
this.status();
}
/**
* The `request.post` callback used by `Job#status`.
*
* @private
* @param {Object} [error] The error object.
* @param {Object} res The response data object.
* @param {Object} body The response body JSON object.
*/
function onJobStatus(error, res, body) {
this.checking = false;
if (!this.running || this.stopping) {
return;
}
var completed = _.get(body, 'completed', false),
data = _.first(_.get(body, 'js tests')),
elapsed = (_.now() - this.timestamp) / 1000,
jobId = _.get(data, 'job_id', null),
jobResult = _.get(data, 'result', null),
jobStatus = _.get(data, 'status', ''),
jobUrl = _.get(data, 'url', null),
expired = (elapsed >= queueTimeout && !_.includes(jobStatus, 'in progress')),
options = this.options,
platform = options.platforms[0];
if (_.isObject(jobResult)) {
var message = _.get(jobResult, 'message');
} else {
if (typeof jobResult == 'string') {
message = jobResult;
}
jobResult = null;
}
if (isJobId(jobId)) {
this.id = jobId;
this.result = jobResult;
this.url = jobUrl;
} else {
completed = false;
}
this.emit('status', jobStatus);
if (!completed && !expired) {
this._pollerId = _.delay(_.bind(this.status, this), this.statusInterval * 1000);
return;
}
var description = browserName(platform[1]) + ' ' + platform[2] + ' on ' + _.startCase(platform[0]),
errored = !jobResult || !jobResult.passed || reError.test(message) || reError.test(jobStatus),
failures = _.get(jobResult, 'failed'),
label = options.name + ':',
tunnel = this.tunnel;
if (errored || failures) {
if (errored && this.attempts < this.retries) {
this.restart();
return;
}
var details = 'See ' + jobUrl + ' for details.';
this.failed = true;
logInline();
if (failures) {
console.error(label + ' %s ' + chalk.red('failed') + ' %d test' + (failures > 1 ? 's' : '') + '. %s', description, failures, details);
}
else if (tunnel.attempts < tunnel.retries) {
tunnel.restart();
return;
}
else {
if (message === undefined) {
message = 'Results are unavailable. ' + details;
}
console.error(label, description, chalk.red('failed') + ';', message);
}
}
else {
logInline();
console.log(label, description, chalk.green('passed'));
}
this.running = false;
this.emit('complete');
}
/**
* The `SauceTunnel#start` callback used by `Tunnel#start`.
*
* @private
* @param {boolean} success The connection success indicator.
*/
function onTunnelStart(success) {
this.starting = false;
if (this._timeoutId) {
clearTimeout(this._timeoutId);
this._timeoutId = null;
}
if (!success) {
if (this.attempts < this.retries) {
this.restart();
return;
}
logInline();
console.error('Failed to open Sauce Connect tunnel');
process.exit(2);
}
logInline();
console.log('Sauce Connect tunnel opened');
var jobs = this.jobs;
push.apply(jobs.queue, jobs.all);
this.running = true;
this.emit('start');
console.log('Starting jobs...');
this.dequeue();
}
/*----------------------------------------------------------------------------*/
/**
* The Job constructor.
*
* @private
* @param {Object} [properties] The properties to initialize a job with.
*/
function Job(properties) {
EventEmitter.call(this);
this.options = {};
_.merge(this, properties);
_.defaults(this.options, _.cloneDeep(jobOptions));
this.attempts = 0;
this.checking = this.failed = this.removing = this.resetting = this.restarting = this.running = this.starting = this.stopping = false;
this._pollerId = this.id = this.result = this.taskId = this.url = null;
}
util.inherits(Job, EventEmitter);
/**
* Removes the job.
*
* @memberOf Job
* @param {Function} callback The function called once the job is removed.
* @param {Object} Returns the job instance.
*/
Job.prototype.remove = function(callback) {
this.once('remove', _.iteratee(callback));
if (this.removing) {
return this;
}
this.removing = true;
return this.stop(function() {
var onRemove = _.bind(onJobRemove, this);
if (!this.id) {
_.defer(onRemove);
return;
}
request.del(_.template('https://saucelabs.com/rest/v1/${user}/jobs/${id}')(this), {
'auth': { 'user': this.user, 'pass': this.pass }
}, onRemove);
});
};
/**
* Resets the job.
*
* @memberOf Job
* @param {Function} callback The function called once the job is reset.
* @param {Object} Returns the job instance.
*/
Job.prototype.reset = function(callback) {
this.once('reset', _.iteratee(callback));
if (this.resetting) {
return this;
}
this.resetting = true;
return this.remove(onJobReset);
};
/**
* Restarts the job.
*
* @memberOf Job
* @param {Function} callback The function called once the job is restarted.
* @param {Object} Returns the job instance.
*/
Job.prototype.restart = function(callback) {
this.once('restart', _.iteratee(callback));
if (this.restarting) {
return this;
}
this.restarting = true;
var options = this.options,
platform = options.platforms[0],
description = browserName(platform[1]) + ' ' + platform[2] + ' on ' + _.startCase(platform[0]),
label = options.name + ':';
logInline();
console.log('%s %s restart %d of %d', label, description, ++this.attempts, this.retries);
return this.remove(onGenericRestart);
};
/**
* Starts the job.
*
* @memberOf Job
* @param {Function} callback The function called once the job is started.
* @param {Object} Returns the job instance.
*/
Job.prototype.start = function(callback) {
this.once('start', _.iteratee(callback));
if (this.starting || this.running) {
return this;
}
this.starting = true;
request.post(_.template('https://saucelabs.com/rest/v1/${user}/js-tests')(this), {
'auth': { 'user': this.user, 'pass': this.pass },
'json': this.options
}, _.bind(onJobStart, this));
return this;
};
/**
* Checks the status of a job.
*
* @memberOf Job
* @param {Function} callback The function called once the status is resolved.
* @param {Object} Returns the job instance.
*/
Job.prototype.status = function(callback) {
this.once('status', _.iteratee(callback));
if (this.checking || this.removing || this.resetting || this.restarting || this.starting || this.stopping) {
return this;
}
this._pollerId = null;
this.checking = true;
request.post(_.template('https://saucelabs.com/rest/v1/${user}/js-tests/status')(this), {
'auth': { 'user': this.user, 'pass': this.pass },
'json': { 'js tests': [this.taskId] }
}, _.bind(onJobStatus, this));
return this;
};
/**
* Stops the job.
*
* @memberOf Job
* @param {Function} callback The function called once the job is stopped.
* @param {Object} Returns the job instance.
*/
Job.prototype.stop = function(callback) {
this.once('stop', _.iteratee(callback));
if (this.stopping) {
return this;
}
this.stopping = true;
if (this._pollerId) {
clearTimeout(this._pollerId);
this._pollerId = null;
this.checking = false;
}
var onStop = _.bind(onGenericStop, this);
if (!this.running || !this.id) {
_.defer(onStop);
return this;
}
request.put(_.template('https://saucelabs.com/rest/v1/${user}/jobs/${id}/stop')(this), {
'auth': { 'user': this.user, 'pass': this.pass }
}, onStop);
return this;
};
/*----------------------------------------------------------------------------*/
/**
* The Tunnel constructor.
*
* @private
* @param {Object} [properties] The properties to initialize the tunnel with.
*/
function Tunnel(properties) {
EventEmitter.call(this);
_.merge(this, properties);
var active = [],
queue = [];
var all = _.map(this.platforms, _.bind(function(platform) {
return new Job(_.merge({
'user': this.user,
'pass': this.pass,
'tunnel': this,
'options': { 'platforms': [platform] }
}, this.job));
}, this));
var completed = 0,
restarted = [],
success = true,
total = all.length,
tunnel = this;
_.invokeMap(all, 'on', 'complete', function() {
_.pull(active, this);
if (success) {
success = !this.failed;
}
if (++completed == total) {
tunnel.stop(_.partial(tunnel.emit, 'complete', success));
return;
}
tunnel.dequeue();
});
_.invokeMap(all, 'on', 'restart', function() {
if (!_.includes(restarted, this)) {
restarted.push(this);
}
// Restart tunnel if all active jobs have restarted.
var threshold = Math.min(all.length, _.isFinite(throttled) ? throttled : 3);
if (tunnel.attempts < tunnel.retries &&
active.length >= threshold && _.isEmpty(_.difference(active, restarted))) {
tunnel.restart();
}
});
this.on('restart', function() {
completed = 0;
success = true;
restarted.length = 0;
});
this._timeoutId = null;
this.attempts = 0;
this.restarting = this.running = this.starting = this.stopping = false;
this.jobs = { 'active': active, 'all': all, 'queue': queue };
this.connection = new SauceTunnel(this.user, this.pass, this.id, this.tunneled, ['-P', '0']);
}
util.inherits(Tunnel, EventEmitter);
/**
* Restarts the tunnel.
*
* @memberOf Tunnel
* @param {Function} callback The function called once the tunnel is restarted.
*/
Tunnel.prototype.restart = function(callback) {
this.once('restart', _.iteratee(callback));
if (this.restarting) {
return this;
}
this.restarting = true;
logInline();
console.log('Tunnel %s: restart %d of %d', this.id, ++this.attempts, this.retries);
var jobs = this.jobs,
active = jobs.active,
all = jobs.all;
var reset = _.after(all.length, _.bind(this.stop, this, onGenericRestart)),
stop = _.after(active.length, _.partial(_.invokeMap, all, 'reset', reset));
if (_.isEmpty(active)) {
_.defer(stop);
}
if (_.isEmpty(all)) {
_.defer(reset);
}
_.invokeMap(active, 'stop', function() {
_.pull(active, this);
stop();
});
if (this._timeoutId) {
clearTimeout(this._timeoutId);
this._timeoutId = null;
}
return this;
};
/**
* Starts the tunnel.
*
* @memberOf Tunnel
* @param {Function} callback The function called once the tunnel is started.
* @param {Object} Returns the tunnel instance.
*/
Tunnel.prototype.start = function(callback) {
this.once('start', _.iteratee(callback));
if (this.starting || this.running) {
return this;
}
this.starting = true;
logInline();
console.log('Opening Sauce Connect tunnel...');
var onStart = _.bind(onTunnelStart, this);
if (this.timeout) {
this._timeoutId = _.delay(onStart, this.timeout * 1000, false);
}
this.connection.start(onStart);
return this;
};
/**
* Removes jobs from the queue and starts them.
*
* @memberOf Tunnel
* @param {Object} Returns the tunnel instance.
*/
Tunnel.prototype.dequeue = function() {
var count = 0,
jobs = this.jobs,
active = jobs.active,
queue = jobs.queue,
throttled = this.throttled;
while (queue.length && (active.length < throttled)) {
var job = queue.shift();
active.push(job);
_.delay(_.bind(job.start, job), ++count * 1000);
}
return this;
};
/**
* Stops the tunnel.
*
* @memberOf Tunnel
* @param {Function} callback The function called once the tunnel is stopped.
* @param {Object} Returns the tunnel instance.
*/
Tunnel.prototype.stop = function(callback) {
this.once('stop', _.iteratee(callback));
if (this.stopping) {
return this;
}
this.stopping = true;
logInline();
console.log('Shutting down Sauce Connect tunnel...');
var jobs = this.jobs,
active = jobs.active;
var stop = _.after(active.length, _.bind(function() {
var onStop = _.bind(onGenericStop, this);
if (this.running) {
this.connection.stop(onStop);
} else {
onStop();
}
}, this));
jobs.queue.length = 0;
if (_.isEmpty(active)) {
_.defer(stop);
}
_.invokeMap(active, 'stop', function() {
_.pull(active, this);
stop();
});
if (this._timeoutId) {
clearTimeout(this._timeoutId);
this._timeoutId = null;
}
return this;
};
/*----------------------------------------------------------------------------*/
// Cleanup any inline logs when exited via `ctrl+c`.
process.on('SIGINT', function() {
logInline();
process.exit();
});
// Create a web server for the current working directory.
http.createServer(function(req, res) {
// See http://msdn.microsoft.com/en-us/library/ff955275(v=vs.85).aspx.
if (compatMode && path.extname(url.parse(req.url).pathname) == '.html') {
res.setHeader('X-UA-Compatible', 'IE=' + compatMode);
}
mount(req, res);
}).listen(port);
// Setup Sauce Connect so we can use this server from Sauce Labs.
var tunnel = new Tunnel({
'user': username,
'pass': accessKey,
'id': tunnelId,
'job': { 'retries': maxJobRetries, 'statusInterval': statusInterval },
'platforms': platforms,
'retries': maxTunnelRetries,
'throttled': throttled,
'tunneled': tunneled,
'timeout': tunnelTimeout
});
tunnel.on('complete', function(success) {
process.exit(success ? 0 : 1);
});
tunnel.start();
setInterval(logThrobber, throbberDelay);

View File

@@ -16573,6 +16573,21 @@
assert.deepEqual(object, { 'a': { 'b': 2 } });
});
});
// Prevent regression for https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg
QUnit.test('Security: _.omit should not allow modifying prototype or constructor properties', function(assert) {
assert.expect(3);
var testObj1 = {};
assert.strictEqual(typeof testObj1.toString, 'function', 'Object.toString should work before omit');
_.omit({}, ['__proto__.toString']);
_.omit({}, ['constructor.prototype.toString']);
var testObj2 = {};
assert.strictEqual(typeof testObj2.toString, 'function', 'Object.toString should still work after omit');
assert.strictEqual(Object.prototype.toString.call({}), '[object Object]', 'Object.toString should behave as expected');
});
}());
/*--------------------------------------------------------------------------*/
@@ -22299,7 +22314,7 @@
QUnit.test('should forbid code injection through the "variable" options', function(assert) {
assert.expect(1);
assert.raises(function () {
assert.raises(function() {
_.template('', { 'variable': '){console.log(process.env)}; with(obj' });
});
});
@@ -22655,7 +22670,7 @@
var actual,
expected = 'no error';
try {
actual = _.template(expected, {'sourceURL': '\u2028\u2029\n!this would err if it was executed!'})();
actual = _.template(expected, {'sourceURL': '\u2028\u2029\n!this would err if it was executed!'})();
} catch (e) {}
assert.equal(actual, expected);
@@ -25239,6 +25254,21 @@
skipAssert(assert);
}
});
// Prevent regression for https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg
QUnit.test('Security: _.unset should not allow modifying prototype or constructor properties', function(assert) {
assert.expect(3);
var testStr1 = 'ABC';
assert.strictEqual(typeof testStr1.toLowerCase, 'function', 'String.toLowerCase should exist before unset');
_.unset({ foo: 'bar' }, 'foo.__proto__.toLowerCase');
_.unset({ foo: 'bar' }, 'foo.constructor.prototype.toLowerCase');
var testStr2 = 'ABC';
assert.strictEqual(typeof testStr2.toLowerCase, 'function', 'String.toLowerCase should still exist after unset');
assert.strictEqual(testStr2.toLowerCase(), 'abc', 'String.toLowerCase should work as expected');
});
}());
/*--------------------------------------------------------------------------*/
@@ -25840,35 +25870,35 @@
});
// zipObjectDeep prototype pollution
['__proto__', 'constructor', 'prototype'].forEach(function (keyToTest) {
QUnit.test('zipObjectDeep is not setting ' + keyToTest + ' on global', function (assert) {
['__proto__', 'constructor', 'prototype'].forEach(function(keyToTest) {
QUnit.test('zipObjectDeep is not setting ' + keyToTest + ' on global', function(assert) {
assert.expect(1);
_.zipObjectDeep([keyToTest + '.a'], ['newValue']);
// Can't access plain `a` as it's not defined and test fails
assert.notEqual(root['a'], 'newValue');
assert.notEqual(root.a, 'newValue');
});
QUnit.test('zipObjectDeep is not overwriting ' + keyToTest + ' on vars', function (assert) {
QUnit.test('zipObjectDeep is not overwriting ' + keyToTest + ' on vars', function(assert) {
assert.expect(3);
const b = 'oldValue'
const b = 'oldValue';
_.zipObjectDeep([keyToTest + '.b'], ['newValue']);
assert.equal(b, 'oldValue');
assert.notEqual(root['b'], 'newValue');
assert.notEqual(root.b, 'newValue');
// ensure nothing was created
assert.notOk(root['b']);
assert.notOk(root.b);
});
QUnit.test('zipObjectDeep is not overwriting global.' + keyToTest, function (assert) {
QUnit.test('zipObjectDeep is not overwriting global.' + keyToTest, function(assert) {
assert.expect(2);
_.zipObjectDeep([root + '.' + keyToTest + '.c'], ['newValue']);
assert.notEqual(root['c'], 'newValue');
assert.notEqual(root.c, 'newValue');
// ensure nothing was created
assert.notOk(root['c']);
assert.notOk(root.c);
});
});

82
threat-model.md Normal file
View File

@@ -0,0 +1,82 @@
# The Lodash Threat Model
The Lodash threat model defines what Lodash trusts and does not trust when executing within a JavaScript environment. Lodash is a general-purpose utility library that operates within the same trust boundaries as the code that calls it. Therefore, vulnerabilities requiring the compromise of trusted elements — such as the JavaScript runtime, the host environment, or developer-controlled inputs — lie outside the scope of this threat model.
For a vulnerability to be considered within scope, it must result from Lodash itself violating its documented behavior or failing to maintain integrity, confidentiality, or availability under its standard usage assumptions.
## Elements Lodash Does NOT Trust
1. **Data provided to Lodash functions**
Lodash treats all input data (arrays, objects, strings, functions, etc.) as untrusted. It does not attempt to validate or sanitize the semantic correctness of inputs — it operates on values as they are given.
*If an untrusted input can cause Lodash to execute behavior beyond what is documented — such as prototype pollution, type confusion, memory exhaustion, or code injection — that would indicate a security vulnerability.*
2. **Untrusted network sources or user-controlled data**
Any input derived from unvalidated user input, network responses, file contents, or deserialized data is untrusted. Lodash does not perform input isolation or sandboxing.
3. **Tampering with Lodash internals at runtime**
Modifying Lodashs internal symbols, monkey-patching its functions, or overwriting internal references at runtime is outside the trusted boundary.
*If such modification changes Lodash behavior, that reflects a compromise of trusted code, not a Lodash vulnerability.*
## Elements Lodash Trusts
1. **The JavaScript runtime and its standard library**
Lodash assumes a correct, uncompromised runtime environment (e.g., Node.js, browser). Vulnerabilities in the runtime (e.g., prototype chain issues, engine crashes) are out of scope.
2. **The environment and its configuration**
Lodash relies on the correct functioning of the host environment (Node.js, browser, Deno, etc.) and any global objects or APIs it uses (e.g., `Object`, `Array`, `Function`, `JSON`).
3. **The code that invokes Lodash**
The application or library using Lodash is responsible for validating user input, performing security checks, and handling execution context appropriately.
4. **Installed package integrity**
Lodash assumes that the package installed (via npm, cdn, etc.) has not been tampered with and originates from the legitimate Lodash distribution channel.
*Supply-chain compromise or malicious clones are not considered Lodash vulnerabilities.*
5. **The privileges and permissions of the execution context**
Lodash inherits the privileges of the user or process that invokes it. Misuse or over-privileged execution environments (e.g., running as root, or with excessive browser permissions) are not within scope.
## Examples of Vulnerabilities (in scope)
- **Prototype Pollution ([CWE-1321](https://cwe.mitre.org/data/definitions/1321.html))**
If a Lodash function (e.g., `merge`, `defaultsDeep`, or `set`) allows modification of `Object.prototype` properties via untrusted input (e.g., `__proto__` keys) due to insufficient sanitization, it is in scope.
This class of vulnerability has been observed in prior Lodash versions (e.g., [CVE-2019-10744](https://www.cve.org/CVERecord?id=CVE-2019-10744)).
- **Unexpected code execution ([CWE-94](https://cwe.mitre.org/data/definitions/94.html))**
If a Lodash method (e.g., `template()`) executes attacker-controlled input as code without documented warnings or sanitization requirements, that is a Lodash vulnerability (e.g., [CVE-2021-23337](https://nvd.nist.gov/vuln/detail/CVE-2021-23337)).
- **Denial of Service (DoS) through logic flaws ([CWE-400](https://cwe.mitre.org/data/definitions/400.html))**
If Lodash enters unbounded recursion, excessive memory usage, or hangs when operating on otherwise valid inputs within documented usage limits, this is a vulnerability in Lodash (e.g, [CVE-2020-28500](https://www.cve.org/CVERecord?id=CVE-2020-28500)).
## Examples of Non-Vulnerabilities (out of scope)
### Malicious Third-Party Packages ([CWE-1357](https://cwe.mitre.org/data/definitions/1357.html))
If a project includes a malicious dependency that overrides Lodash behavior or injects malicious code into Lodashs namespace, it does not represent a Lodash vulnerability. Lodash trusts its runtime and installation context.
### Unvalidated Application Input
Applications using Lodash are responsible for input validation. Passing attacker-controlled data directly into Lodash functions (e.g., `_.merge(req.body, config)`) is an application bug, not a Lodash vulnerability.
### Prototype Pollution via Trusted Code
If a developer intentionally merges user input into global objects or fails to isolate data structures, that is a misuse of Lodashs documented API, not a Lodash defect.
### Vulnerabilities in the JavaScript Runtime or Platform
If a Lodash method triggers a bug in the JavaScript engine (e.g., V8, SpiderMonkey, JavaScriptCore) that leads to memory corruption or incorrect behavior, the vulnerability lies in the engine, not Lodash.
### Environmental Misconfiguration ([CWE-15](https://cwe.mitre.org/data/definitions/15.html))
Issues arising from misconfigured execution environments, such as running outdated Node.js versions or insecure Content Security Policies in browsers, are not considered Lodash vulnerabilities.
### Supply Chain Compromise
Tampering with Lodash packages in the npm registry, MITM attacks during installation, or local file system manipulation are not vulnerabilities in Lodash itself.
## Summary
Lodash is a utility library operating entirely within the trust boundary of its caller. Vulnerabilities in scope are limited to cases where **Lodash fails to uphold its documented behavior** in the presence of **untrusted input**, without assuming compromise of trusted components such as the runtime, the operating system, or the invoking application code.

3346
yarn.lock

File diff suppressed because it is too large Load Diff